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/ethernet.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/mach_descrip.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/mdeg.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#include <sys/vnet.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#include <sys/vnet_gen.h>
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * This file contains the implementation of TxDring data transfer mode of VIO
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Protocol in vnet. The functions in this file are invoked from vnet_gen.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 vnet_gen.c */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint vgen_create_tx_dring(vgen_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vgen_destroy_tx_dring(vgen_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint vgen_map_rx_dring(vgen_ldc_t *ldcp, void *pkt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vgen_unmap_rx_dring(vgen_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint vgen_dringsend(void *arg, mblk_t *mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vgen_ldc_msg_worker(void *arg);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid vgen_stop_msg_thread(vgen_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint vgen_handle_dringdata(void *arg1, void *arg2);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnamblk_t *vgen_poll_rcv(vgen_ldc_t *ldcp, int bytes_to_pickup);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint vgen_check_datamsg_seq(vgen_ldc_t *ldcp, vio_msg_tag_t *tagp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint vgen_sendmsg(vgen_ldc_t *ldcp, caddr_t msg, size_t msglen,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t caller_holds_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/* Internal functions */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int vgen_init_multipools(vgen_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int vgen_handle_dringdata_info(vgen_ldc_t *ldcp, vio_msg_tag_t *tagp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int vgen_process_dringdata(vgen_ldc_t *ldcp, vio_msg_tag_t *tagp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int vgen_handle_dringdata_ack(vgen_ldc_t *ldcp, vio_msg_tag_t *tagp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int vgen_handle_dringdata_nack(vgen_ldc_t *ldcp, vio_msg_tag_t *tagp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic void vgen_rx(vgen_ldc_t *ldcp, mblk_t *bp, mblk_t *bpt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int vgen_send_dringdata(vgen_ldc_t *ldcp, uint32_t start, int32_t end);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int vgen_send_dringack(vgen_ldc_t *ldcp, vio_msg_tag_t *tagp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t start, int32_t end, uint8_t pstate);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic void vgen_reclaim(vgen_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic void vgen_reclaim_dring(vgen_ldc_t *ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/* Functions imported from vnet_gen.c */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern int vgen_handle_evt_read(vgen_ldc_t *ldcp, vgen_caller_t caller);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern int vgen_handle_evt_reset(vgen_ldc_t *ldcp, vgen_caller_t caller);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern void vgen_handle_pkt_data(void *arg1, void *arg2, uint32_t msglen);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern void vgen_destroy_rxpools(void *arg);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/* Tunables */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern int vgen_rxpool_cleanup_delay;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern boolean_t vnet_jumbo_rxpools;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vnet_num_descriptors;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vgen_chain_len;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vgen_ldcwr_retries;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vgen_recv_delay;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vgen_recv_retries;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vgen_rbufsz1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vgen_rbufsz2;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vgen_rbufsz3;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vgen_rbufsz4;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vgen_nrbufs1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vgen_nrbufs2;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vgen_nrbufs3;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern uint32_t vgen_nrbufs4;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#ifdef DEBUG
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#define DEBUG_PRINTF vgen_debug_printf
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern int vnet_dbglevel;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern int vgen_inject_err_flag;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern void vgen_debug_printf(const char *fname, vgen_t *vgenp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_ldc_t *ldcp, const char *fmt, ...);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaextern boolean_t vgen_inject_error(vgen_ldc_t *ldcp, int error);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#endif
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 Basavapatnaint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_create_tx_dring(vgen_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int i;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldc_mem_info_t minfo;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t txdsize;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t tbufsize;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_private_desc_t *tbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_public_desc_t *txdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_entry_hdr_t *hdrp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna caddr_t datap = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int ci;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t ncookies;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t data_sz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->num_txds = vnet_num_descriptors;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdsize = sizeof (vnet_public_desc_t);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufsize = sizeof (vgen_private_desc_t);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* allocate transmit buffer ring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp = kmem_zalloc(ldcp->num_txds * tbufsize, KM_NOSLEEP);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (tbufp == NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (DDI_FAILURE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->tbufp = tbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->tbufendp = &((ldcp->tbufp)[ldcp->num_txds]);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* create transmit descriptor ring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_dring_create(ldcp->num_txds, txdsize,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna &ldcp->tx_dring_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "ldc_mem_dring_create() failed\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* get the addr of descriptor ring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_dring_info(ldcp->tx_dring_handle, &minfo);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "ldc_mem_dring_info() failed\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->txdp = (vnet_public_desc_t *)(minfo.vaddr);
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 data_sz = vgenp->max_frame_size + VNET_IPALIGN + VNET_LDCALIGN;
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 /* allocate extra 8K bytes for alignment */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->tx_data_sz = (data_sz * ldcp->num_txds) + VNET_8K;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna datap = kmem_zalloc(ldcp->tx_data_sz, KM_SLEEP);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->tx_datap = datap;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* align the starting address of the data area to 8K */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna datap = (caddr_t)VNET_ROUNDUP_8K((uintptr_t)datap);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * for each private descriptor, allocate a ldc mem_handle which is
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * required to map the data during transmit, set the flags
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * to free (available for use by transmit routine).
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (i = 0; i < ldcp->num_txds; i++) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp = &(ldcp->tbufp[i]);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_alloc_handle(ldcp->ldc_handle,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna &(tbufp->memhandle));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp->memhandle = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * bind ldc memhandle to the corresponding transmit buffer.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ci = ncookies = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_bind_handle(tbufp->memhandle,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (caddr_t)datap, data_sz, LDC_SHADOW_MAP,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna LDC_MEM_R, &(tbufp->memcookie[ci]), &ncookies);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * successful in binding the handle to tx data buffer.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * set datap in the private descr to this buffer.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp->datap = datap;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((ncookies == 0) ||
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (ncookies > MAX_COOKIES)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (ci = 1; ci < ncookies; ci++) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_nextcookie(tbufp->memhandle,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna &(tbufp->memcookie[ci]));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp->ncookies = ncookies;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna datap += data_sz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp->flags = VGEN_PRIV_DESC_FREE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp = &(ldcp->txdp[i]);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp = &txdp->hdr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp->dstate = VIO_DESC_FREE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp->ack = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp->descp = txdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * The descriptors and the associated buffers are all ready;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * now bind descriptor ring to the channel.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_dring_bind(ldcp->ldc_handle, ldcp->tx_dring_handle,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna LDC_DIRECT_MAP | LDC_SHADOW_MAP, LDC_MEM_RW,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna &ldcp->tx_dring_cookie, &ncookies);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "ldc_mem_dring_bind failed "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "rv(%x)\n", rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ASSERT(ncookies == 1);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->tx_dring_ncookies = ncookies;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* reset tbuf walking pointers */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_tbufp = ldcp->tbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->cur_tbufp = ldcp->tbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* initialize tx seqnum and index */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_txseq = VNET_ISS;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_txi = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->resched_peer = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->resched_peer_txi = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (VGEN_SUCCESS);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnafail:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_destroy_tx_dring(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (VGEN_FAILURE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Free transmit resources for the channel.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_destroy_tx_dring(vgen_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int i;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int tbufsize = sizeof (vgen_private_desc_t);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_private_desc_t *tbufp = ldcp->tbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* We first unbind the descriptor ring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->tx_dring_ncookies != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_dring_unbind(ldcp->tx_dring_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->tx_dring_ncookies = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Unbind transmit buffers */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->tbufp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* for each tbuf (priv_desc), free ldc mem_handle */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (i = 0; i < ldcp->num_txds; i++) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp = &(ldcp->tbufp[i]);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (tbufp->datap) { /* if bound to a ldc memhandle */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_unbind_handle(tbufp->memhandle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp->datap = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (tbufp->memhandle) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_free_handle(tbufp->memhandle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp->memhandle = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Free tx data buffer area */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->tx_datap != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kmem_free(ldcp->tx_datap, ldcp->tx_data_sz);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->tx_datap = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->tx_data_sz = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Free transmit descriptor ring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->tx_dring_handle != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_dring_destroy(ldcp->tx_dring_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->tx_dring_handle = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->txdp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Free transmit buffer ring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->tbufp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kmem_free(ldcp->tbufp, ldcp->num_txds * tbufsize);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->tbufp = ldcp->tbufendp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
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 Basavapatnaint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_map_rx_dring(vgen_ldc_t *ldcp, void *pkt)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldc_mem_info_t minfo;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldc_mem_cookie_t dcookie;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t ncookies;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t num_desc;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t desc_size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_reg_msg_t *msg = pkt;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ncookies = msg->ncookies;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna num_desc = msg->num_descriptors;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna desc_size = msg->descriptor_size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bcopy(&msg->cookie[0], &dcookie, sizeof (ldc_mem_cookie_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Sanity check.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (num_desc < VGEN_NUM_DESCRIPTORS_MIN ||
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna desc_size < sizeof (vnet_public_desc_t)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Map the remote dring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_dring_map(ldcp->ldc_handle, &dcookie, ncookies, num_desc,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna desc_size, LDC_DIRECT_MAP, &(ldcp->rx_dring_handle));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Sucessfully mapped, now try to get info about the mapped dring
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_dring_info(ldcp->rx_dring_handle, &minfo);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto fail;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Save ring address, number of descriptors.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->mrxdp = (vnet_public_desc_t *)(minfo.vaddr);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bcopy(&dcookie, &(ldcp->rx_dring_cookie), sizeof (dcookie));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->rx_dring_ncookies = ncookies;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->num_rxds = num_desc;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Initialize rx dring indexes and seqnum */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_rxi = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_rxseq = VNET_ISS;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->dring_mtype = minfo.mtype;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Save peer's dring_info values */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bcopy(&dcookie, &(ldcp->peer_hparams.dring_cookie),
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (ldc_mem_cookie_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->peer_hparams.num_desc = num_desc;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->peer_hparams.desc_size = desc_size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->peer_hparams.dring_ncookies = ncookies;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Set dring_ident for the peer */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->peer_hparams.dring_ident = (uint64_t)ldcp->txdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Return the dring_ident in ack msg */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msg->dring_ident = (uint64_t)ldcp->txdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* alloc rx mblk pools */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_init_multipools(ldcp);
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(vgenp, ldcp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "vnet%d: failed to allocate rx mblk "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "pools for channel(0x%lx)\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgenp->instance, ldcp->ldc_id);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (VGEN_SUCCESS);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnafail:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->rx_dring_handle != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_dring_unmap(ldcp->rx_dring_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->rx_dring_handle = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (VGEN_FAILURE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Unmap the receive descriptor ring.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_unmap_rx_dring(vgen_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_mblk_pool_t *vmp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Destroy receive mblk pools */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_destroy_multipools(&ldcp->vmp, &vmp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (vmp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If we can't destroy the rx pool for this channel,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * dispatch a task to retry and clean up. Note that we
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * don't need to wait for the task to complete. If the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * vnet device itself gets detached, it will wait for
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the task to complete implicitly in
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * ddi_taskq_destroy().
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ddi_taskq_dispatch(vgenp->rxp_taskq,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_destroy_rxpools, vmp, DDI_SLEEP);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Unmap peer's dring */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->rx_dring_handle != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) ldc_mem_dring_unmap(ldcp->rx_dring_handle);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->rx_dring_handle = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* clobber rx ring members */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bzero(&ldcp->rx_dring_cookie, sizeof (ldcp->rx_dring_cookie));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->mrxdp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_rxi = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->num_rxds = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_rxseq = VNET_ISS;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/* Allocate receive resources */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_init_multipools(vgen_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t data_sz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int status;
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.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We then create rx pools based on the rounded up size.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_sz = vgenp->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 (vgen_rbufsz1 != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz1 = vgen_rbufsz1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz2 = vgen_rbufsz2;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz3 = vgen_rbufsz3;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz4 = vgen_rbufsz4;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (sz4 == 0) { /* need 3 pools */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->max_rxpool_size = sz3;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna status = vio_init_multipools(&ldcp->vmp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VGEN_NUM_VMPOOLS, sz1, sz2, sz3, vgen_nrbufs1,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_nrbufs2, vgen_nrbufs3);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->max_rxpool_size = sz4;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna status = vio_init_multipools(&ldcp->vmp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VGEN_NUM_VMPOOLS + 1, sz1, sz2, sz3, sz4,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_nrbufs1, vgen_nrbufs2, vgen_nrbufs3,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_nrbufs4);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (status);
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 (vnet_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 = VGEN_DBLK_SZ_128;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz2 = VGEN_DBLK_SZ_256;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz3 = VGEN_DBLK_SZ_2048;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->max_rxpool_size = sz3;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna status = vio_init_multipools(&ldcp->vmp, VGEN_NUM_VMPOOLS,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz1, sz2, sz3,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_nrbufs1, vgen_nrbufs2, vgen_nrbufs3);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (status);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna switch (data_sz) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna case VNET_4K:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz1 = VGEN_DBLK_SZ_128;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz2 = VGEN_DBLK_SZ_256;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz3 = VGEN_DBLK_SZ_2048;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz4 = sz3 << 1; /* 4K */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->max_rxpool_size = sz4;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna status = vio_init_multipools(&ldcp->vmp, VGEN_NUM_VMPOOLS + 1,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz1, sz2, sz3, sz4,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_nrbufs1, vgen_nrbufs2, vgen_nrbufs3, vgen_nrbufs4);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna default: /* data_sz: 4K+ to 16K */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz1 = VGEN_DBLK_SZ_256;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz2 = VGEN_DBLK_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 status = vio_init_multipools(&ldcp->vmp, VGEN_NUM_VMPOOLS + 1,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz1, sz2, sz3, sz4,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_nrbufs1, vgen_nrbufs2, vgen_nrbufs3, vgen_nrbufs4);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (status);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * This function transmits normal data frames (non-priority) over the channel.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * It queues the frame into the transmit descriptor ring and sends a
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * VIO_DRING_DATA message if needed, to wake up the peer to (re)start
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * processing.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_dringsend(void *arg, mblk_t *mp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_ldc_t *ldcp = (vgen_ldc_t *)arg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_private_desc_t *tbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_private_desc_t *rtbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_public_desc_t *rtxdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_private_desc_t *ntbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_public_desc_t *txdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_entry_hdr_t *hdrp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_stats_t *statsp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna struct ether_header *ehp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t is_bcast = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t is_mcast = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t mblksz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna caddr_t dst;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *bp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_hparams_t *lp = &ldcp->local_hparams;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp = &ldcp->stats;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size = msgsize(mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "enter\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->ldc_status != LDC_UP) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "status(%d), dropping packet\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->ldc_status);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto dringsend_exit;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* drop the packet if ldc is not up or handshake is not done */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->hphase != VH_DONE) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "hphase(%x), dropping packet\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->hphase);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto dringsend_exit;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (size > (size_t)lp->mtu) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "invalid size(%d)\n", size);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto dringsend_exit;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (size < ETHERMIN)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size = ETHERMIN;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ehp = (struct ether_header *)mp->b_rptr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna is_bcast = IS_BROADCAST(ehp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna is_mcast = IS_MULTICAST(ehp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->txlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * allocate a descriptor
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp = ldcp->next_tbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ntbufp = NEXTTBUF(ldcp, tbufp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ntbufp == ldcp->cur_tbufp) { /* out of tbufs/txds */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->tclock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Try reclaiming now */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_reclaim_dring(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->reclaim_lbolt = ddi_get_lbolt();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ntbufp == ldcp->cur_tbufp) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Now we are really out of tbuf/txds */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->tx_blocked_lbolt = ddi_get_lbolt();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->tx_blocked = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->tclock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->tx_no_desc++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->txlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (VGEN_TX_NORESOURCES);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->tclock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* update next available tbuf in the ring and update tx index */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_tbufp = ntbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna INCR_TXI(ldcp->next_txi, ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Mark the buffer busy before releasing the lock */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp->flags = VGEN_PRIV_DESC_BUSY;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->txlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* copy data into pre-allocated transmit buffer */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dst = tbufp->datap + VNET_IPALIGN;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (bp = mp; bp != NULL; bp = bp->b_cont) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblksz = MBLKL(bp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bcopy(bp->b_rptr, dst, mblksz);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dst += mblksz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp->datalen = size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* initialize the corresponding public descriptor (txd) */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp = tbufp->descp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp = &txdp->hdr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp->nbytes = size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp->ncookies = tbufp->ncookies;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bcopy((tbufp->memcookie), (txdp->memcookie),
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp->ncookies * sizeof (ldc_mem_cookie_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->wrlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If the flags not set to BUSY, it implies that the clobber
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * was done while we were copying the data. In such case,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * discard the packet and return.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (tbufp->flags != VGEN_PRIV_DESC_BUSY) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->oerrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->wrlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto dringsend_exit;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp->dstate = VIO_DESC_READY;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* update stats */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->opackets++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->obytes += size;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (is_bcast)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->brdcstxmt++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna else if (is_mcast)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->multixmt++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* send dring datamsg to the peer */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->resched_peer) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rtbufp = &ldcp->tbufp[ldcp->resched_peer_txi];
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rtxdp = rtbufp->descp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rtxdp->hdr.dstate == VIO_DESC_READY) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_send_dringdata(ldcp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (uint32_t)ldcp->resched_peer_txi, -1);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* error: drop the packet */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "failed sending dringdata msg "
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "rv(%d) len(%d)\n", rv, size);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->oerrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->resched_peer = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->wrlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnadringsend_exit:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv == ECONNRESET) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (void) vgen_handle_evt_reset(ldcp, VGEN_OTHER);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna freemsg(mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "exit\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (VGEN_TX_SUCCESS);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnamblk_t *
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_poll_rcv(vgen_ldc_t *ldcp, int bytes_to_pickup)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *bp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *bpt = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *mp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t mblk_sz = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t sz = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint_t count = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->pollq_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bp = ldcp->pollq_headp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna while (bp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* get the size of this packet */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_sz = msgdsize(bp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* if adding this pkt, exceeds the size limit, we are done. */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (sz + mblk_sz > bytes_to_pickup) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* we have room for this packet */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sz += mblk_sz;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* increment the # of packets being sent up */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna count++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* track the last processed pkt */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bpt = bp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* get the next pkt */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bp = bp->b_next;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (count != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * picked up some packets; save the head of pkts to be sent up.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp = ldcp->pollq_headp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* move the pollq_headp to skip over the pkts being sent up */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->pollq_headp = bp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* picked up all pending pkts in the queue; reset tail also */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->pollq_headp == NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->pollq_tailp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* terminate the tail of pkts to be sent up */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bpt->b_next = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We prepend any high priority packets to the chain of packets; note
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * that if we are already at the bytes_to_pickup limit, we might
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * slightly exceed that in such cases. That should be ok, as these pkts
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * are expected to be small in size and arrive at an interval in the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the order of a few seconds.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->rx_pktdata == vgen_handle_pkt_data &&
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->rx_pri_head != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->rx_pri_tail->b_next = mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp = ldcp->rx_pri_head;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->rx_pri_head = ldcp->rx_pri_tail = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->pollq_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Process dring data messages (info/ack/nack)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_handle_dringdata(void *arg1, void *arg2)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_ldc_t *ldcp = (vgen_ldc_t *)arg1;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_msg_tag_t *tagp = (vio_msg_tag_t *)arg2;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "enter\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna switch (tagp->vio_subtype) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna case VIO_SUBTYPE_INFO:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * To reduce the locking contention, release the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * cblock here and re-acquire it once we are done
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * receiving packets.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->cblock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->rxlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_handle_dringdata_info(ldcp, tagp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->rxlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->cblock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna case VIO_SUBTYPE_ACK:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_handle_dringdata_ack(ldcp, tagp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna case VIO_SUBTYPE_NACK:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_handle_dringdata_nack(ldcp, tagp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "exit rv(%d)\n", rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_handle_dringdata_info(vgen_ldc_t *ldcp, vio_msg_tag_t *tagp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int32_t end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *dringmsg = (vio_dring_msg_t *)tagp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_stats_t *statsp = &ldcp->stats;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#ifdef VGEN_HANDLE_LOST_PKTS
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int n;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#endif
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "enter\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna start = dringmsg->start_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna end = dringmsg->end_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * received a data msg, which contains the start and end
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * indices of the descriptors within the rx ring holding data,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the seq_num of data packet corresponding to the start index,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * and the dring_ident.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We can now read the contents of each of these descriptors
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * and gather data from it.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "INFO: start(%d), end(%d)\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna start, end);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* validate rx start and end indexes */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (!(CHECK_RXI(start, ldcp)) || ((end != -1) &&
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna !(CHECK_RXI(end, ldcp)))) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "Invalid Rx start(%d) or end(%d)\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna start, end);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* drop the message if invalid index */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* validate dring_ident */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dringmsg->dring_ident != ldcp->peer_hparams.dring_ident) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "Invalid dring ident 0x%x\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dringmsg->dring_ident);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* invalid dring_ident, drop the msg */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#ifdef DEBUG
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (vgen_inject_error(ldcp, VGEN_ERR_RXLOST)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* drop this msg to simulate lost pkts for debugging */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_inject_err_flag &= ~(VGEN_ERR_RXLOST);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#endif
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->dring_data_msgs_rcvd++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#ifdef VGEN_HANDLE_LOST_PKTS
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* receive start index doesn't match expected index */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->next_rxi != start) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "next_rxi(%d) != start(%d)\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_rxi, start);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* calculate the number of pkts lost */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (start >= ldcp->next_rxi) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna n = start - ldcp->next_rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna n = ldcp->num_rxds - (ldcp->next_rxi - start);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->rx_lost_pkts += n;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tagp->vio_subtype = VIO_SUBTYPE_NACK;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tagp->vio_sid = ldcp->local_sid;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* indicate the range of lost descriptors */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dringmsg->start_idx = ldcp->next_rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxi = start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DECR_RXI(rxi, ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dringmsg->end_idx = rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* dring ident is left unchanged */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_sendmsg(ldcp, (caddr_t)tagp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna sizeof (*dringmsg), B_FALSE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != VGEN_SUCCESS) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "vgen_sendmsg failed, stype:NACK\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * treat this range of descrs/pkts as dropped
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * and set the new expected value of next_rxi
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * and continue(below) to process from the new
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * start index.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_rxi = start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#endif /* VGEN_HANDLE_LOST_PKTS */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Now receive messages */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_process_dringdata(ldcp, tagp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "exit rv(%d)\n", rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_process_dringdata(vgen_ldc_t *ldcp, vio_msg_tag_t *tagp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t set_ack_start = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t ack_end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t next_rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int count = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t retries = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_stats_t *statsp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_public_desc_t rxd;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_entry_hdr_t *hdrp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *bp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *bpt = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t ack_start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t rxd_err = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mblk_t *mp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_mblk_t *vmp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t nbytes;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t ack_needed = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t nread;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint64_t off = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna struct ether_header *ehp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *dringmsg = (vio_dring_msg_t *)tagp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_hparams_t *lp = &ldcp->local_hparams;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "enter\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp = &ldcp->stats;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna start = dringmsg->start_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * start processing the descriptors from the specified
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * start index, up to the index a descriptor is not ready
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * to be processed or we process the entire descriptor ring
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * and wrap around upto the start index.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* need to set the start index of descriptors to be ack'd */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna set_ack_start = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* index upto which we have ack'd */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ack_end = start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DECR_RXI(ack_end, ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna next_rxi = rxi = start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna do {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_recv_retry:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vnet_dring_entry_copy(&(ldcp->mrxdp[rxi]), &rxd,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->dring_mtype, ldcp->rx_dring_handle, rxi, rxi);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "ldc_mem_dring_acquire() failed"
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna " rv(%d)\n", rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->ierrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp = &rxd.hdr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (hdrp->dstate != VIO_DESC_READY) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Before waiting and retry here, send up
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the packets that are received already
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (bp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DTRACE_PROBE1(vgen_rcv_msgs, int, count);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_rx(ldcp, bp, bpt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna count = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bp = bpt = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * descriptor is not ready.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * retry descriptor acquire, stop processing
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * after max # retries.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (retries == vgen_recv_retries)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna retries++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna drv_usecwait(vgen_recv_delay);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto vgen_recv_retry;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna retries = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (set_ack_start) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * initialize the start index of the range
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * of descriptors to be ack'd.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ack_start = rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna set_ack_start = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((rxd.nbytes < ETHERMIN) ||
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (rxd.nbytes > lp->mtu) ||
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (rxd.ncookies == 0) ||
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (rxd.ncookies > MAX_COOKIES)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxd_err = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Try to allocate an mblk from the free pool
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * of recv mblks for the channel.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If this fails, use allocb().
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna nbytes = (VNET_IPALIGN + rxd.nbytes + 7) & ~7;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (nbytes > ldcp->max_rxpool_size) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp = allocb(VNET_IPALIGN + rxd.nbytes + 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 statsp->rx_vio_allocb_fail++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Data buffer returned by allocb(9F)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * is 8byte aligned. We allocate extra
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * 8 bytes to ensure size is multiple
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * of 8 bytes for ldc_mem_copy().
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp = allocb(VNET_IPALIGN +
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxd.nbytes + 8, BPRI_MED);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp = vmp->mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((rxd_err) || (mp == NULL)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * rxd_err or allocb() failure,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * drop this packet, get next.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rxd_err) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->ierrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxd_err = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->rx_allocb_fail++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ack_needed = hdrp->ack;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* set descriptor done bit */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vnet_dring_entry_set_dstate(&(ldcp->mrxdp[rxi]),
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->dring_mtype, ldcp->rx_dring_handle, rxi, rxi,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VIO_DESC_DONE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "vnet_dring_entry_set_dstate err rv(%d)\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ack_needed) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ack_needed = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * sender needs ack for this packet,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * ack pkts upto this index.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ack_end = rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_send_dringack(ldcp, tagp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ack_start, ack_end,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VIO_DP_ACTIVE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != VGEN_SUCCESS) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto error_ret;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* need to set new ack start index */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna set_ack_start = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto vgen_next_rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna nread = nbytes;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_mem_copy(ldcp->ldc_handle,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (caddr_t)mp->b_rptr, off, &nread,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxd.memcookie, rxd.ncookies, LDC_COPY_IN);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* if ldc_mem_copy() failed */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "ldc_mem_copy err rv(%d)\n", rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->ierrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna freemsg(mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto error_ret;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ack_needed = hdrp->ack;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vnet_dring_entry_set_dstate(&(ldcp->mrxdp[rxi]),
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->dring_mtype, ldcp->rx_dring_handle, rxi, rxi,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VIO_DESC_DONE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "vnet_dring_entry_set_dstate err rv(%d)\n", rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna freemsg(mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto error_ret;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->b_rptr += VNET_IPALIGN;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ack_needed) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ack_needed = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * sender needs ack for this packet,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * ack pkts upto this index.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ack_end = rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_send_dringack(ldcp, tagp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ack_start, ack_end, VIO_DP_ACTIVE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != VGEN_SUCCESS) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna freemsg(mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto error_ret;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* need to set new ack start index */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna set_ack_start = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (nread != nbytes) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "ldc_mem_copy nread(%lx), nbytes(%lx)\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna nread, nbytes);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->ierrors++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna freemsg(mp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto vgen_next_rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* point to the actual end of data */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->b_wptr = mp->b_rptr + rxd.nbytes;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (vmp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmp->state = VIO_MBLK_HAS_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* update stats */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->ipackets++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->rbytes += rxd.nbytes;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ehp = (struct ether_header *)mp->b_rptr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (IS_BROADCAST(ehp))
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->brdcstrcv++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna else if (IS_MULTICAST(ehp))
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->multircv++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* build a chain of received packets */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (bp == NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* first pkt */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bp = mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bpt = bp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bpt->b_next = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mp->b_next = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bpt->b_next = mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bpt = mp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (count++ > vgen_chain_len) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DTRACE_PROBE1(vgen_rcv_msgs, int, count);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_rx(ldcp, bp, bpt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna count = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bp = bpt = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_next_rxi:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* update end index of range of descrs to be ack'd */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ack_end = rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* update the next index to be processed */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna INCR_RXI(next_rxi, ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (next_rxi == start) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * processed the entire descriptor ring upto
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the index at which we started.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rxi = next_rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna _NOTE(CONSTCOND)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } while (1);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * send an ack message to peer indicating that we have stopped
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * processing descriptors.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (set_ack_start) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * We have ack'd upto some index and we have not
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * processed any descriptors beyond that index.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Use the last ack'd index as both the start and
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * end of range of descrs being ack'd.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Note: This results in acking the last index twice
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * and should be harmless.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ack_start = ack_end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_send_dringack(ldcp, tagp, ack_start, ack_end,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna VIO_DP_STOPPED);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != VGEN_SUCCESS) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna goto error_ret;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* save new recv index of next dring msg */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_rxi = next_rxi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaerror_ret:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* send up packets received so far */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (bp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DTRACE_PROBE1(vgen_rcv_msgs, int, count);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_rx(ldcp, bp, bpt);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bp = bpt = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "exit rv(%d)\n", rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_handle_dringdata_ack(vgen_ldc_t *ldcp, vio_msg_tag_t *tagp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int32_t end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t txi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t ready_txd = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_stats_t *statsp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_private_desc_t *tbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_public_desc_t *txdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_entry_hdr_t *hdrp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *dringmsg = (vio_dring_msg_t *)tagp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "enter\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna start = dringmsg->start_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna end = dringmsg->end_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp = &ldcp->stats;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * received an ack corresponding to a specific descriptor for
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * which we had set the ACK bit in the descriptor (during
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * transmit). This enables us to reclaim descriptors.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG2(vgenp, ldcp, "ACK: start(%d), end(%d)\n", start, end);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* validate start and end indexes in the tx ack msg */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (!(CHECK_TXI(start, ldcp)) || !(CHECK_TXI(end, ldcp))) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* drop the message if invalid index */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "Invalid Tx ack start(%d) or end(%d)\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna start, end);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* validate dring_ident */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dringmsg->dring_ident != ldcp->local_hparams.dring_ident) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* invalid dring_ident, drop the msg */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "Invalid dring ident 0x%x\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dringmsg->dring_ident);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->dring_data_acks_rcvd++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* reclaim descriptors that are done */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_reclaim(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dringmsg->dring_process_state != VIO_DP_STOPPED) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * receiver continued processing descriptors after
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * sending us the ack.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->dring_stopped_acks_rcvd++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* receiver stopped processing descriptors */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->wrlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->tclock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * determine if there are any pending tx descriptors
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * ready to be processed by the receiver(peer) and if so,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * send a message to the peer to restart receiving.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ready_txd = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * using the end index of the descriptor range for which
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * we received the ack, check if the next descriptor is
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * ready.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txi = end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna INCR_TXI(txi, ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp = &ldcp->tbufp[txi];
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp = tbufp->descp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp = &txdp->hdr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (hdrp->dstate == VIO_DESC_READY) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ready_txd = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * descr next to the end of ack'd descr range is not
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * ready.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * starting from the current reclaim index, check
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * if any descriptor is ready.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txi = ldcp->cur_tbufp - ldcp->tbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp = &ldcp->tbufp[txi];
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp = tbufp->descp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp = &txdp->hdr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (hdrp->dstate == VIO_DESC_READY) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ready_txd = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ready_txd) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * we have tx descriptor(s) ready to be
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * processed by the receiver.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * send a message to the peer with the start index
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * of ready descriptors.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_send_dringdata(ldcp, txi, -1);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != VGEN_SUCCESS) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->resched_peer = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->resched_peer_txi = txi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->tclock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->wrlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * no ready tx descriptors. set the flag to send a
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * message to peer when tx descriptors are ready in
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * transmit routine.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->resched_peer = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->resched_peer_txi = ldcp->cur_tbufp - ldcp->tbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->tclock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->wrlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "exit rv(%d)\n", rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_handle_dringdata_nack(vgen_ldc_t *ldcp, vio_msg_tag_t *tagp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int32_t end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t txi;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_public_desc_t *txdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_entry_hdr_t *hdrp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *dringmsg = (vio_dring_msg_t *)tagp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "enter\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna start = dringmsg->start_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna end = dringmsg->end_idx;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * peer sent a NACK msg to indicate lost packets.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * The start and end correspond to the range of descriptors
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * for which the peer didn't receive a dring data msg and so
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * didn't receive the corresponding data.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "NACK: start(%d), end(%d)\n", start, end);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* validate start and end indexes in the tx nack msg */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (!(CHECK_TXI(start, ldcp)) || !(CHECK_TXI(end, ldcp))) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* drop the message if invalid index */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "Invalid Tx nack start(%d) or end(%d)\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna start, end);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* validate dring_ident */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (dringmsg->dring_ident != ldcp->local_hparams.dring_ident) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* invalid dring_ident, drop the msg */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "Invalid dring ident 0x%x\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dringmsg->dring_ident);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->txlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->tclock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->next_tbufp == ldcp->cur_tbufp) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* no busy descriptors, bogus nack ? */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->tclock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->txlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* we just mark the descrs as done so they can be reclaimed */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (txi = start; txi <= end; ) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp = &(ldcp->txdp[txi]);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp = &txdp->hdr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (hdrp->dstate == VIO_DESC_READY)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp->dstate = VIO_DESC_DONE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna INCR_TXI(txi, ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->tclock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->txlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "exit rv(%d)\n", rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Send received packets up the stack.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic void
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_rx(vgen_ldc_t *ldcp, mblk_t *bp, mblk_t *bpt)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_net_rx_cb_t vrx_cb = ldcp->portp->vcb.vio_net_rx_cb;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->msg_thread != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ASSERT(MUTEX_HELD(&ldcp->rxlock));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ASSERT(MUTEX_HELD(&ldcp->cblock));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->pollq_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->polling_on == B_TRUE) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * If we are in polling mode, simply queue
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the packets onto the poll queue and return.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->pollq_headp == NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->pollq_headp = bp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->pollq_tailp = bpt;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->pollq_tailp->b_next = bp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->pollq_tailp = bpt;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->pollq_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Prepend any pending mblks in the poll queue, now that we
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * are in interrupt mode, before sending up the chain of pkts.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->pollq_headp != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG2(vgenp, ldcp, "vgen_rx(%lx), pending pollq_headp\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (uintptr_t)ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->pollq_tailp->b_next = bp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bp = ldcp->pollq_headp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->pollq_headp = ldcp->pollq_tailp = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->pollq_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->msg_thread != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->rxlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->cblock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* Send up the packets */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vrx_cb(ldcp->portp->vhp, bp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (ldcp->msg_thread != NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->rxlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->cblock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic void
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_reclaim(vgen_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->tclock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_reclaim_dring(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->reclaim_lbolt = ddi_get_lbolt();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->tclock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * transmit reclaim function. starting from the current reclaim index
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * look for descriptors marked DONE and reclaim the descriptor.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic void
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_reclaim_dring(vgen_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int count = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vnet_public_desc_t *txdp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_private_desc_t *tbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_entry_hdr_t *hdrp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp = ldcp->cur_tbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp = tbufp->descp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp = &txdp->hdr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna while ((hdrp->dstate == VIO_DESC_DONE) &&
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna (tbufp != ldcp->next_tbufp)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp->flags = VGEN_PRIV_DESC_FREE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp->dstate = VIO_DESC_FREE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp->ack = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tbufp = NEXTTBUF(ldcp, tbufp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna txdp = tbufp->descp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna hdrp = &txdp->hdr;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna count++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->cur_tbufp = tbufp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Check if mac layer should be notified to restart transmissions
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((ldcp->tx_blocked) && (count > 0)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_net_tx_update_t vtx_update =
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->portp->vcb.vio_net_tx_update;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->tx_blocked = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vtx_update(ldcp->portp->vhp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Send descriptor ring data message to the peer over ldc.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_send_dringdata(vgen_ldc_t *ldcp, uint32_t start, int32_t end)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t dringmsg, *msgp = &dringmsg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_msg_tag_t *tagp = &msgp->tag;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_stats_t *statsp = &ldcp->stats;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#ifdef DEBUG
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (vgen_inject_error(ldcp, VGEN_ERR_TXTIMEOUT)) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (VGEN_SUCCESS);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna#endif
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna bzero(msgp, sizeof (*msgp));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tagp->vio_msgtype = VIO_TYPE_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tagp->vio_subtype = VIO_SUBTYPE_INFO;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tagp->vio_subtype_env = VIO_DRING_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tagp->vio_sid = ldcp->local_sid;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->dring_ident = ldcp->local_hparams.dring_ident;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->start_idx = start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->end_idx = end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_sendmsg(ldcp, (caddr_t)tagp, sizeof (dringmsg), B_TRUE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != VGEN_SUCCESS) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "vgen_sendmsg failed\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->dring_data_msgs_sent++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG2(vgenp, ldcp, "DRING_DATA_SENT \n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (VGEN_SUCCESS);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Send dring data ack message.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnastatic int
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_send_dringack(vgen_ldc_t *ldcp, vio_msg_tag_t *tagp, uint32_t start,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int32_t end, uint8_t pstate)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *msgp = (vio_dring_msg_t *)tagp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_stats_t *statsp = &ldcp->stats;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tagp->vio_msgtype = VIO_TYPE_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tagp->vio_subtype = VIO_SUBTYPE_ACK;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tagp->vio_subtype_env = VIO_DRING_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna tagp->vio_sid = ldcp->local_sid;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->start_idx = start;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->end_idx = end;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna msgp->dring_process_state = pstate;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_sendmsg(ldcp, (caddr_t)tagp, sizeof (*msgp), B_FALSE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != VGEN_SUCCESS) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "vgen_sendmsg() failed\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->dring_data_acks_sent++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (pstate == VIO_DP_STOPPED) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna statsp->dring_stopped_acks_sent++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Wrapper routine to send the given message over ldc using ldc_write().
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_sendmsg(vgen_ldc_t *ldcp, caddr_t msg, size_t msglen,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t caller_holds_lock)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna size_t len;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint32_t retries = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_msg_tag_t *tagp = (vio_msg_tag_t *)msg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *dmsg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_raw_data_msg_t *rmsg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna boolean_t data_msg = B_FALSE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna len = msglen;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((len == 0) || (msg == NULL))
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (VGEN_FAILURE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (!caller_holds_lock) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->wrlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (tagp->vio_subtype == VIO_SUBTYPE_INFO) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (tagp->vio_subtype_env == VIO_DRING_DATA) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dmsg = (vio_dring_msg_t *)tagp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dmsg->seq_num = ldcp->next_txseq;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_msg = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else if (tagp->vio_subtype_env == VIO_PKT_DATA) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rmsg = (vio_raw_data_msg_t *)tagp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rmsg->seq_num = ldcp->next_txseq;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna data_msg = B_TRUE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna do {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna len = msglen;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = ldc_write(ldcp->ldc_handle, (caddr_t)msg, &len);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (retries++ >= vgen_ldcwr_retries)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } while (rv == EWOULDBLOCK);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv == 0 && data_msg == B_TRUE) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_txseq++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (!caller_holds_lock) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->wrlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "ldc_write failed: rv(%d)\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv, msglen);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (rv);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (len != msglen) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp, "ldc_write failed: rv(%d) msglen (%d)\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv, msglen);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (VGEN_FAILURE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (VGEN_SUCCESS);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnaint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_check_datamsg_seq(vgen_ldc_t *ldcp, vio_msg_tag_t *tagp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_raw_data_msg_t *rmsg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_dring_msg_t *dmsg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint64_t seq_num;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (tagp->vio_subtype_env == VIO_DRING_DATA) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna dmsg = (vio_dring_msg_t *)tagp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna seq_num = dmsg->seq_num;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else if (tagp->vio_subtype_env == VIO_PKT_DATA) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rmsg = (vio_raw_data_msg_t *)tagp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna seq_num = rmsg->seq_num;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (EINVAL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (seq_num != ldcp->next_rxseq) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* seqnums don't match */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DWARN(vgenp, ldcp,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "next_rxseq(0x%lx) != seq_num(0x%lx)\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_rxseq, seq_num);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (EINVAL);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->next_rxseq++;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (0);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * vgen_ldc_msg_worker -- A per LDC worker thread. This thread is woken up by
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * the LDC interrupt handler to process LDC packets and receive data.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_ldc_msg_worker(void *arg)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna callb_cpr_t cprinfo;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_ldc_t *ldcp = (vgen_ldc_t *)arg;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna int rv;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "enter\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna CALLB_CPR_INIT(&cprinfo, &ldcp->msg_thr_lock, callb_generic_cpr,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna "vnet_rcv_thread");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->msg_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna while (!(ldcp->msg_thr_flags & VGEN_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 (VGEN_WTHR_DATARCVD | VGEN_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 & VGEN_WTHR_STOP) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG2(vgenp, ldcp, "stopped\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->msg_thr_flags &= ~VGEN_WTHR_DATARCVD;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->msg_thr_flags |= VGEN_WTHR_PROCESSING;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&ldcp->msg_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG2(vgenp, ldcp, "calling vgen_handle_evt_read\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna rv = vgen_handle_evt_read(ldcp, VGEN_MSG_THR);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&ldcp->msg_thr_lock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->msg_thr_flags &= ~VGEN_WTHR_PROCESSING;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (rv != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Channel has been reset. The thread should now exit.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * The thread may be recreated if TxDring is negotiated
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * on this channel after the channel comes back up
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * again.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->msg_thr_flags |= VGEN_WTHR_STOP;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna break;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
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 &= ~VGEN_WTHR_STOP;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ldcp->msg_thread = NULL;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna CALLB_CPR_EXIT(&cprinfo);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna thread_exit();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "exit\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/* vgen_stop_msg_thread -- Co-ordinate with receive thread to stop it */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavgen_stop_msg_thread(vgen_ldc_t *ldcp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kt_did_t tid = 0;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vgen_t *vgenp = LDC_TO_VGEN(ldcp);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna DBG1(vgenp, ldcp, "enter\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Send a stop request by setting the stop flag and
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * wait until the receive 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 |= VGEN_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 DBG1(vgenp, ldcp, "exit\n");
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}