7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * CDDL HEADER START
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * The contents of this file are subject to the terms of the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Common Development and Distribution License (the "License").
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * You may not use this file except in compliance with the License.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * or http://www.opensolaris.org/os/licensing.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * See the License for the specific language governing permissions
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * and limitations under the License.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * When distributing Covered Code, include this CDDL HEADER in each
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If applicable, add the following below this CDDL HEADER, with the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * fields enclosed by brackets "[]" replaced with your own identifying
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * information: Portions Copyright [yyyy] [name of copyright owner]
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * CDDL HEADER END
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
8e51227711fb29b69b8f42a3953e759963432065WENTAO YANG * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
8e51227711fb29b69b8f42a3953e759963432065WENTAO YANG
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/types.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/errno.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/sysmacros.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/param.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/machsystm.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/stream.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/strsubr.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/kmem.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/strsun.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/callb.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/sdt.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/mach_descrip.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/mdeg.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <net/if.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/vsw.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/vio_mailbox.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/vio_common.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/vnet_common.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/vnet_mailbox.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/vio_util.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * This file contains the implementation of RxDringData transfer mode of VIO
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Protocol in vsw. The functions in this file are invoked from vsw_ldc.c
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * after RxDringData mode is negotiated with the peer during attribute phase of
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * handshake. This file contains functions that setup the transmit and receive
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * descriptor rings, and associated resources in RxDringData mode. It also
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * contains the transmit and receive data processing functions that are invoked
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * in RxDringData mode. The data processing routines in this file have the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * suffix '_shm' to indicate the shared memory mechanism used in RxDringData
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * mode.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/* Functions exported to vsw_ldc.c */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavio_dring_reg_msg_t *vsw_create_rx_dring_info(vsw_ldc_t *);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vsw_destroy_rx_dring(vsw_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnadring_info_t *vsw_map_tx_dring(vsw_ldc_t *ldcp, void *pkt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vsw_unmap_tx_dring(vsw_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint vsw_dringsend_shm(vsw_ldc_t *, mblk_t *);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vsw_ldc_rcv_worker(void *arg);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vsw_stop_rcv_thread(vsw_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vsw_process_dringdata_shm(void *, void *);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/* Internal functions */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic dring_info_t *vsw_create_rx_dring(vsw_ldc_t *);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int vsw_setup_rx_dring(vsw_ldc_t *ldcp, dring_info_t *dp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic void vsw_process_dringdata_info_shm(vsw_ldc_t *ldcp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *msg);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic void vsw_process_dringdata_ack_shm(vsw_ldc_t *ldcp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *msg);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic void vsw_ldc_rcv_shm(vsw_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int vsw_receive_packet(vsw_ldc_t *ldcp, mblk_t **bp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int vsw_send_msg_shm(vsw_ldc_t *ldcp, void *msgp, int size,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t handle_reset);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/* Functions imported from vsw_ldc.c */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern void vsw_process_pkt(void *);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern void vsw_destroy_rxpools(void *);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern dring_info_t *vsw_map_dring_cmn(vsw_ldc_t *ldcp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_reg_msg_t *dring_pkt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern void vsw_process_conn_evt(vsw_ldc_t *, uint16_t);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern mblk_t *vsw_vlan_frame_pretag(void *arg, int type, mblk_t *mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/* Tunables */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern int vsw_wretries;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern int vsw_recv_delay;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern int vsw_recv_retries;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vsw_chain_len;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vsw_num_descriptors;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vsw_nrbufs_factor;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#define VSW_SWITCH_FRAMES(vswp, ldcp, bp, bpt, count, total_count) \
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{ \
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DTRACE_PROBE2(vsw_rx_pkts, vsw_ldc_t *, (ldcp), int, (count)); \
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (vswp)->vsw_switch_frame((vswp), (bp), VSW_VNETPORT, \
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (ldcp)->ldc_port, NULL); \
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (bp) = (bpt) = NULL; \
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (count) = 0; \
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavio_dring_reg_msg_t *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_create_rx_dring_info(vsw_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_reg_msg_t *mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_reg_ext_msg_t *emsg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint8_t *buf;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(vswp, "%s enter\n", __func__);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If we can't create a dring, obviously no point sending
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * a message.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((dp = vsw_create_rx_dring(ldcp)) == NULL)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp = kmem_zalloc(VNET_DRING_REG_EXT_MSG_SIZE(dp->data_ncookies),
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna KM_SLEEP);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->tag.vio_msgtype = VIO_TYPE_CTRL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->tag.vio_subtype = VIO_SUBTYPE_INFO;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->tag.vio_subtype_env = VIO_DRING_REG;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->tag.vio_sid = ldcp->local_session;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* payload */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->num_descriptors = dp->num_descriptors;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->descriptor_size = dp->descriptor_size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->options = dp->options;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->ncookies = dp->dring_ncookies;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bcopy(&dp->dring_cookie[0], &mp->cookie[0],
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (ldc_mem_cookie_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->dring_ident = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna buf = (uint8_t *)mp->cookie;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* skip over dring cookies */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ASSERT(mp->ncookies == 1);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna buf += (mp->ncookies * sizeof (ldc_mem_cookie_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna emsg = (vio_dring_reg_ext_msg_t *)buf;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* copy data_ncookies in the msg */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna emsg->data_ncookies = dp->data_ncookies;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* copy data area size in the msg */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna emsg->data_area_size = dp->data_sz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* copy data area cookies in the msg */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bcopy(dp->data_cookie, (ldc_mem_cookie_t *)emsg->data_cookie,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (ldc_mem_cookie_t) * dp->data_ncookies);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(vswp, "%s exit\n", __func__);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Allocate receive resources for the channel. The resources consist of a
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * receive descriptor ring and an associated receive buffer area.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic dring_info_t *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_create_rx_dring(vsw_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldc_mem_info_t minfo;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp = (dring_info_t *)kmem_zalloc(sizeof (dring_info_t), KM_SLEEP);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_init(&dp->dlock, NULL, MUTEX_DRIVER, NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->lane_out.dringp = dp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Create the receive descriptor ring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((ldc_mem_dring_create(vsw_num_descriptors,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (vnet_rx_dringdata_desc_t), &dp->dring_handle)) != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "vsw_create_rx_dring(%lld): ldc dring create "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "failed", ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ASSERT(dp->dring_handle != NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Get the addr of descriptor ring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((ldc_mem_dring_info(dp->dring_handle, &minfo)) != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "vsw_create_rx_dring(%lld): dring info failed\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ASSERT(minfo.vaddr != 0);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->pub_addr = minfo.vaddr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->num_descriptors = vsw_num_descriptors;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->descriptor_size = sizeof (vnet_rx_dringdata_desc_t);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->options = VIO_RX_DRING_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->dring_ncookies = 1; /* guaranteed by ldc */
34f94fbc7a730740933e4776ade5f74009afe4ceWENTAO YANG dp->num_bufs = VSW_RXDRING_NRBUFS;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Allocate a table that maps descriptor to its associated buffer;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * used while receiving to validate that the peer has not changed the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * buffer offset provided in the descriptor.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->rxdp_to_vmp = kmem_zalloc(dp->num_descriptors * sizeof (uintptr_t),
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna KM_SLEEP);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Setup the descriptor ring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (vsw_setup_rx_dring(ldcp, dp)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s: unable to setup ring", __func__);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * The descriptors and the associated buffers are all ready;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * now bind descriptor ring to the channel.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((ldc_mem_dring_bind(ldcp->ldc_handle, dp->dring_handle,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna LDC_DIRECT_MAP | LDC_SHADOW_MAP, LDC_MEM_RW,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna &dp->dring_cookie[0], &dp->dring_ncookies)) != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "vsw_create_rx_dring: unable to bind to channel "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "%lld", ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* haven't used any descriptors yet */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->end_idx = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->last_ack_recv = -1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->next_rxi = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (dp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnafail:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_destroy_rx_dring(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Setup the descriptors in the rx dring.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Returns 0 on success, 1 on failure.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_setup_rx_dring(vsw_ldc_t *ldcp, dring_info_t *dp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
8e51227711fb29b69b8f42a3953e759963432065WENTAO YANG int i, j;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t data_sz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_mblk_t *vmp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_mblk_t **rxdp_to_vmp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_rx_dringdata_desc_t *rxdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_rx_dringdata_desc_t *pub_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t ncookies = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna static char *name = "vsw_setup_rx_dring";
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna void *data_addr = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Allocate a single large buffer that serves as the rx buffer area.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We allocate a ldc memory handle and export the buffer area as shared
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * memory. We send the ldc memcookie for this buffer space to the peer,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * as part of dring registration phase during handshake. We manage this
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * buffer area as individual buffers of max_frame_size and provide
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * specific buffer offsets in each descriptor to the peer. Note that
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the factor used to compute the # of buffers (above) must be > 1 to
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * ensure that there are more buffers than the # of descriptors. This
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * is needed because, while the shared memory buffers are sent up our
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * stack during receive, the sender needs additional buffers that can
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * be used for further transmits. This also means there is no one to
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * one correspondence between the descriptor index and buffer offset.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * The sender has to read the buffer offset in the descriptor and use
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the specified offset to copy the tx data into the shared buffer. We
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * (receiver) manage the individual buffers and their state (see
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * VIO_MBLK_STATEs in vio_util.h).
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
34f94fbc7a730740933e4776ade5f74009afe4ceWENTAO YANG data_sz = RXDRING_DBLK_SZ(vswp->max_frame_size);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->desc_data_sz = data_sz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_sz = (dp->num_bufs * data_sz);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_addr = kmem_zalloc(dp->data_sz, KM_SLEEP);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_addr = data_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s: allocated %lld bytes at 0x%llx\n", name,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_sz, dp->data_addr);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Allocate a ldc memhandle for the entire rx data area */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_alloc_handle(ldcp->ldc_handle, &dp->data_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s: alloc mem handle failed", name);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Allocate memory for the data cookies */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_cookie = kmem_zalloc(VNET_DATA_AREA_COOKIES *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (ldc_mem_cookie_t), KM_SLEEP);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Bind ldc memhandle to the corresponding rx data area.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_bind_handle(dp->data_handle, (caddr_t)data_addr,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_sz, LDC_DIRECT_MAP, LDC_MEM_W,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_cookie, &ncookies);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld): ldc_mem_bind_handle failed "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "(rv %d)", name, ldcp->ldc_id, rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((ncookies == 0) || (ncookies > VNET_DATA_AREA_COOKIES)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_ncookies = ncookies;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
8e51227711fb29b69b8f42a3953e759963432065WENTAO YANG for (j = 1; j < ncookies; j++) {
8e51227711fb29b69b8f42a3953e759963432065WENTAO YANG rv = ldc_mem_nextcookie(dp->data_handle,
8e51227711fb29b69b8f42a3953e759963432065WENTAO YANG &(dp->data_cookie[j]));
8e51227711fb29b69b8f42a3953e759963432065WENTAO YANG if (rv != 0) {
8e51227711fb29b69b8f42a3953e759963432065WENTAO YANG DERR(vswp, "%s: ldc_mem_nextcookie "
8e51227711fb29b69b8f42a3953e759963432065WENTAO YANG "failed rv (%d)", name, rv);
8e51227711fb29b69b8f42a3953e759963432065WENTAO YANG goto fail;
8e51227711fb29b69b8f42a3953e759963432065WENTAO YANG }
8e51227711fb29b69b8f42a3953e759963432065WENTAO YANG }
8e51227711fb29b69b8f42a3953e759963432065WENTAO YANG
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Successful in binding the handle to rx data area. Now setup mblks
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * around each data buffer and setup the descriptors to point to these
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * rx data buffers. We associate each descriptor with a buffer
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * by specifying the buffer offset in the descriptor. When the peer
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * needs to transmit data, this offset is read by the peer to determine
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the buffer in the mapped buffer area where the data to be
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * transmitted should be copied, for a specific descriptor.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vio_create_mblks(dp->num_bufs, data_sz, (uint8_t *)data_addr,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna &dp->rx_vmp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub_addr = dp->pub_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxdp_to_vmp = dp->rxdp_to_vmp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (i = 0; i < dp->num_descriptors; i++) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxdp = &pub_addr[i];
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* allocate an mblk around this data buffer */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmp = vio_allocb(dp->rx_vmp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ASSERT(vmp != NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxdp->data_buf_offset = VIO_MBLK_DATA_OFF(vmp) + VNET_IPALIGN;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxdp->dstate = VIO_DESC_FREE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxdp_to_vmp[i] = vmp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (0);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnafail:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* return failure; caller will cleanup */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (1);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Free receive resources for the channel.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_destroy_rx_dring(vsw_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna lane_t *lp = &ldcp->lane_out;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp = lp->dringp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp == NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&dp->dlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->rx_vmp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_clobber_pool(dp->rx_vmp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If we can't destroy the rx pool for this channel, dispatch a
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * task to retry and clean up those rx pools. Note that we
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * don't need to wait for the task to complete. If the vsw
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * device itself gets detached (vsw_detach()), it will wait for
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the task to complete implicitly in ddi_taskq_destroy().
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (vio_destroy_mblks(dp->rx_vmp) != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ddi_taskq_dispatch(vswp->rxp_taskq,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_destroy_rxpools, dp->rx_vmp, DDI_SLEEP);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Free rx data area cookies */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->data_cookie != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kmem_free(dp->data_cookie, VNET_DATA_AREA_COOKIES *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (ldc_mem_cookie_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_cookie = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Unbind rx data area memhandle */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->data_ncookies != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_unbind_handle(dp->data_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_ncookies = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Free rx data area memhandle */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->data_handle) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_free_handle(dp->data_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_handle = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Now free the rx data area itself */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->data_addr != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kmem_free(dp->data_addr, dp->data_sz);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Finally, free the receive descriptor ring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->dring_handle != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_dring_unbind(dp->dring_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_dring_destroy(dp->dring_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->rxdp_to_vmp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kmem_free(dp->rxdp_to_vmp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->num_descriptors * sizeof (uintptr_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->rxdp_to_vmp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->dlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_destroy(&dp->dlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_destroy(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kmem_free(dp, sizeof (dring_info_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna lp->dringp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Map the receive descriptor ring exported by the peer, as our transmit
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * descriptor ring.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnadring_info_t *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_map_tx_dring(vsw_ldc_t *ldcp, void *pkt)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int i;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_rx_dringdata_desc_t *txdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna on_trap_data_t otd;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_reg_msg_t *dring_pkt = pkt;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp = vsw_map_dring_cmn(ldcp, dring_pkt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp == NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* RxDringData mode specific initializations */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_init(&dp->txlock, NULL, MUTEX_DRIVER, NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_init(&dp->restart_lock, NULL, MUTEX_DRIVER, NULL);
0e26330710421d79f1fbb73c4f5f75086785b207WENTAO YANG dp->next_txi = dp->restart_peer_txi = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->restart_reqd = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->dringdata_msgid = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->lane_in.dringp = dp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Mark the descriptor state as 'done'. This is implementation specific
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * and not required by the protocol. In our implementation, we only
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * need the descripor to be in 'done' state to be used by the transmit
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * function and the peer is not aware of it. As the protocol requires
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * that during initial registration the exporting end point mark the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * dstate as 'free', we change it 'done' here. After this, the dstate
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * in our implementation will keep moving between 'ready', set by our
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * transmit function; and and 'done', set by the peer (per protocol)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * after receiving data.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Setup on_trap() protection before accessing dring shared memory area.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = LDC_ON_TRAP(&otd);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Data access fault occured down the code path below while
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * accessing the descriptors. Return failure.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp = (vnet_rx_dringdata_desc_t *)dp->pub_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (i = 0; i < dp->num_descriptors; i++) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp[i].dstate = VIO_DESC_DONE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) LDC_NO_TRAP();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (dp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnafail:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->dring_handle != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_dring_unmap(dp->dring_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kmem_free(dp, sizeof (*dp));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Unmap the transmit descriptor ring.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_unmap_tx_dring(vsw_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna lane_t *lp = &ldcp->lane_in;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((dp = lp->dringp) == NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Unmap tx data area and free data handle */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->data_handle != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_unmap(dp->data_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_free_handle(dp->data_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_handle = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Free tx data area cookies */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->data_cookie != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kmem_free(dp->data_cookie, dp->data_ncookies *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (ldc_mem_cookie_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_cookie = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_ncookies = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Unmap peer's dring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->dring_handle != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_dring_unmap(dp->dring_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->dring_handle = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_destroy(&dp->txlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kmem_free(dp, sizeof (dring_info_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna lp->dringp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * A per LDC worker thread to process the rx dring and receive packets. This
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * thread is woken up by the LDC interrupt handler when a dring data info
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * message is received.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_ldc_rcv_worker(void *arg)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna callb_cpr_t cprinfo;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_ldc_t *ldcp = (vsw_ldc_t *)arg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(vswp, "%s(%lld):enter\n", __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna CALLB_CPR_INIT(&cprinfo, &ldcp->rcv_thr_lock, callb_generic_cpr,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "vsw_rcv_thread");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->rcv_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna while (!(ldcp->rcv_thr_flags & VSW_WTHR_STOP)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna CALLB_CPR_SAFE_BEGIN(&cprinfo);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Wait until the data is received or a stop
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * request is received.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna while (!(ldcp->rcv_thr_flags &
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (VSW_WTHR_DATARCVD | VSW_WTHR_STOP))) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna cv_wait(&ldcp->rcv_thr_cv, &ldcp->rcv_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna CALLB_CPR_SAFE_END(&cprinfo, &ldcp->rcv_thr_lock)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * First process the stop request.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->rcv_thr_flags & VSW_WTHR_STOP) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s(%lld):Rx thread stopped\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->rcv_thr_flags &= ~VSW_WTHR_DATARCVD;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->rcv_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(vswp, "%s(%lld):calling vsw_process_pkt\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_ldc_rcv_shm(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->rcv_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Update the run status and wakeup the thread that
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * has sent the stop request.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->rcv_thr_flags &= ~VSW_WTHR_STOP;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->rcv_thread = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna CALLB_CPR_EXIT(&cprinfo);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(vswp, "%s(%lld):exit\n", __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna thread_exit();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Process the rx descriptor ring in the context of receive worker
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * thread and switch the received packets to their destinations.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic void
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_ldc_rcv_shm(vsw_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t end_ix;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t msg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *msgp = &msg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int count = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int total_count = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t retries = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *bp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *bpt = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *mp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna lane_t *lp = &ldcp->lane_out;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp = lp->dringp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna do {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaagain:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vsw_receive_packet(ldcp, &mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv == EINVAL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Invalid descriptor error; get next */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna continue;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != EAGAIN) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Descriptor not ready for processsing */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (retries == vsw_recv_retries) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DTRACE_PROBE1(vsw_noready_rxds,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_ldc_t *, ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Switch packets received so far before retrying */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (bp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VSW_SWITCH_FRAMES(vswp, ldcp, bp, bpt, count,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna total_count);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna retries++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna drv_usecwait(vsw_recv_delay);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto again;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna retries = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Build a chain of received packets */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (bp == NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* first pkt */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bp = mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bpt = bp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bpt->b_next = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->b_next = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bpt->b_next = mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bpt = mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna total_count++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna count++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If we have gathered vsw_chain_len (tunable)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * # of packets in the chain, switch them.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (count == vsw_chain_len) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VSW_SWITCH_FRAMES(vswp, ldcp, bp, bpt, count,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna total_count);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Stop further processing if we processed the entire dring
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * once; otherwise continue.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } while (total_count < dp->num_bufs);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DTRACE_PROBE2(vsw_rx_total_count, vsw_ldc_t *, ldcp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int, (total_count));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (bp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VSW_SWITCH_FRAMES(vswp, ldcp, bp, bpt, count,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna total_count);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Send stopped signal to peer (sender) */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna end_ix = lp->dringp->next_rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DECR_RXI(dp, end_ix);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->tag.vio_msgtype = VIO_TYPE_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->tag.vio_subtype = VIO_SUBTYPE_ACK;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->tag.vio_subtype_env = VIO_DRING_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->dring_ident = ldcp->lane_in.dringp->ident;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->tag.vio_sid = ldcp->local_session;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->dring_process_state = VIO_DP_STOPPED;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->start_idx = VNET_START_IDX_UNSPEC;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->end_idx = end_ix;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) vsw_send_msg_shm(ldcp, (void *)msgp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (vio_dring_msg_t), B_TRUE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.dring_data_acks_sent++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.dring_stopped_acks_sent++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Process the next index in the rx dring and receive the associated packet.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Returns:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * bp: Success: The received packet.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Failure: NULL
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * retval:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Success: 0
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Failure: EAGAIN: Descriptor not ready
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * EIO: Descriptor contents invalid.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_receive_packet(vsw_ldc_t *ldcp, mblk_t **bp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_mblk_t *vmp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_mblk_t *new_vmp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna struct ether_header *ehp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_rx_dringdata_desc_t *rxdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int err = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint_t nbytes = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *mp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *dmp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_stats_t *statsp = &ldcp->ldc_stats;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp = ldcp->lane_out.dringp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_rx_dringdata_desc_t *pub_addr = dp->pub_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxi = dp->next_rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxdp = &(pub_addr[rxi]);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmp = dp->rxdp_to_vmp[rxi];
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rxdp->dstate != VIO_DESC_READY) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Descriptor is not ready.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (EAGAIN);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Ensure load ordering of dstate and nbytes.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna MEMBAR_CONSUMER();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((rxdp->nbytes < ETHERMIN) ||
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (rxdp->nbytes > ldcp->lane_in.mtu) ||
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (rxdp->data_buf_offset !=
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (VIO_MBLK_DATA_OFF(vmp) + VNET_IPALIGN))) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Descriptor contents invalid.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->ierrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxdp->dstate = VIO_DESC_DONE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna err = EIO;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto done;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Now allocate a new buffer for this descriptor before sending up the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * buffer being processed. If that fails, stop processing; as we are
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * out of receive buffers.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna new_vmp = vio_allocb(dp->rx_vmp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Process the current buffer being received.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna nbytes = rxdp->nbytes;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp = vmp->mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (new_vmp == NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We failed to get a new mapped buffer that is needed to
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * refill the descriptor. In that case, leave the current
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * buffer bound to the descriptor; allocate an mblk dynamically
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * and copy the contents of the buffer to the mblk. Then send
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * up this mblk. This way the sender has the same buffer as
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * before that can be used to send new data.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->norcvbuf++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dmp = allocb(nbytes + VNET_IPALIGN, BPRI_MED);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bcopy(mp->b_rptr + VNET_IPALIGN,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dmp->b_rptr + VNET_IPALIGN, nbytes);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp = dmp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Mark the status of the current rbuf */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmp->state = VIO_MBLK_HAS_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Set the offset of the new buffer in the descriptor */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxdp->data_buf_offset =
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VIO_MBLK_DATA_OFF(new_vmp) + VNET_IPALIGN;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->rxdp_to_vmp[rxi] = new_vmp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->b_rptr += VNET_IPALIGN;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->b_wptr = mp->b_rptr + nbytes;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Ensure store ordering of data_buf_offset and dstate; so that the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * peer sees the right data_buf_offset after it checks that the dstate
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * is DONE.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna MEMBAR_PRODUCER();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Now mark the descriptor 'done' */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxdp->dstate = VIO_DESC_DONE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Update stats */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->ipackets++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->rbytes += rxdp->nbytes;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ehp = (struct ether_header *)mp->b_rptr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (IS_BROADCAST(ehp))
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->brdcstrcv++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna else if (IS_MULTICAST(ehp))
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->multircv++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnadone:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Update the next index to be processed */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna INCR_RXI(dp, rxi);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Save the new recv index */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->next_rxi = rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Return the packet received */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *bp = mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (err);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_stop_rcv_thread(vsw_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kt_did_t tid = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(vswp, "%s(%lld):enter\n", __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Send a stop request by setting the stop flag and
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * wait until the rcv process thread stops.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->rcv_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->rcv_thread != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tid = ldcp->rcv_thread->t_did;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->rcv_thr_flags |= VSW_WTHR_STOP;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna cv_signal(&ldcp->rcv_thr_cv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->rcv_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (tid != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna thread_join(tid);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(vswp, "%s(%lld):exit\n", __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_dringsend_shm(vsw_ldc_t *ldcp, mblk_t *mp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t next_txi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t txi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_rx_dringdata_desc_t *txdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna struct ether_header *ehp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t mblksz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna caddr_t dst;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *bp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna on_trap_data_t otd;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t buf_offset;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_rx_dringdata_desc_t *pub_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t msg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *msgp = &msg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t resched_peer = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t is_bcast = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t is_mcast = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_stats_t *statsp = &ldcp->ldc_stats;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna lane_t *lane_in = &ldcp->lane_in;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna lane_t *lane_out = &ldcp->lane_out;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp = lane_in->dringp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((!(lane_in->lstate & VSW_LANE_ACTIVE)) ||
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (ldcp->ldc_status != LDC_UP) || (ldcp->ldc_handle == NULL)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vswp, "%s(%lld) status(%d) lstate(0x%llx), dropping "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "packet\n", __func__, ldcp->ldc_id, ldcp->ldc_status,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna lane_in->lstate);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->oerrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (LDC_TX_FAILURE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp == NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld): no dring for outbound lane on"
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna " channel %d", __func__, ldcp->ldc_id, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->oerrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (LDC_TX_FAILURE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub_addr = dp->pub_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size = msgsize(mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Note: In RxDringData mode, lane_in is associated with transmit and
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * lane_out is associated with receive. However, we still keep the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * negotiated mtu in lane_out (our exported attributes).
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (size > (size_t)lane_out->mtu) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld) invalid size (%ld)\n", __func__,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_id, size);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->oerrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (LDC_TX_FAILURE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (size < ETHERMIN)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size = ETHERMIN;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ehp = (struct ether_header *)mp->b_rptr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna is_bcast = IS_BROADCAST(ehp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna is_mcast = IS_MULTICAST(ehp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Setup on_trap() protection before accessing shared memory areas
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * (descriptor and data buffer). Note that we enable this protection a
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * little early and turn it off slightly later, than keeping it enabled
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * strictly at the points in code below where the descriptor and data
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * buffer are accessed. This is done for performance reasons:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * (a) to avoid calling the trap protection code while holding mutex.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * (b) to avoid multiple on/off steps for descriptor and data accesses.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = LDC_ON_TRAP(&otd);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Data access fault occured down the code path below while
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * accessing either the descriptor or the data buffer. Release
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * any locks that we might have acquired in the code below and
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * return failure.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld) data access fault occured\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->oerrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (mutex_owned(&dp->txlock)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->txlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (mutex_owned(&dp->restart_lock)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto dringsend_shm_exit;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Allocate a descriptor
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&dp->txlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txi = next_txi = dp->next_txi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna INCR_TXI(dp, next_txi);
0e26330710421d79f1fbb73c4f5f75086785b207WENTAO YANG txdp = &(pub_addr[txi]);
0e26330710421d79f1fbb73c4f5f75086785b207WENTAO YANG if (txdp->dstate != VIO_DESC_DONE) { /* out of descriptors */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->tx_no_desc++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->txlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) LDC_NO_TRAP();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (LDC_TX_NORESOURCES);
0e26330710421d79f1fbb73c4f5f75086785b207WENTAO YANG } else {
0e26330710421d79f1fbb73c4f5f75086785b207WENTAO YANG txdp->dstate = VIO_DESC_INITIALIZING;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Update descriptor ring index */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->next_txi = next_txi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->txlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Ensure load ordering of dstate (above) and data_buf_offset. */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna MEMBAR_CONSUMER();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Get the offset of the buffer to be used */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna buf_offset = txdp->data_buf_offset;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Access the buffer using the offset */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dst = (caddr_t)dp->data_addr + buf_offset;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Copy data into mapped transmit buffer */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (bp = mp; bp != NULL; bp = bp->b_cont) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblksz = MBLKL(bp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bcopy(bp->b_rptr, dst, mblksz);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dst += mblksz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Set the size of data in the descriptor */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp->nbytes = size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Ensure store ordering of nbytes and dstate (below); so that the peer
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * sees the right nbytes value after it checks that the dstate is READY.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna MEMBAR_PRODUCER();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
0e26330710421d79f1fbb73c4f5f75086785b207WENTAO YANG ASSERT(txdp->dstate == VIO_DESC_INITIALIZING);
0e26330710421d79f1fbb73c4f5f75086785b207WENTAO YANG
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Mark the descriptor ready */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp->dstate = VIO_DESC_READY;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Check if peer needs wake up (handled below) */
0e26330710421d79f1fbb73c4f5f75086785b207WENTAO YANG if (dp->restart_reqd == B_TRUE && dp->restart_peer_txi == txi) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->restart_reqd = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna resched_peer = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Update tx stats */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->opackets++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->obytes += size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (is_bcast)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->brdcstxmt++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna else if (is_mcast)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->multixmt++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We are done accessing shared memory; clear trap protection.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) LDC_NO_TRAP();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Need to wake up the peer ?
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (resched_peer == B_TRUE) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->tag.vio_msgtype = VIO_TYPE_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->tag.vio_subtype = VIO_SUBTYPE_INFO;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->tag.vio_subtype_env = VIO_DRING_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->tag.vio_sid = ldcp->local_session;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->dring_ident = lane_out->dringp->ident;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->start_idx = txi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->end_idx = -1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vsw_send_msg_shm(ldcp, (void *)msgp, sizeof (*msgp),
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna B_FALSE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* error: drop the packet */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld) failed sending dringdata msg\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->oerrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->restart_reqd = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->dring_data_msgs_sent++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnadringsend_shm_exit:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv == ECONNRESET || rv == EACCES) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_process_conn_evt(ldcp, VSW_CONN_RESET);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (LDC_TX_SUCCESS);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_process_dringdata_shm(void *arg, void *dpkt)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_ldc_t *ldcp = arg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *dring_pkt = dpkt;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna switch (dring_pkt->tag.vio_subtype) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna case VIO_SUBTYPE_INFO:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s(%lld): VIO_SUBTYPE_INFO", __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_process_dringdata_info_shm(ldcp, dring_pkt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna case VIO_SUBTYPE_ACK:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s(%lld): VIO_SUBTYPE_ACK", __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_process_dringdata_ack_shm(ldcp, dring_pkt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna case VIO_SUBTYPE_NACK:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vswp, "%s(%lld): VIO_SUBTYPE_NACK",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Something is badly wrong if we are getting NACK's
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * for our data pkts. So reset the channel.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_process_conn_evt(ldcp, VSW_CONN_RESTART);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna default:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld): Unknown vio_subtype %x\n", __func__,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_id, dring_pkt->tag.vio_subtype);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic void
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_process_dringdata_info_shm(vsw_ldc_t *ldcp, vio_dring_msg_t *msg)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp = ldcp->lane_in.dringp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_stats_t *statsp = &ldcp->ldc_stats;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->ident != msg->dring_ident) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* drop the message */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld): Invalid dring ident 0x%llx",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id, msg->dring_ident);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->dring_data_msgs_rcvd++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Wake up the rcv worker thread to process the rx dring.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ASSERT(MUTEX_HELD(&ldcp->ldc_cblock));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->ldc_cblock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->rcv_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (!(ldcp->rcv_thr_flags & VSW_WTHR_DATARCVD)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->rcv_thr_flags |= VSW_WTHR_DATARCVD;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna cv_signal(&ldcp->rcv_thr_cv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->rcv_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->ldc_cblock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic void
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_process_dringdata_ack_shm(vsw_ldc_t *ldcp, vio_dring_msg_t *msg)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int32_t end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna on_trap_data_t otd;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t txi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_rx_dringdata_desc_t *txdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_rx_dringdata_desc_t *pub_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t ready_txd = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_stats_t *statsp = &ldcp->ldc_stats;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp = ldcp->lane_in.dringp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna start = msg->start_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna end = msg->end_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub_addr = dp->pub_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * In RxDringData mode (v1.6), start index of -1 can be used by the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * peer to indicate that it is unspecified. However, the end index
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * must be set correctly indicating the last descriptor index processed.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (((start != VNET_START_IDX_UNSPEC) && !(CHECK_TXI(dp, start))) ||
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna !(CHECK_TXI(dp, end))) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* drop the message if invalid index */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vswp, "%s(%lld): Invalid Tx ack start(%d) or end(%d)\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id, start, end);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Validate dring_ident */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (msg->dring_ident != ldcp->lane_out.dringp->ident) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* invalid dring_ident, drop the msg */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vswp, "%s(%lld): Invalid dring ident 0x%x\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id, msg->dring_ident);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->dring_data_acks_rcvd++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (msg->dring_process_state != VIO_DP_STOPPED) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Receiver continued processing
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * dring after sending us the ack.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->dring_stopped_acks_rcvd++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Setup on_trap() protection before accessing dring shared memory area.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = LDC_ON_TRAP(&otd);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Data access fault occured down the code path below while
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * accessing the descriptors. Release any locks that we might
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * have acquired in the code below and return failure.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (mutex_owned(&dp->restart_lock)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Determine if there are any pending tx descriptors ready to be
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * processed by the receiver(peer) and if so, send a message to the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * peer to restart receiving.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ready_txd = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txi = end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna INCR_TXI(dp, txi);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp = &pub_addr[txi];
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (txdp->dstate == VIO_DESC_READY) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ready_txd = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We are done accessing shared memory; clear trap protection.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) LDC_NO_TRAP();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ready_txd == B_FALSE) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * No ready tx descriptors. Set the flag to send a message to
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the peer when tx descriptors are ready in transmit routine.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->restart_reqd = B_TRUE;
0e26330710421d79f1fbb73c4f5f75086785b207WENTAO YANG dp->restart_peer_txi = txi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We have some tx descriptors ready to be processed by the receiver.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Send a dring data message to the peer to restart processing.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->restart_reqd = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msg->tag.vio_msgtype = VIO_TYPE_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msg->tag.vio_subtype = VIO_SUBTYPE_INFO;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msg->tag.vio_subtype_env = VIO_DRING_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msg->tag.vio_sid = ldcp->local_session;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msg->dring_ident = ldcp->lane_out.dringp->ident;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msg->start_idx = txi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msg->end_idx = -1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vsw_send_msg_shm(ldcp, (void *)msg,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (vio_dring_msg_t), B_FALSE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->dring_data_msgs_sent++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->restart_reqd = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv == ECONNRESET) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_process_conn_evt(ldcp, VSW_CONN_RESET);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Send dring data msgs (info/ack/nack) over LDC.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_send_msg_shm(vsw_ldc_t *ldcp, void *msgp, int size, boolean_t handle_reset)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int retries = vsw_wretries;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t msglen = size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *dmsg = (vio_dring_msg_t *)msgp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(vswp, "vsw_send_msg (%lld) enter : sending %d bytes",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_id, size);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dmsg->seq_num = atomic_inc_32_nv(&ldcp->dringdata_msgid);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna do {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msglen = size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_write(ldcp->ldc_handle, (caddr_t)msgp, &msglen);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } while (rv == EWOULDBLOCK && --retries > 0);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((rv != 0) || (msglen != size)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "vsw_send_msg_shm:ldc_write failed: "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "chan(%lld) rv(%d) size (%d) msglen(%d)\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_id, rv, size, msglen);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.oerrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If channel has been reset we either handle it here or
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * simply report back that it has been reset and let caller
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * decide what to do.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv == ECONNRESET) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vswp, "%s (%lld) channel reset", __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (handle_reset) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_process_conn_evt(ldcp, VSW_CONN_RESET);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}