b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * CDDL HEADER START
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * The contents of this file are subject to the terms of the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Common Development and Distribution License (the "License").
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * You may not use this file except in compliance with the License.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * or http://www.opensolaris.org/os/licensing.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * See the License for the specific language governing permissions
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * and limitations under the License.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * When distributing Covered Code, include this CDDL HEADER in each
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If applicable, add the following below this CDDL HEADER, with the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * fields enclosed by brackets "[]" replaced with your own identifying
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * information: Portions Copyright [yyyy] [name of copyright owner]
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * CDDL HEADER END
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Allocate a eib_chan_t to store stuff about admin qp and
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * initialize some basic stuff
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan chan = kmem_zalloc(sizeof (eib_chan_t), KM_SLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_init(&chan->ch_pkey_lock, NULL, MUTEX_DRIVER, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_init(&chan->ch_cep_lock, NULL, MUTEX_DRIVER, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_init(&chan->ch_tx_lock, NULL, MUTEX_DRIVER, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_init(&chan->ch_rx_lock, NULL, MUTEX_DRIVER, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_init(&chan->ch_vhub_lock, NULL, MUTEX_DRIVER, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_init(&chan->ch_cep_cv, NULL, CV_DEFAULT, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_init(&chan->ch_tx_cv, NULL, CV_DEFAULT, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_init(&chan->ch_rx_cv, NULL, CV_DEFAULT, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_chan_post_rx(eib_t *ss, eib_chan_t *chan, uint_t *n_posted)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We don't want to post beyond the maximum rwqe size for this channel
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan room = chan->ch_max_rwqes - chan->ch_rx_posted;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan limit = (room > chan->ch_rwqe_bktsz) ? chan->ch_rwqe_bktsz : room;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (wndx = 0; wndx < limit; wndx += chunk_sz) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Grab a chunk of rwqes
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan chunk_sz = ((limit - wndx) < EIB_RWR_CHUNK_SZ) ?
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * When eib_chan_post_rx() is called to post a bunch of rwqes,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * it is either during the vnic setup or when we're refilling
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the data channel. Neither situation is important enough for
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * us to grab the wqes reserved for sending keepalives of
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * previously established vnics.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = eib_rsrc_grab_rwqes(ss, rwqes, chunk_sz, &n_got,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Post work requests from the rwqes we just grabbed
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (i = 0; i < n_got; i++) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If we got less rwqes than we asked for during the grab
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * earlier, we'll stop asking for more and quit now.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If we posted absolutely nothing, we return failure; otherwise
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * return success.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneib_chan_post_recv(eib_t *ss, eib_chan_t *chan, eib_wqe_t *rwqe)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan rwqe->qe_sgl.ds_va = (ib_vaddr_t)(uintptr_t)rwqe->qe_cpbuf;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If this channel has receive buffer alignment restrictions, make
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * sure the requirements are met
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan rwqe->qe_sgl.ds_va += chan->ch_ip_hdr_align;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan rwqe->qe_sgl.ds_len -= chan->ch_ip_hdr_align;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If the receive buffer for this channel needs to have an mblk
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * allocated, do it
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mp_base = (uint8_t *)(uintptr_t)(rwqe->qe_sgl.ds_va);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan rwqe->qe_mp = desballoc(mp_base, mp_len, 0, &rwqe->qe_frp);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_ERR(ss->ei_instance, "eib_chan_post_recv: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "desballoc(base=0x%llx, len=0x%llx) failed",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Check if the recv queue is already full or if we can post one more
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (chan->ch_rx_posted > (chan->ch_max_rwqes - 1)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_ERR(ss->ei_instance, "eib_chan_post_recv: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "too many rwqes posted already, posted=0x%lx, max=0x%lx",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan rwqe->qe_info |= EIB_WQE_FLG_POSTED_TO_HCA;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_post_recv(chan->ch_chan, &(rwqe->qe_wr.recv), 1, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_DPRINTF_ERR(ss->ei_instance, "eib_chan_post_recv: "