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/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Use is subject to license terms.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
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 TxDring data transfer mode of VIO
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Protocol in vsw. The functions in this file are invoked from vsw_ldc.c
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * after TxDring 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 TxDring mode. It also contains
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the transmit and receive data processing functions that are invoked in
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * TxDring mode.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/* Functions exported to vsw_ldc.c */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavio_dring_reg_msg_t *vsw_create_tx_dring_info(vsw_ldc_t *);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint vsw_setup_tx_dring(vsw_ldc_t *ldcp, dring_info_t *dp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vsw_destroy_tx_dring(vsw_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnadring_info_t *vsw_map_rx_dring(vsw_ldc_t *ldcp, void *pkt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vsw_unmap_rx_dring(vsw_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint vsw_dringsend(vsw_ldc_t *, mblk_t *);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vsw_ldc_msg_worker(void *arg);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vsw_stop_msg_thread(vsw_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vsw_process_dringdata(void *, void *);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint vsw_send_msg(vsw_ldc_t *, void *, int, boolean_t);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint vsw_reclaim_dring(dring_info_t *dp, int start);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint vsw_dring_find_free_desc(dring_info_t *, vsw_private_desc_t **, int *);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/* Internal functions */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int vsw_init_multipools(vsw_ldc_t *ldcp, vsw_t *vswp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic dring_info_t *vsw_create_tx_dring(vsw_ldc_t *);
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 boolean_t vsw_jumbo_rxpools;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vsw_chain_len;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vsw_num_descriptors;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vsw_mblk_size1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vsw_mblk_size2;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vsw_mblk_size3;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vsw_mblk_size4;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vsw_num_mblks1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vsw_num_mblks2;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vsw_num_mblks3;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vsw_num_mblks4;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#define VSW_NUM_VMPOOLS 3 /* number of vio mblk pools */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#define SND_DRING_NACK(ldcp, pkt) \
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pkt->tag.vio_subtype = VIO_SUBTYPE_NACK; \
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pkt->tag.vio_sid = ldcp->local_session; \
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) vsw_send_msg(ldcp, (void *)pkt, \
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (vio_dring_msg_t), B_TRUE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavio_dring_reg_msg_t *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_create_tx_dring_info(vsw_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_reg_msg_t *mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp;
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_tx_dring(ldcp)) == NULL)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp = kmem_zalloc(sizeof (vio_dring_reg_msg_t), 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], sizeof (ldc_mem_cookie_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->dring_ident = 0;
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 transmit resources for the channel. The resources consist of a
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * transmit descriptor ring and an associated transmit buffer area.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic dring_info_t *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_create_tx_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 mutex_init(&dp->restart_lock, NULL, MUTEX_DRIVER, NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->lane_out.dringp = dp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* create public section of ring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((ldc_mem_dring_create(vsw_num_descriptors,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (vnet_public_desc_t), &dp->dring_handle)) != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "vsw_create_tx_dring(%lld): ldc dring create "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "failed", ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ASSERT(dp->dring_handle != NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Get the base address of the public section of the ring.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((ldc_mem_dring_info(dp->dring_handle, &minfo)) != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "vsw_create_tx_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_public_desc_t);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->options = VIO_TX_DRING;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->dring_ncookies = 1; /* guaranteed by ldc */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * create private portion of ring
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->priv_addr = (vsw_private_desc_t *)kmem_zalloc(
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (sizeof (vsw_private_desc_t) * vsw_num_descriptors), KM_SLEEP);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (vsw_setup_tx_dring(ldcp, dp)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s: unable to setup ring", __func__);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* bind dring to the channel */
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_tx_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->restart_reqd = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (dp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnafail:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_destroy_tx_dring(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Setup the descriptors in the tx dring.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Returns 0 on success, 1 on failure.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_setup_tx_dring(vsw_ldc_t *ldcp, dring_info_t *dp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_public_desc_t *pub_addr = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_private_desc_t *priv_addr = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint64_t *tmpp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint64_t offset = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t ncookies = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna static char *name = "vsw_setup_ring";
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int i, j, nc, rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t data_sz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna void *data_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr = dp->priv_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub_addr = dp->pub_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* public section may be null but private should never be */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ASSERT(priv_addr != NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Allocate the region of memory which will be used to hold
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the data the descriptors will refer to.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_sz = vswp->max_frame_size + VNET_IPALIGN + VNET_LDCALIGN;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * In order to ensure that the number of ldc cookies per descriptor is
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * limited to be within the default MAX_COOKIES (2), we take the steps
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * outlined below:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Align the entire data buffer area to 8K and carve out per descriptor
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * data buffers starting from this 8K aligned base address.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We round up the mtu specified to be a multiple of 2K or 4K.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * For sizes up to 12K we round up the size to the next 2K.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * For sizes > 12K we round up to the next 4K (otherwise sizes such as
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * 14K could end up needing 3 cookies, with the buffer spread across
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * 3 8K pages: 8K+6K, 2K+8K+2K, 6K+8K, ...).
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (data_sz <= VNET_12K) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_sz = VNET_ROUNDUP_2K(data_sz);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_sz = VNET_ROUNDUP_4K(data_sz);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->desc_data_sz = data_sz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* allocate extra 8K bytes for alignment */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->data_sz = (vsw_num_descriptors * data_sz) + VNET_8K;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_addr = kmem_alloc(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 /* align the starting address of the data area to 8K */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_addr = (void *)VNET_ROUNDUP_8K((uintptr_t)data_addr);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tmpp = (uint64_t *)data_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna offset = dp->desc_data_sz/sizeof (tmpp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Initialise some of the private and public (if they exist)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * descriptor fields.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (i = 0; i < vsw_num_descriptors; i++) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_init(&priv_addr->dstate_lock, NULL, MUTEX_DRIVER, NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((ldc_mem_alloc_handle(ldcp->ldc_handle,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna &priv_addr->memhandle)) != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s: alloc mem handle failed", name);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr->datap = (void *)tmpp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_bind_handle(priv_addr->memhandle,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (caddr_t)priv_addr->datap, dp->desc_data_sz,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna LDC_SHADOW_MAP, LDC_MEM_R|LDC_MEM_W,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna &(priv_addr->memcookie[0]), &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 priv_addr->bound = 1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s: %d: memcookie 0 : addr 0x%llx : size 0x%llx",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna name, i, priv_addr->memcookie[0].addr,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr->memcookie[0].size);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ncookies >= (uint32_t)(VSW_MAX_COOKIES + 1)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld) ldc_mem_bind_handle returned "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "invalid num of cookies (%d) for size 0x%llx",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna name, ldcp->ldc_id, ncookies, VSW_RING_EL_DATA_SZ);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (j = 1; j < ncookies; j++) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_nextcookie(priv_addr->memhandle,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna &(priv_addr->memcookie[j]));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s: ldc_mem_nextcookie "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "failed rv (%d)", name, rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D3(vswp, "%s: memcookie %d : addr 0x%llx : "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "size 0x%llx", name, j,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr->memcookie[j].addr,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr->memcookie[j].size);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr->ncookies = ncookies;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr->dstate = VIO_DESC_FREE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (pub_addr != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* link pub and private sides */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr->descp = pub_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub_addr->ncookies = priv_addr->ncookies;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (nc = 0; nc < pub_addr->ncookies; nc++) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bcopy(&priv_addr->memcookie[nc],
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna &pub_addr->memcookie[nc],
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (ldc_mem_cookie_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub_addr->hdr.dstate = VIO_DESC_FREE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub_addr++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * move to next element in the dring and the next
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * position in the data buffer.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tmpp += offset;
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 transmit resources for the channel.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_destroy_tx_dring(vsw_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_private_desc_t *paddr = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int i;
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->priv_addr != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * First unbind and free the memory handles
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * stored in each descriptor within the ring.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (i = 0; i < vsw_num_descriptors; i++) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna paddr = (vsw_private_desc_t *)dp->priv_addr + i;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (paddr->memhandle != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (paddr->bound == 1) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldc_mem_unbind_handle(
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna paddr->memhandle) != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(NULL, "error "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "unbinding handle for "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "ring 0x%llx at pos %d",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp, i);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna continue;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna paddr->bound = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldc_mem_free_handle(
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna paddr->memhandle) != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(NULL, "error freeing "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "handle for ring 0x%llx "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "at pos %d", dp, i);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna continue;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna paddr->memhandle = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_destroy(&paddr->dstate_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kmem_free(dp->priv_addr,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (sizeof (vsw_private_desc_t) * vsw_num_descriptors));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Now unbind and destroy the ring itself.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
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->data_addr != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kmem_free(dp->data_addr, dp->data_sz);
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 transmit descriptor ring exported
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * by the peer, as our receive descriptor ring.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnadring_info_t *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_map_rx_dring(vsw_ldc_t *ldcp, void *pkt)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_reg_msg_t *dring_pkt = pkt;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
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 /* TxDring mode specific initializations */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->end_idx = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->lane_in.dringp = dp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Allocate pools of receive mblks */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vsw_init_multipools(ldcp, vswp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We do not return failure if receive mblk pools can't
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * be allocated, instead allocb(9F) will be used to
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * dynamically allocate buffers during receive.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vswp, "%s: unable to create free mblk pools for"
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna " channel %ld (rv %d)", __func__, ldcp->ldc_id, rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (dp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Unmap the receive descriptor ring.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_unmap_rx_dring(vsw_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_mblk_pool_t *fvmp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
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 /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If we can't destroy all the rx pools for this channel,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * dispatch a task to retry and clean up those rx pools. Note
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * that we don't need to wait for the task to complete. If the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * vsw device itself gets detached (vsw_detach()), it will wait
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * for the task to complete implicitly in ddi_taskq_destroy().
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_destroy_multipools(&ldcp->vmp, &fvmp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (fvmp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ddi_taskq_dispatch(vswp->rxp_taskq,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_destroy_rxpools, fvmp, DDI_SLEEP);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
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 (dring_info_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna lp->dringp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_init_multipools(vsw_ldc_t *ldcp, vsw_t *vswp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t data_sz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t sz1 = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t sz2 = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t sz3 = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t sz4 = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We round up the mtu specified to be a multiple of 2K to limit the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * number of rx buffer pools created for a given mtu.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_sz = vswp->max_frame_size + VNET_IPALIGN + VNET_LDCALIGN;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_sz = VNET_ROUNDUP_2K(data_sz);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If pool sizes are specified, use them. Note that the presence of
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the first tunable will be used as a hint.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (vsw_mblk_size1 != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz1 = vsw_mblk_size1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz2 = vsw_mblk_size2;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz3 = vsw_mblk_size3;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz4 = vsw_mblk_size4;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (sz4 == 0) { /* need 3 pools */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->max_rxpool_size = sz3;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vio_init_multipools(&ldcp->vmp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VSW_NUM_VMPOOLS, sz1, sz2, sz3,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_num_mblks1, vsw_num_mblks2, vsw_num_mblks3);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->max_rxpool_size = sz4;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vio_init_multipools(&ldcp->vmp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VSW_NUM_VMPOOLS + 1, sz1, sz2, sz3, sz4,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_num_mblks1, vsw_num_mblks2, vsw_num_mblks3,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_num_mblks4);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Pool sizes are not specified. We select the pool sizes based on the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * mtu if vnet_jumbo_rxpools is enabled.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (vsw_jumbo_rxpools == B_FALSE || data_sz == VNET_2K) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Receive buffer pool allocation based on mtu is disabled.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Use the default mechanism of standard size pool allocation.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz1 = VSW_MBLK_SZ_128;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz2 = VSW_MBLK_SZ_256;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz3 = VSW_MBLK_SZ_2048;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->max_rxpool_size = sz3;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vio_init_multipools(&ldcp->vmp, VSW_NUM_VMPOOLS,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz1, sz2, sz3,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_num_mblks1, vsw_num_mblks2, vsw_num_mblks3);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna switch (data_sz) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna case VNET_4K:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz1 = VSW_MBLK_SZ_128;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz2 = VSW_MBLK_SZ_256;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz3 = VSW_MBLK_SZ_2048;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz4 = sz3 << 1; /* 4K */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->max_rxpool_size = sz4;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vio_init_multipools(&ldcp->vmp, VSW_NUM_VMPOOLS + 1,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz1, sz2, sz3, sz4,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_num_mblks1, vsw_num_mblks2, vsw_num_mblks3,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_num_mblks4);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna default: /* data_sz: 4K+ to 16K */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz1 = VSW_MBLK_SZ_256;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz2 = VSW_MBLK_SZ_2048;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz3 = data_sz >> 1; /* Jumbo-size/2 */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz4 = data_sz; /* Jumbo-size */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->max_rxpool_size = sz4;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vio_init_multipools(&ldcp->vmp, VSW_NUM_VMPOOLS + 1,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz1, sz2, sz3, sz4,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_num_mblks1, vsw_num_mblks2, vsw_num_mblks3,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_num_mblks4);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Generic routine to send message out over ldc channel.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * It is possible that when we attempt to write over the ldc channel
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * that we get notified that it has been reset. Depending on the value
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * of the handle_reset flag we either handle that event here or simply
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * notify the caller that the channel was reset.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_send_msg(vsw_ldc_t *ldcp, void *msgp, int size, boolean_t handle_reset)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t msglen = size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_msg_tag_t *tag = (vio_msg_tag_t *)msgp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *dmsg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_raw_data_msg_t *rmsg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_ibnd_desc_t *imsg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t data_msg = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int retries = vsw_wretries;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(vswp, "vsw_send_msg (%lld) enter : sending %d bytes",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_id, size);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "send_msg: type 0x%llx", tag->vio_msgtype);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "send_msg: stype 0x%llx", tag->vio_subtype);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "send_msg: senv 0x%llx", tag->vio_subtype_env);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->ldc_txlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (tag->vio_subtype == VIO_SUBTYPE_INFO) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (tag->vio_subtype_env == VIO_DRING_DATA) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dmsg = (vio_dring_msg_t *)tag;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dmsg->seq_num = ldcp->lane_out.seq_num;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_msg = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else if (tag->vio_subtype_env == VIO_PKT_DATA) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rmsg = (vio_raw_data_msg_t *)tag;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rmsg->seq_num = ldcp->lane_out.seq_num;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_msg = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else if (tag->vio_subtype_env == VIO_DESC_DATA) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna imsg = (vnet_ibnd_desc_t *)tag;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna imsg->hdr.seq_num = ldcp->lane_out.seq_num;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_msg = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
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 && data_msg == B_TRUE) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->lane_out.seq_num++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((rv != 0) || (msglen != size)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "vsw_send_msg:ldc_write failed: chan(%lld) rv(%d) "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "size (%d) msglen(%d)\n", ldcp->ldc_id, rv, size, msglen);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.oerrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->ldc_txlock);
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}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * A per LDC worker thread to process ldc messages. This thread is woken up by
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the LDC interrupt handler to process LDC packets and receive data.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_ldc_msg_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->msg_thr_lock, callb_generic_cpr,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "vsw_msg_thread");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->msg_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna while (!(ldcp->msg_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->msg_thr_flags &
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (VSW_WTHR_DATARCVD | VSW_WTHR_STOP))) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna cv_wait(&ldcp->msg_thr_cv, &ldcp->msg_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna CALLB_CPR_SAFE_END(&cprinfo, &ldcp->msg_thr_lock)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * First process the stop request.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->msg_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->msg_thr_flags &= ~VSW_WTHR_DATARCVD;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->msg_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(vswp, "%s(%lld):calling vsw_process_pkt\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->ldc_cblock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_process_pkt(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->ldc_cblock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->msg_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->msg_thr_flags &= ~VSW_WTHR_STOP;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->msg_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/* Co-ordinate with msg processing thread to stop it */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_stop_msg_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 msg process thread stops.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->msg_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->msg_thread != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tid = ldcp->msg_thread->t_did;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->msg_thr_flags |= VSW_WTHR_STOP;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna cv_signal(&ldcp->msg_thr_cv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->msg_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 Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Send packet out via descriptor ring to a logical device.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_dringsend(vsw_ldc_t *ldcp, mblk_t *mp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t dring_pkt;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_private_desc_t *priv_desc = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_public_desc_t *pub = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *bp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t n, size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna caddr_t bufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int status = LDC_TX_SUCCESS;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna struct ether_header *ehp = (struct ether_header *)mp->b_rptr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna lane_t *lp = &ldcp->lane_out;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(vswp, "%s(%lld): enter\n", __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* TODO: make test a macro */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((!(ldcp->lane_out.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 ldcp->lane_out.lstate);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.oerrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (LDC_TX_FAILURE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((dp = ldcp->lane_out.dringp) == 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 ldcp->ldc_stats.oerrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (LDC_TX_FAILURE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size = msgsize(mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (size > (size_t)lp->mtu) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld) invalid size (%ld)\n", __func__,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_id, size);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.oerrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (LDC_TX_FAILURE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Find a free descriptor
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Note: for the moment we are assuming that we will only
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * have one dring going from the switch to each of its
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * peers. This may change in the future.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (vsw_dring_find_free_desc(dp, &priv_desc, &idx) != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s(%lld): no descriptor available for ring "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "at 0x%llx", __func__, ldcp->ldc_id, dp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* nothing more we can do */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna status = LDC_TX_NORESOURCES;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.tx_no_desc++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto vsw_dringsend_free_exit;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s(%lld): free private descriptor found at pos %ld "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "addr 0x%llx\n", __func__, ldcp->ldc_id, idx, priv_desc);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* copy data into the descriptor */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bufp = priv_desc->datap;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bufp += VNET_IPALIGN;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (bp = mp, n = 0; bp != NULL; bp = bp->b_cont) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna n = MBLKL(bp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bcopy(bp->b_rptr, bufp, n);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bufp += n;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_desc->datalen = (size < (size_t)ETHERMIN) ? ETHERMIN : size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub = priv_desc->descp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub->nbytes = priv_desc->datalen;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* update statistics */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (IS_BROADCAST(ehp))
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.brdcstxmt++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna else if (IS_MULTICAST(ehp))
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.multixmt++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.opackets++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.obytes += priv_desc->datalen;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&priv_desc->dstate_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub->hdr.dstate = VIO_DESC_READY;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&priv_desc->dstate_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Determine whether or not we need to send a message to our
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * peer prompting them to read our newly updated descriptor(s).
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->restart_reqd) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->restart_reqd = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.dring_data_msgs_sent++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Send a vio_dring_msg to peer to prompt them to read
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the updated descriptor ring.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt.tag.vio_msgtype = VIO_TYPE_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt.tag.vio_subtype = VIO_SUBTYPE_INFO;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt.tag.vio_subtype_env = VIO_DRING_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt.tag.vio_sid = ldcp->local_session;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Note - for now using first ring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt.dring_ident = dp->ident;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If last_ack_recv is -1 then we know we've not
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * received any ack's yet, so this must be the first
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * msg sent, so set the start to the begining of the ring.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&dp->dlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->last_ack_recv == -1) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt.start_idx = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt.start_idx =
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (dp->last_ack_recv + 1) % dp->num_descriptors;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt.end_idx = -1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->dlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D3(vswp, "%s(%lld): dring 0x%llx : ident 0x%llx\n", __func__,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_id, dp, dring_pkt.dring_ident);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D3(vswp, "%s(%lld): start %lld : end %lld :\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id, dring_pkt.start_idx,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt.end_idx);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) vsw_send_msg(ldcp, (void *)&dring_pkt,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (vio_dring_msg_t), B_TRUE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (status);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s(%lld): updating descp %d", __func__,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_id, idx);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_dringsend_free_exit:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(vswp, "%s(%lld): exit\n", __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (status);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Searches the private section of a ring for a free descriptor,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * starting at the location of the last free descriptor found
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * previously.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Returns 0 if free descriptor is available, and updates state
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * of private descriptor to VIO_DESC_READY, otherwise returns 1.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * FUTURE: might need to return contiguous range of descriptors
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * as dring info msg assumes all will be contiguous.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_dring_find_free_desc(dring_info_t *dringp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_private_desc_t **priv_p, int *idx)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_private_desc_t *addr = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int num = vsw_num_descriptors;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int ret = 1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(NULL, "%s enter\n", __func__);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ASSERT(dringp->priv_addr != NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(NULL, "%s: searching ring, dringp 0x%llx : start pos %lld",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, dringp, dringp->end_idx);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna addr = (vsw_private_desc_t *)dringp->priv_addr + dringp->end_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&addr->dstate_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (addr->dstate == VIO_DESC_FREE) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna addr->dstate = VIO_DESC_READY;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *priv_p = addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna *idx = dringp->end_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dringp->end_idx = (dringp->end_idx + 1) % num;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ret = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&addr->dstate_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* ring full */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ret == 1) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(NULL, "%s: no desp free: started at %d", __func__,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dringp->end_idx);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(NULL, "%s: exit\n", __func__);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (ret);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/* vsw_reclaim_dring -- reclaim descriptors */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_reclaim_dring(dring_info_t *dp, int start)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int i, j, len;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_private_desc_t *priv_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_public_desc_t *pub_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub_addr = (vnet_public_desc_t *)dp->pub_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr = (vsw_private_desc_t *)dp->priv_addr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna len = dp->num_descriptors;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(NULL, "%s: start index %ld\n", __func__, start);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna j = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (i = start; j < len; i = (i + 1) % len, j++) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub_addr = (vnet_public_desc_t *)dp->pub_addr + i;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr = (vsw_private_desc_t *)dp->priv_addr + i;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&priv_addr->dstate_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (pub_addr->hdr.dstate != VIO_DESC_DONE) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&priv_addr->dstate_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub_addr->hdr.dstate = VIO_DESC_FREE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr->dstate = VIO_DESC_FREE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* clear all the fields */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr->datalen = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub_addr->hdr.ack = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&priv_addr->dstate_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D3(NULL, "claiming descp:%d pub state:0x%llx priv state 0x%llx",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna i, pub_addr->hdr.dstate, priv_addr->dstate);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (j);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_process_dringdata(void *arg, void *dpkt)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_ldc_t *ldcp = arg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *dring_pkt;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_public_desc_t desc, *pub_addr = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_private_desc_t *priv_addr = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_info_t *dp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_t *vswp = ldcp->ldc_vswp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *mp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_mblk_t *vmp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *bp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *bpt = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t nbytes = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint64_t chain = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint64_t len;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t pos, start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t range_start, range_end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int32_t end, num, cnt = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int i, rv, rng_rv = 0, msg_rv = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t prev_desc_ack = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int read_attempts = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna struct ether_header *ehp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna lane_t *lp = &ldcp->lane_out;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D1(vswp, "%s(%lld): enter", __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We know this is a data/dring packet so
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * cast it into the correct structure.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt = (vio_dring_msg_t *)dpkt;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Switch on the vio_subtype. If its INFO then we need to
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * process the data. If its an ACK we need to make sure
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * it makes sense (i.e did we send an earlier data/info),
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * and if its a NACK then we maybe attempt a retry.
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
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp = ldcp->lane_in.dringp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->ident != dring_pkt->dring_ident) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld): unable to find dring from "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "ident 0x%llx", __func__, ldcp->ldc_id,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->dring_ident);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna SND_DRING_NACK(ldcp, dring_pkt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.dring_data_msgs_rcvd++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna start = pos = dring_pkt->start_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna end = dring_pkt->end_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna len = dp->num_descriptors;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna range_start = range_end = pos;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s(%lld): start index %ld : end %ld\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id, start, end);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (end == -1) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna num = -1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else if (end >= 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna num = end >= pos ? end - pos + 1: (len - pos + 1) + end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* basic sanity check */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (end > len) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld): endpoint %lld outside "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "ring length %lld", __func__,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_id, end, len);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna SND_DRING_NACK(ldcp, dring_pkt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld): invalid endpoint %lld",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id, end);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna SND_DRING_NACK(ldcp, dring_pkt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna while (cnt != num) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_recheck_desc:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub_addr = (vnet_public_desc_t *)dp->pub_addr + pos;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((rng_rv = vnet_dring_entry_copy(pub_addr,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna &desc, dp->dring_mtype, dp->dring_handle,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pos, pos)) != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld): unable to copy "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "descriptor at pos %d: err %d",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, pos, ldcp->ldc_id, rng_rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.ierrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * When given a bounded range of descriptors
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * to process, its an error to hit a descriptor
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * which is not ready. In the non-bounded case
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * (end_idx == -1) this simply indicates we have
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * reached the end of the current active range.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (desc.hdr.dstate != VIO_DESC_READY) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* unbound - no error */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (end == -1) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (read_attempts == vsw_recv_retries)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna delay(drv_usectohz(vsw_recv_delay));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna read_attempts++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto vsw_recheck_desc;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* bounded - error - so NACK back */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld): descriptor not READY "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "(%d)", __func__, ldcp->ldc_id,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna desc.hdr.dstate);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna SND_DRING_NACK(ldcp, dring_pkt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DTRACE_PROBE1(read_attempts, int, read_attempts);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna range_end = pos;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If we ACK'd the previous descriptor then now
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * record the new range start position for later
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * ACK's.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (prev_desc_ack) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna range_start = pos;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s(%lld): updating range start to be "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "%d", __func__, ldcp->ldc_id, range_start);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna prev_desc_ack = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s(%lld): processing desc %lld at pos"
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna " 0x%llx : dstate 0x%lx : datalen 0x%lx",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id, pos, &desc,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna desc.hdr.dstate, desc.nbytes);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((desc.nbytes < ETHERMIN) ||
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (desc.nbytes > lp->mtu)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* invalid size; drop the packet */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.ierrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto vsw_process_desc_done;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Ensure that we ask ldc for an aligned
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * number of bytes. Data is padded to align on 8
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * byte boundary, desc.nbytes is actual data length,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * i.e. minus that padding.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna nbytes = (desc.nbytes + VNET_IPALIGN + 7) & ~7;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (nbytes > ldcp->max_rxpool_size) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp = allocb(desc.nbytes + VNET_IPALIGN + 8,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna BPRI_MED);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmp = vio_multipool_allocb(&ldcp->vmp, nbytes);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (vmp == NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.rx_vio_allocb_fail++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * No free receive buffers available,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * so fallback onto allocb(9F). Make
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * sure that we get a data buffer which
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * is a multiple of 8 as this is
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * required by ldc_mem_copy.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DTRACE_PROBE(allocb);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp = allocb(desc.nbytes +
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VNET_IPALIGN + 8, BPRI_MED);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp = vmp->mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (mp == NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%ld): allocb failed",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rng_rv = vnet_dring_entry_set_dstate(pub_addr,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->dring_mtype, dp->dring_handle, pos, pos,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VIO_DESC_DONE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.ierrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.rx_allocb_fail++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_copy(ldcp->ldc_handle,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (caddr_t)mp->b_rptr, 0, &nbytes,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna desc.memcookie, desc.ncookies, LDC_COPY_IN);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%d): unable to copy in data "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "from %d cookies in desc %d (rv %d)",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id, desc.ncookies,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pos, rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna freemsg(mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rng_rv = vnet_dring_entry_set_dstate(pub_addr,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->dring_mtype, dp->dring_handle, pos, pos,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VIO_DESC_DONE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.ierrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s(%d): copied in %ld bytes"
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna " using %d cookies", __func__,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_id, nbytes, desc.ncookies);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* adjust the read pointer to skip over the padding */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->b_rptr += VNET_IPALIGN;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* point to the actual end of data */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->b_wptr = mp->b_rptr + desc.nbytes;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (vmp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmp->state = VIO_MBLK_HAS_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* update statistics */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ehp = (struct ether_header *)mp->b_rptr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (IS_BROADCAST(ehp))
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.brdcstrcv++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna else if (IS_MULTICAST(ehp))
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.multircv++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.ipackets++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.rbytes += desc.nbytes;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * IPALIGN space can be used for VLAN_TAG
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) vsw_vlan_frame_pretag(ldcp->ldc_port,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VSW_VNETPORT, mp);
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 bp->b_next = bp->b_prev = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bpt = bp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna chain = 1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->b_next = mp->b_prev = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bpt->b_next = mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bpt = mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna chain++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavsw_process_desc_done:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* mark we are finished with this descriptor */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((rng_rv = vnet_dring_entry_set_dstate(pub_addr,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->dring_mtype, dp->dring_handle, pos, pos,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VIO_DESC_DONE)) != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld): unable to update "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "dstate at pos %d: err %d",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, pos, ldcp->ldc_id, rng_rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.ierrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Send an ACK back to peer if requested.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (desc.hdr.ack) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->start_idx = range_start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->end_idx = range_end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s(%lld): processed %d %d, ACK"
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna " requested", __func__, ldcp->ldc_id,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->start_idx, dring_pkt->end_idx);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->dring_process_state = VIO_DP_ACTIVE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->tag.vio_subtype = VIO_SUBTYPE_ACK;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->tag.vio_sid = ldcp->local_session;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msg_rv = vsw_send_msg(ldcp, (void *)dring_pkt,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (vio_dring_msg_t), B_FALSE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Check if ACK was successfully sent. If not
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * we break and deal with that below.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (msg_rv != 0)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna prev_desc_ack = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna range_start = pos;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* next descriptor */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pos = (pos + 1) % len;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna cnt++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Break out of loop here and stop processing to
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * allow some other network device (or disk) to
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * get access to the cpu.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (chain > vsw_chain_len) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D3(vswp, "%s(%lld): switching chain of %d "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "msgs", __func__, ldcp->ldc_id, chain);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* send the chain of packets to be switched */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (bp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DTRACE_PROBE1(vsw_rcv_msgs, int, chain);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D3(vswp, "%s(%lld): switching chain of %d msgs",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id, chain);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vswp->vsw_switch_frame(vswp, bp, VSW_VNETPORT,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_port, NULL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If when we encountered an error when attempting to
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * access an imported dring, initiate a connection reset.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rng_rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_process_conn_evt(ldcp, VSW_CONN_RESTART);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If when we attempted to send the ACK we found that the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * channel had been reset then now handle this.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (msg_rv == ECONNRESET) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_process_conn_evt(ldcp, VSW_CONN_RESET);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DTRACE_PROBE1(msg_cnt, int, cnt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We are now finished so ACK back with the state
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * set to STOPPING so our peer knows we are finished
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->tag.vio_subtype = VIO_SUBTYPE_ACK;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->tag.vio_sid = ldcp->local_session;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->dring_process_state = VIO_DP_STOPPED;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DTRACE_PROBE(stop_process_sent);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We have not processed any more descriptors beyond
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the last one we ACK'd.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (prev_desc_ack)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna range_start = range_end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->start_idx = range_start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->end_idx = range_end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s(%lld) processed : %d : %d, now stopping",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id, dring_pkt->start_idx,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->end_idx);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) vsw_send_msg(ldcp, (void *)dring_pkt,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (vio_dring_msg_t), B_TRUE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.dring_data_acks_sent++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.dring_stopped_acks_sent++;
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 /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Verify that the relevant descriptors are all
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * marked as DONE
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp = ldcp->lane_out.dringp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dp->ident != dring_pkt->dring_ident) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DERR(vswp, "%s: unknown ident in ACK", __func__);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna start = end = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna start = dring_pkt->start_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna end = dring_pkt->end_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna len = dp->num_descriptors;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&dp->dlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->last_ack_recv = end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.dring_data_acks_rcvd++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->dlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) vsw_reclaim_dring(dp, start);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If our peer is stopping processing descriptors then
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * we check to make sure it has processed all the descriptors
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * we have updated. If not then we send it a new message
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * to prompt it to restart.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dring_pkt->dring_process_state == VIO_DP_STOPPED) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DTRACE_PROBE(stop_process_recv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s(%lld): got stopping msg : %d : %d",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna __func__, ldcp->ldc_id, dring_pkt->start_idx,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->end_idx);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Check next descriptor in public section of ring.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If its marked as READY then we need to prompt our
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * peer to start processing the ring again.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna i = (end + 1) % len;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna pub_addr = (vnet_public_desc_t *)dp->pub_addr + i;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna priv_addr = (vsw_private_desc_t *)dp->priv_addr + i;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Hold the restart lock across all of this to
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * make sure that its not possible for us to
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * decide that a msg needs to be sent in the future
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * but the sending code having already checked is
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * about to exit.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.dring_stopped_acks_rcvd++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&priv_addr->dstate_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (pub_addr->hdr.dstate == VIO_DESC_READY) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&priv_addr->dstate_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->tag.vio_subtype = VIO_SUBTYPE_INFO;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->tag.vio_sid = ldcp->local_session;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->start_idx = (end + 1) % len;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->end_idx = -1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna D2(vswp, "%s(%lld) : sending restart msg:"
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna " %d : %d", __func__, ldcp->ldc_id,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dring_pkt->start_idx, dring_pkt->end_idx);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msg_rv = vsw_send_msg(ldcp, (void *)dring_pkt,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (vio_dring_msg_t), B_FALSE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_stats.dring_data_msgs_sent++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&priv_addr->dstate_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dp->restart_reqd = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&dp->restart_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (msg_rv == ECONNRESET)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vsw_process_conn_evt(ldcp, VSW_CONN_RESET);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
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
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 D1(vswp, "%s(%lld) exit", __func__, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}