4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * CDDL HEADER START
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * The contents of this file are subject to the terms of the
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * Common Development and Distribution License (the "License").
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * You may not use this file except in compliance with the License.
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * or http://www.opensolaris.org/os/licensing.
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * See the License for the specific language governing permissions
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * and limitations under the License.
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * When distributing Covered Code, include this CDDL HEADER in each
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * If applicable, add the following below this CDDL HEADER, with the
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * fields enclosed by brackets "[]" replaced with your own identifying
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * information: Portions Copyright [yyyy] [name of copyright owner]
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * CDDL HEADER END
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore/* Copyright © 2003-2011 Emulex. All rights reserved. */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer * Source file containing the Receive Path handling
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * functions
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan#include <oce_impl.h>
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanvoid oce_rx_pool_free(char *arg);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanstatic void oce_rqb_dtor(oce_rq_bdesc_t *rqbd);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanstatic int oce_rqb_ctor(oce_rq_bdesc_t *rqbd, struct oce_rq *rq,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan size_t size, int flags);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanstatic inline mblk_t *oce_rx(struct oce_dev *dev, struct oce_rq *rq,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_nic_rx_cqe *cqe);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic inline mblk_t *oce_rx_bcopy(struct oce_dev *dev,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_rq *rq, struct oce_nic_rx_cqe *cqe);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanstatic int oce_rq_charge(struct oce_rq *rq, uint32_t nbufs, boolean_t repost);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic void oce_rx_insert_tag(mblk_t *mp, uint16_t vtag);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic void oce_set_rx_oflags(mblk_t *mp, struct oce_nic_rx_cqe *cqe);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic inline void oce_rx_drop_pkt(struct oce_rq *rq,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_nic_rx_cqe *cqe);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanstatic oce_rq_bdesc_t *oce_rqb_alloc(struct oce_rq *rq);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanstatic void oce_rqb_free(struct oce_rq *rq, oce_rq_bdesc_t *rqbd);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanstatic void oce_rq_post_buffer(struct oce_rq *rq, int nbufs);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan#pragma inline(oce_rx)
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan#pragma inline(oce_rx_bcopy)
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan#pragma inline(oce_rq_charge)
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan#pragma inline(oce_rx_insert_tag)
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan#pragma inline(oce_set_rx_oflags)
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan#pragma inline(oce_rx_drop_pkt)
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan#pragma inline(oce_rqb_alloc)
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan#pragma inline(oce_rqb_free)
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan#pragma inline(oce_rq_post_buffer)
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanstatic ddi_dma_attr_t oce_rx_buf_attr = {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan DMA_ATTR_V0, /* version number */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan 0x0000000000000000ull, /* low address */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan 0xFFFFFFFFFFFFFFFFull, /* high address */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan 0x00000000FFFFFFFFull, /* dma counter max */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan OCE_DMA_ALIGNMENT, /* alignment */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan 0x000007FF, /* burst sizes */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan 0x00000001, /* minimum transfer size */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan 0x00000000FFFFFFFFull, /* maximum transfer size */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan 0xFFFFFFFFFFFFFFFFull, /* maximum segment size */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan 1, /* scatter/gather list length */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan 0x00000001, /* granularity */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan DDI_DMA_FLAGERR|DDI_DMA_RELAXED_ORDERING /* DMA flags */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan};
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to create a DMA buffer pool for RQ
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * num_items - number of buffers in the pool
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * item_size - size of each buffer
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return DDI_SUCCESS => success, DDI_FAILURE otherwise
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanint
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_rqb_cache_create(struct oce_rq *rq, size_t buf_size)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int size;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int cnt;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int ret;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_rq_bdesc_t *rqbd;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan _NOTE(ARGUNUSED(buf_size));
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd = rq->rq_bdesc_array;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan size = rq->cfg.frag_size + OCE_RQE_BUF_HEADROOM;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (cnt = 0; cnt < rq->cfg.nbufs; cnt++, rqbd++) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->rqb_freelist[cnt] = rqbd;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan ret = oce_rqb_ctor(rqbd, rq,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan size, (DDI_DMA_RDWR|DDI_DMA_STREAMING));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (ret != DDI_SUCCESS) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan goto rqb_fail;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->rqb_free = rq->cfg.nbufs;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->rqb_rc_head = 0;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->rqb_next_free = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (DDI_SUCCESS);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanrqb_fail:
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_rqb_cache_destroy(rq);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (DDI_FAILURE);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_rqb_cache_create */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to Destroy RQ DMA buffer cache
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rq - pointer to rq structure
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return none
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanvoid
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_rqb_cache_destroy(struct oce_rq *rq)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_rq_bdesc_t *rqbd = NULL;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan int cnt;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd = rq->rq_bdesc_array;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (cnt = 0; cnt < rq->cfg.nbufs; cnt++, rqbd++) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_rqb_dtor(rqbd);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_rqb_cache_destroy */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * RQ buffer destructor function
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rqbd - pointer to rq buffer descriptor
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return none
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanstatic void
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_rqb_dtor(oce_rq_bdesc_t *rqbd)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if ((rqbd == NULL) || (rqbd->rq == NULL)) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (rqbd->mp != NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rqbd->fr_rtn.free_arg = NULL;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan freemsg(rqbd->mp);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd->mp = NULL;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_free_dma_buffer(rqbd->rq->parent, rqbd->rqb);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_rqb_dtor */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * RQ buffer constructor function
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rqbd - pointer to rq buffer descriptor
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rq - pointer to RQ structure
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * size - size of the buffer
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * flags - KM_SLEEP OR KM_NOSLEEP
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return DDI_SUCCESS => success, DDI_FAILURE otherwise
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanstatic int
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_rqb_ctor(oce_rq_bdesc_t *rqbd, struct oce_rq *rq, size_t size, int flags)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_dev *dev;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_dma_buf_t *dbuf;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan dev = rq->parent;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dbuf = oce_alloc_dma_buffer(dev, size, &oce_rx_buf_attr, flags);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (dbuf == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (DDI_FAILURE);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* Set the call back function parameters */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd->fr_rtn.free_func = (void (*)())oce_rx_pool_free;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd->fr_rtn.free_arg = (caddr_t)(void *)rqbd;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd->mp = desballoc((uchar_t *)(dbuf->base),
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dbuf->size, 0, &rqbd->fr_rtn);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (rqbd->mp == NULL) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_free_dma_buffer(dev, dbuf);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan return (DDI_FAILURE);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rqbd->rqb = dbuf;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rqbd->rq = rq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rqbd->frag_addr.dw.addr_lo = ADDR_LO(dbuf->addr + OCE_RQE_BUF_HEADROOM);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rqbd->frag_addr.dw.addr_hi = ADDR_HI(dbuf->addr + OCE_RQE_BUF_HEADROOM);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rqbd->mp->b_rptr = (uchar_t *)rqbd->rqb->base + OCE_RQE_BUF_HEADROOM;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (DDI_SUCCESS);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_rqb_ctor */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * RQ buffer allocator function
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rq - pointer to RQ structure
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return pointer to RQ buffer descriptor
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanstatic inline oce_rq_bdesc_t *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_rqb_alloc(struct oce_rq *rq)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_rq_bdesc_t *rqbd;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan uint32_t free_index;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan free_index = rq->rqb_next_free;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd = rq->rqb_freelist[free_index];
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->rqb_freelist[free_index] = NULL;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->rqb_next_free = GET_Q_NEXT(free_index, 1, rq->cfg.nbufs);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (rqbd);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_rqb_alloc */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to free the RQ buffer
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rq - pointer to RQ structure
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rqbd - pointer to recieve buffer descriptor
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return none
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanstatic inline void
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_rqb_free(struct oce_rq *rq, oce_rq_bdesc_t *rqbd)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan uint32_t free_index;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mutex_enter(&rq->rc_lock);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan free_index = rq->rqb_rc_head;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->rqb_freelist[free_index] = rqbd;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->rqb_rc_head = GET_Q_NEXT(free_index, 1, rq->cfg.nbufs);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mutex_exit(&rq->rc_lock);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_32(&rq->rqb_free);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_rqb_free */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanstatic void oce_rq_post_buffer(struct oce_rq *rq, int nbufs)
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan{
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan pd_rxulp_db_t rxdb_reg;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan int count;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan struct oce_dev *dev = rq->parent;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rxdb_reg.dw0 = 0;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rxdb_reg.bits.qid = rq->rq_id & DB_RQ_ID_MASK;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (count = nbufs/OCE_MAX_RQ_POSTS; count > 0; count--) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rxdb_reg.bits.num_posted = OCE_MAX_RQ_POSTS;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan OCE_DB_WRITE32(dev, PD_RXULP_DB, rxdb_reg.dw0);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->buf_avail += OCE_MAX_RQ_POSTS;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan nbufs -= OCE_MAX_RQ_POSTS;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (nbufs > 0) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rxdb_reg.bits.num_posted = nbufs;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan OCE_DB_WRITE32(dev, PD_RXULP_DB, rxdb_reg.dw0);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->buf_avail += nbufs;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan}
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to charge a given rq with buffers from a pool's free list
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rq - pointer to the RQ to charge
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * nbufs - numbers of buffers to be charged
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return number of rqe's charges.
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanstatic inline int
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanoce_rq_charge(struct oce_rq *rq, uint32_t nbufs, boolean_t repost)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_nic_rqe *rqe;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_rq_bdesc_t *rqbd;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_rq_bdesc_t **shadow_rq;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan int cnt;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan int cur_index;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_ring_buffer_t *ring;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan shadow_rq = rq->shadow_ring;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan ring = rq->ring;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan cur_index = ring->cidx;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (cnt = 0; cnt < nbufs; cnt++) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (!repost) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd = oce_rqb_alloc(rq);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan } else {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* just repost the buffers from shadow ring */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd = shadow_rq[cur_index];
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan cur_index = GET_Q_NEXT(cur_index, 1, ring->num_items);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* fill the rqes */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rqe = RING_GET_PRODUCER_ITEM_VA(rq->ring,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_nic_rqe);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rqe->u0.s.frag_pa_lo = rqbd->frag_addr.dw.addr_lo;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rqe->u0.s.frag_pa_hi = rqbd->frag_addr.dw.addr_hi;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan shadow_rq[rq->ring->pidx] = rqbd;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan DW_SWAP(u32ptr(rqe), sizeof (struct oce_nic_rqe));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan RING_PUT(rq->ring, 1);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan return (cnt);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_rq_charge */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to release the posted buffers
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rq - pointer to the RQ to charge
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return none
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanvoid
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_rq_discharge(struct oce_rq *rq)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_rq_bdesc_t *rqbd;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_rq_bdesc_t **shadow_rq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan shadow_rq = rq->shadow_ring;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* Free the posted buffer since RQ is destroyed already */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan while ((int32_t)rq->buf_avail > 0) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd = shadow_rq[rq->ring->cidx];
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_rqb_free(rq, rqbd);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan RING_GET(rq->ring, 1);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq->buf_avail--;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan}
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to process a single packet
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rq - pointer to the RQ to charge
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * cqe - Pointer to Completion Q entry
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return mblk pointer => success, NULL => error
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanstatic inline mblk_t *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_rx(struct oce_dev *dev, struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mblk_t *mp;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int pkt_len;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int32_t frag_cnt = 0;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mblk_t **mblk_tail;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mblk_t *mblk_head;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int frag_size;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_rq_bdesc_t *rqbd;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan uint16_t cur_index;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_ring_buffer_t *ring;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan int i;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan frag_cnt = cqe->u0.s.num_fragments & 0x7;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mblk_head = NULL;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mblk_tail = &mblk_head;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan ring = rq->ring;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan cur_index = ring->cidx;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* Get the relevant Queue pointers */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan pkt_len = cqe->u0.s.pkt_size;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (i = 0; i < frag_cnt; i++) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd = rq->shadow_ring[cur_index];
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (rqbd->mp == NULL) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd->mp = desballoc((uchar_t *)rqbd->rqb->base,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd->rqb->size, 0, &rqbd->fr_rtn);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (rqbd->mp == NULL) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan return (NULL);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd->mp->b_rptr =
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (uchar_t *)rqbd->rqb->base + OCE_RQE_BUF_HEADROOM;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mp = rqbd->mp;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan frag_size = (pkt_len > rq->cfg.frag_size) ?
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq->cfg.frag_size : pkt_len;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mp->b_wptr = mp->b_rptr + frag_size;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan pkt_len -= frag_size;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mp->b_next = mp->b_cont = NULL;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* Chain the message mblks */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan *mblk_tail = mp;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mblk_tail = &mp->b_cont;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (void) DBUF_SYNC(rqbd->rqb, DDI_DMA_SYNC_FORCPU);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan cur_index = GET_Q_NEXT(cur_index, 1, ring->num_items);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (mblk_head == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_RX, "%s", "oce_rx:no frags?");
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* replace the buffer with new ones */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (void) oce_rq_charge(rq, frag_cnt, B_FALSE);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan atomic_add_32(&rq->pending, frag_cnt);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (mblk_head);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan} /* oce_rx */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic inline mblk_t *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_rx_bcopy(struct oce_dev *dev, struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mblk_t *mp;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan int pkt_len;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan int alloc_len;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan int32_t frag_cnt = 0;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan int frag_size;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_rq_bdesc_t *rqbd;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan unsigned char *rptr;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan uint32_t cur_index;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_ring_buffer_t *ring;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_rq_bdesc_t **shadow_rq;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan int cnt = 0;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan _NOTE(ARGUNUSED(dev));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan shadow_rq = rq->shadow_ring;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan pkt_len = cqe->u0.s.pkt_size;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan alloc_len = pkt_len + OCE_RQE_BUF_HEADROOM;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan frag_cnt = cqe->u0.s.num_fragments & 0x7;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mp = allocb(alloc_len, BPRI_HI);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (mp == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mp->b_rptr += OCE_RQE_BUF_HEADROOM;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rptr = mp->b_rptr;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mp->b_wptr = mp->b_rptr + pkt_len;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan ring = rq->ring;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan cur_index = ring->cidx;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (cnt = 0; cnt < frag_cnt; cnt++) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd = shadow_rq[cur_index];
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan frag_size = (pkt_len > rq->cfg.frag_size) ?
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rq->cfg.frag_size : pkt_len;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (void) DBUF_SYNC(rqbd->rqb, DDI_DMA_SYNC_FORCPU);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan bcopy(rqbd->rqb->base + OCE_RQE_BUF_HEADROOM, rptr, frag_size);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rptr += frag_size;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan pkt_len -= frag_size;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan cur_index = GET_Q_NEXT(cur_index, 1, ring->num_items);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (void) oce_rq_charge(rq, frag_cnt, B_TRUE);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (mp);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan}
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic inline void
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_set_rx_oflags(mblk_t *mp, struct oce_nic_rx_cqe *cqe)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan int csum_flags = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* set flags */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (cqe->u0.s.ip_cksum_pass) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer csum_flags |= HCK_IPV4_HDRCKSUM_OK;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (cqe->u0.s.l4_cksum_pass) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan csum_flags |= (HCK_FULLCKSUM | HCK_FULLCKSUM_OK);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (csum_flags) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer (void) mac_hcksum_set(mp, 0, 0, 0, 0, csum_flags);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan}
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic inline void
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_rx_insert_tag(mblk_t *mp, uint16_t vtag)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct ether_vlan_header *ehp;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore (void) memmove(mp->b_rptr - VTAG_SIZE,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mp->b_rptr, 2 * ETHERADDRL);
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore mp->b_rptr -= VTAG_SIZE;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan ehp = (struct ether_vlan_header *)voidptr(mp->b_rptr);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan ehp->ether_tpid = htons(ETHERTYPE_VLAN);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan ehp->ether_tci = LE_16(vtag);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan}
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanstatic inline void
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanoce_rx_drop_pkt(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan{
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan int frag_cnt;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_rq_bdesc_t *rqbd;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_rq_bdesc_t **shadow_rq;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan shadow_rq = rq->shadow_ring;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (frag_cnt = 0; frag_cnt < cqe->u0.s.num_fragments; frag_cnt++) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd = shadow_rq[rq->ring->cidx];
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_rqb_free(rq, rqbd);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan RING_GET(rq->ring, 1);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan}
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to process a Recieve queue
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * arg - pointer to the RQ to charge
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return number of cqes processed
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanuint16_t
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_drain_rq_cq(void *arg)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_nic_rx_cqe *cqe;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_rq *rq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mblk_t *mp = NULL;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mblk_t *mblk_head;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mblk_t **mblk_tail;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan uint16_t num_cqe = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_cq *cq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_dev *dev;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan int32_t frag_cnt;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan uint32_t nbufs = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq = (struct oce_rq *)arg;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan dev = rq->parent;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq = rq->cq;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mblk_head = NULL;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mblk_tail = &mblk_head;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (void) DBUF_SYNC(cq->ring->dbuf, DDI_DMA_SYNC_FORKERNEL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* dequeue till you reach an invalid cqe */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan while (RQ_CQE_VALID(cqe)) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan DW_SWAP(u32ptr(cqe), sizeof (struct oce_nic_rx_cqe));
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan frag_cnt = cqe->u0.s.num_fragments & 0x7;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* if insufficient buffers to charge then do copy */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if ((cqe->u0.s.pkt_size < dev->rx_bcopy_limit) ||
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (oce_atomic_reserve(&rq->rqb_free, frag_cnt) < 0)) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mp = oce_rx_bcopy(dev, rq, cqe);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan } else {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mp = oce_rx(dev, rq, cqe);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (mp == NULL) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan atomic_add_32(&rq->rqb_free, frag_cnt);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mp = oce_rx_bcopy(dev, rq, cqe);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (mp != NULL) {
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore if (dev->function_mode & FLEX10_MODE) {
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore if (cqe->u0.s.vlan_tag_present &&
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore cqe->u0.s.qnq) {
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore oce_rx_insert_tag(mp,
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore cqe->u0.s.vlan_tag);
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore }
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore } else if (cqe->u0.s.vlan_tag_present) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_rx_insert_tag(mp, cqe->u0.s.vlan_tag);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_set_rx_oflags(mp, cqe);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan *mblk_tail = mp;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan mblk_tail = &mp->b_next;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan } else {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (void) oce_rq_charge(rq, frag_cnt, B_TRUE);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan RING_GET(rq->ring, frag_cnt);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->buf_avail -= frag_cnt;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan nbufs += frag_cnt;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_rq_post_buffer(rq, frag_cnt);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan RQ_CQE_INVALIDATE(cqe);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan RING_GET(cq->ring, 1);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_nic_rx_cqe);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan num_cqe++;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* process max ring size */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (num_cqe > dev->rx_pkt_per_intr) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan break;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan } /* for all valid CQEs */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (mblk_head) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mac_rx(dev->mac_handle, NULL, mblk_head);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_arm_cq(dev, cq->cq_id, num_cqe, B_TRUE);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (num_cqe);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_drain_rq_cq */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to free mblk databuffer to the RQ pool
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * arg - pointer to the receive buffer descriptor
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return none
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanvoid
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanoce_rx_pool_free(char *arg)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_rq_bdesc_t *rqbd;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_rq *rq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* During destroy, arg will be NULL */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (arg == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* retrieve the pointers from arg */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rqbd = (oce_rq_bdesc_t *)(void *)arg;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq = rqbd->rq;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd->mp = desballoc((uchar_t *)rqbd->rqb->base,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rqbd->rqb->size, 0, &rqbd->fr_rtn);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (rqbd->mp) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rqbd->mp->b_rptr =
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (uchar_t *)rqbd->rqb->base + OCE_RQE_BUF_HEADROOM;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_rqb_free(rq, rqbd);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek (void) atomic_dec_32(&rq->pending);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* rx_pool_free */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to stop the RX
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rq - pointer to RQ structure
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return none
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanvoid
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_clean_rq(struct oce_rq *rq)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan uint16_t num_cqe = 0;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_cq *cq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_dev *dev;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_nic_rx_cqe *cqe;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan int32_t ti = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan dev = rq->parent;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan cq = rq->cq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* dequeue till you reach an invalid cqe */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan for (ti = 0; ti < DEFAULT_DRAIN_TIME; ti++) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan while (RQ_CQE_VALID(cqe)) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan DW_SWAP(u32ptr(cqe), sizeof (struct oce_nic_rx_cqe));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_rx_drop_pkt(rq, cqe);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan atomic_add_32(&rq->buf_avail,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan -(cqe->u0.s.num_fragments & 0x7));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_arm_cq(dev, cq->cq_id, 1, B_TRUE);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan RQ_CQE_INVALIDATE(cqe);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan RING_GET(cq->ring, 1);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_nic_rx_cqe);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan num_cqe++;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan OCE_MSDELAY(1);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan} /* oce_clean_rq */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to start the RX
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rq - pointer to RQ structure
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return number of rqe's charges.
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanint
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_start_rq(struct oce_rq *rq)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int ret = 0;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan int to_charge = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_dev *dev = rq->parent;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan to_charge = rq->cfg.q_len - rq->buf_avail;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan to_charge = min(to_charge, rq->rqb_free);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan atomic_add_32(&rq->rqb_free, -to_charge);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (void) oce_rq_charge(rq, to_charge, B_FALSE);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* ok to do it here since Rx has not even started */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_rq_post_buffer(rq, to_charge);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_arm_cq(dev, rq->cq->cq_id, 0, B_TRUE);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (ret);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_start_rq */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan/* Checks for pending rx buffers with Stack */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanint
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanoce_rx_pending(struct oce_dev *dev, struct oce_rq *rq, int32_t timeout)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan int ti;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan _NOTE(ARGUNUSED(dev));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (ti = 0; ti < timeout; ti++) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (rq->pending > 0) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan OCE_MSDELAY(10);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan continue;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan } else {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->pending = 0;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan break;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan return (rq->pending);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan}