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/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * Source file containing Queue handling functions
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan#include <oce_impl.h>
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amoreextern struct oce_dev *oce_dev_list[];
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanint oce_destroy_q(struct oce_dev *oce, struct oce_mbx *mbx, size_t req_size,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan enum qtype qtype);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan/* MAil box Queue functions */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstruct oce_mq *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_mq_create(struct oce_dev *dev, struct oce_eq *eq, uint32_t q_len);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan/* event queue handling */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstruct oce_eq *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_eq_create(struct oce_dev *dev, uint32_t q_len, uint32_t item_size,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan uint32_t eq_delay);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan/* completion queue handling */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstruct oce_cq *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_cq_create(struct oce_dev *dev, struct oce_eq *eq, uint32_t q_len,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan uint32_t item_size, boolean_t sol_event, boolean_t is_eventable,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan boolean_t nodelay, uint32_t ncoalesce);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan/* Tx WQ functions */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic struct oce_wq *oce_wq_init(struct oce_dev *dev, uint32_t q_len,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan int wq_type);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic void oce_wq_fini(struct oce_dev *dev, struct oce_wq *wq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic int oce_wq_create(struct oce_wq *wq, struct oce_eq *eq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic void oce_wq_del(struct oce_dev *dev, struct oce_wq *wq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan/* Rx Queue functions */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic struct oce_rq *oce_rq_init(struct oce_dev *dev, uint32_t q_len,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan uint32_t frag_size, uint32_t mtu,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan boolean_t rss);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic void oce_rq_fini(struct oce_dev *dev, struct oce_rq *rq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic int oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic void oce_rq_del(struct oce_dev *dev, struct oce_rq *rq);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to create an event queue
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * eqcfg - pointer to a config structure containg the eq parameters
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return pointer to EQ; NULL on failure
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanstruct oce_eq *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_eq_create(struct oce_dev *dev, uint32_t q_len, uint32_t item_size,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan uint32_t eq_delay)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_eq *eq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_mbx mbx;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct mbx_create_common_eq *fwcmd;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int ret = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* allocate an eq */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq = kmem_zalloc(sizeof (struct oce_eq), KM_NOSLEEP);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (eq == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan bzero(&mbx, sizeof (struct oce_mbx));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* allocate mbx */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd = (struct mbx_create_common_eq *)&mbx.payload;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq->ring = create_ring_buffer(dev, q_len,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan item_size, DDI_DMA_CONSISTENT);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (eq->ring == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG,
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore "EQ ring alloc failed:0x%p", (void *)eq->ring);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan kmem_free(eq, sizeof (struct oce_eq));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan MBX_SUBSYSTEM_COMMON,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan OPCODE_CREATE_COMMON_EQ, MBX_TIMEOUT_SEC,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan sizeof (struct mbx_create_common_eq));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.num_pages = eq->ring->dbuf->num_pages;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_page_list(eq->ring->dbuf, &fwcmd->params.req.pages[0],
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq->ring->dbuf->num_pages);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* dw 0 */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.eq_ctx.size = (item_size == 4) ? 0 : 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.eq_ctx.valid = 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* dw 1 */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.eq_ctx.armed = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.eq_ctx.pd = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.eq_ctx.count = OCE_LOG2(q_len/256);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* dw 2 */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.eq_ctx.function = dev->fn;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.eq_ctx.nodelay = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.eq_ctx.phase = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* todo: calculate multiplier from max min and cur */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.eq_ctx.delay_mult = eq_delay;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* fill rest of mbx */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx.u0.s.embedded = 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx.payload_length = sizeof (struct mbx_create_common_eq);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* now post the command */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan ret = oce_mbox_post(dev, &mbx, NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (ret != 0) {
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore oce_log(dev, CE_WARN, MOD_CONFIG, "EQ create failed: %d", ret);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan destroy_ring_buffer(dev, eq->ring);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan kmem_free(eq, sizeof (struct oce_eq));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* interpret the response */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq->eq_id = LE_16(fwcmd->params.rsp.eq_id);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq->eq_cfg.q_len = q_len;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq->eq_cfg.item_size = item_size;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq->eq_cfg.cur_eqd = (uint8_t)eq_delay;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq->parent = (void *)dev;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan atomic_inc_32(&dev->neqs);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_NOTE, MOD_CONFIG,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "EQ created, eq=0x%p eq_id=0x%x", (void *)eq, eq->eq_id);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* Save the eq pointer */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (eq);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_eq_create */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to delete an event queue
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * eq - handle to the eq to be deleted
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return 0=>success, failure otherwise
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanvoid
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_eq_del(struct oce_dev *dev, struct oce_eq *eq)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_mbx mbx;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct mbx_destroy_common_eq *fwcmd;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* drain the residual events */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_drain_eq(eq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* destroy the ring */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan destroy_ring_buffer(dev, eq->ring);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq->ring = NULL;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* send a command to delete the EQ */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd = (struct mbx_destroy_common_eq *)&mbx.payload;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd->params.req.id = eq->eq_id;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan (void) oce_destroy_q(dev, &mbx,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan sizeof (struct mbx_destroy_common_eq),
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan QTYPE_EQ);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan kmem_free(eq, sizeof (struct oce_eq));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan atomic_dec_32(&dev->neqs);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan}
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to create a completion queue
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * eq - optional eq to be associated with to the cq
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * cqcfg - configuration for this queue
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return pointer to the cq created. NULL on failure
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanstruct oce_cq *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_cq_create(struct oce_dev *dev, struct oce_eq *eq, uint32_t q_len,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan uint32_t item_size, boolean_t sol_event, boolean_t is_eventable,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan boolean_t nodelay, uint32_t ncoalesce)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_cq *cq = NULL;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_mbx mbx;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct mbx_create_common_cq *fwcmd;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int ret = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* create cq */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq = kmem_zalloc(sizeof (struct oce_cq), KM_NOSLEEP);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (cq == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "CQ allocation failed");
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* create the ring buffer for this queue */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq->ring = create_ring_buffer(dev, q_len,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan item_size, DDI_DMA_CONSISTENT);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (cq->ring == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "CQ ring alloc failed:0x%p",
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan (void *)cq->ring);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan kmem_free(cq, sizeof (struct oce_cq));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* initialize mailbox */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan bzero(&mbx, sizeof (struct oce_mbx));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd = (struct mbx_create_common_cq *)&mbx.payload;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* fill the command header */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan MBX_SUBSYSTEM_COMMON,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan OPCODE_CREATE_COMMON_CQ, MBX_TIMEOUT_SEC,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan sizeof (struct mbx_create_common_cq));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* fill command context */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* dw0 */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.cq_ctx.eventable = is_eventable;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.cq_ctx.sol_event = sol_event;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.cq_ctx.valid = 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.cq_ctx.count = OCE_LOG2(q_len/256);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.cq_ctx.nodelay = nodelay;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.cq_ctx.coalesce_wm = ncoalesce;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* dw1 */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd->params.req.cq_ctx.armed = B_FALSE;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.cq_ctx.eq_id = eq->eq_id;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.cq_ctx.pd = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* dw2 */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.cq_ctx.function = dev->fn;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* fill the rest of the command */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.num_pages = cq->ring->dbuf->num_pages;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_page_list(cq->ring->dbuf, &fwcmd->params.req.pages[0],
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq->ring->dbuf->num_pages);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* fill rest of mbx */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx.u0.s.embedded = 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx.payload_length = sizeof (struct mbx_create_common_cq);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* now send the mail box */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan ret = oce_mbox_post(dev, &mbx, NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (ret != 0) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "CQ create failed: 0x%x", ret);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan destroy_ring_buffer(dev, cq->ring);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan kmem_free(cq, sizeof (struct oce_cq));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq->parent = dev;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq->eq = eq; /* eq array index */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq->cq_cfg.q_len = q_len;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq->cq_cfg.item_size = item_size;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq->cq_cfg.sol_eventable = (uint8_t)sol_event;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq->cq_cfg.nodelay = (uint8_t)nodelay;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* interpret the response */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq->cq_id = LE_16(fwcmd->params.rsp.cq_id);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->cq[cq->cq_id % OCE_MAX_CQ] = cq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan atomic_inc_32(&eq->ref_count);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (cq);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_cq_create */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to delete a completion queue
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * cq - handle to the CQ to delete
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan * return none
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic void
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_cq_del(struct oce_dev *dev, struct oce_cq *cq)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_mbx mbx;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct mbx_destroy_common_cq *fwcmd;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* destroy the ring */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan destroy_ring_buffer(dev, cq->ring);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq->ring = NULL;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan bzero(&mbx, sizeof (struct oce_mbx));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* send a command to delete the CQ */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd = (struct mbx_destroy_common_cq *)&mbx.payload;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd->params.req.id = cq->cq_id;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan (void) oce_destroy_q(dev, &mbx,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan sizeof (struct mbx_destroy_common_cq),
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan QTYPE_CQ);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* Reset the handler */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan cq->cq_handler = NULL;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->cq[cq->cq_id % OCE_MAX_CQ] = NULL;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan atomic_dec_32(&cq->eq->ref_count);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mutex_destroy(&cq->lock);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* release the eq */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan kmem_free(cq, sizeof (struct oce_cq));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_cq_del */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to create an MQ
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * eq - the EQ to associate with the MQ for event notification
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * q_len - the number of entries to create in the MQ
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return pointer to the created MQ, failure otherwise
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanstruct oce_mq *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_mq_create(struct oce_dev *dev, struct oce_eq *eq, uint32_t q_len)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_mbx mbx;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct mbx_create_common_mq *fwcmd;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_mq *mq = NULL;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int ret = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_cq *cq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* Create the Completion Q */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq = oce_cq_create(dev, eq, CQ_LEN_256,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan sizeof (struct oce_mq_cqe),
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan B_FALSE, B_TRUE, B_TRUE, 0);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (cq == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* allocate the mq */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mq = kmem_zalloc(sizeof (struct oce_mq), KM_NOSLEEP);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (mq == NULL) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan goto mq_alloc_fail;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan bzero(&mbx, sizeof (struct oce_mbx));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* allocate mbx */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd = (struct mbx_create_common_mq *)&mbx.payload;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* create the ring buffer for this queue */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mq->ring = create_ring_buffer(dev, q_len,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan sizeof (struct oce_mbx), DDI_DMA_CONSISTENT | DDI_DMA_RDWR);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (mq->ring == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "MQ ring alloc failed:0x%p",
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan (void *)mq->ring);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan goto mq_ring_alloc;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan MBX_SUBSYSTEM_COMMON,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan OPCODE_CREATE_COMMON_MQ, MBX_TIMEOUT_SEC,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan sizeof (struct mbx_create_common_mq));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.num_pages = mq->ring->dbuf->num_pages;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_page_list(mq->ring->dbuf, fwcmd->params.req.pages,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mq->ring->dbuf->num_pages);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.context.u0.s.cq_id = cq->cq_id;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.context.u0.s.ring_size =
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan OCE_LOG2(q_len) + 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.context.u0.s.valid = 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.context.u0.s.fid = dev->fn;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* fill rest of mbx */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx.u0.s.embedded = 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx.payload_length = sizeof (struct mbx_create_common_mq);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* now send the mail box */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan ret = oce_mbox_post(dev, &mbx, NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (ret != DDI_SUCCESS) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "MQ create failed: 0x%x", ret);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan goto mq_fail;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* interpret the response */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mq->mq_id = LE_16(fwcmd->params.rsp.mq_id);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mq->cq = cq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mq->cfg.q_len = (uint8_t)q_len;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mq->cfg.eqd = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* fill rest of the mq */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mq->parent = dev;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* set the MQCQ handlers */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq->cq_handler = oce_drain_mq_cq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq->cb_arg = (void *)mq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mutex_init(&mq->lock, NULL, MUTEX_DRIVER,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan DDI_INTR_PRI(dev->intr_pri));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (mq);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanmq_fail:
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan destroy_ring_buffer(dev, mq->ring);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanmq_ring_alloc:
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan kmem_free(mq, sizeof (struct oce_mq));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanmq_alloc_fail:
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_cq_del(dev, cq);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_mq_create */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to delete an MQ
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * mq - pointer to the MQ to delete
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan * return none
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic void
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_mq_del(struct oce_dev *dev, struct oce_mq *mq)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_mbx mbx;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct mbx_destroy_common_mq *fwcmd;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* destroy the ring */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan destroy_ring_buffer(dev, mq->ring);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mq->ring = NULL;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan bzero(&mbx, sizeof (struct oce_mbx));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd = (struct mbx_destroy_common_mq *)&mbx.payload;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd->params.req.id = mq->mq_id;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan (void) oce_destroy_q(dev, &mbx,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan sizeof (struct mbx_destroy_common_mq),
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan QTYPE_MQ);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_cq_del(dev, mq->cq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mq->cq = NULL;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mutex_destroy(&mq->lock);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan kmem_free(mq, sizeof (struct oce_mq));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_mq_del */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to create a WQ for NIC Tx
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * wqcfg - configuration structure providing WQ config parameters
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return pointer to the WQ created. NULL on failure
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic struct oce_wq *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_wq_init(struct oce_dev *dev, uint32_t q_len, int wq_type)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_wq *wq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan char str[MAX_POOL_NAME];
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int ret;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan static int wq_id = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan ASSERT(dev != NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* q_len must be min 256 and max 2k */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (q_len < 256 || q_len > 2048) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "Invalid q length. Must be "
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "[256, 2000]: 0x%x", q_len);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* allocate wq */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan wq = kmem_zalloc(sizeof (struct oce_wq), KM_NOSLEEP);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (wq == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "WQ allocation failed");
12d61dab3304980e691068219eaaab6398744a2eSukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* Set the wq config */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan wq->cfg.q_len = q_len;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan wq->cfg.wq_type = (uint8_t)wq_type;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan wq->cfg.eqd = OCE_DEFAULT_WQ_EQD;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan wq->cfg.nbufs = 2 * wq->cfg.q_len;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan wq->cfg.nhdl = 2 * wq->cfg.q_len;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan wq->cfg.buf_size = dev->tx_bcopy_limit;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* assign parent */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan wq->parent = (void *)dev;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* Create the WQ Buffer pool */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan ret = oce_wqb_cache_create(wq, wq->cfg.buf_size);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (ret != DDI_SUCCESS) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "WQ Buffer Pool create failed ");
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan goto wqb_fail;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* Create a pool of memory handles */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan ret = oce_wqm_cache_create(wq);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (ret != DDI_SUCCESS) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "WQ MAP Handles Pool create failed ");
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan goto wqm_fail;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (void) snprintf(str, MAX_POOL_NAME, "%s%d%s%d", "oce_wqed_",
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->dev_id, "_", wq_id++);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan wq->wqed_cache = kmem_cache_create(str, sizeof (oce_wqe_desc_t),
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan 0, NULL, NULL, NULL, NULL, NULL, 0);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (wq->wqed_cache == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "WQ Packet Desc Pool create failed ");
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan goto wqed_fail;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* create the ring buffer */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan wq->ring = create_ring_buffer(dev, q_len,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan NIC_WQE_SIZE, DDI_DMA_CONSISTENT | DDI_DMA_RDWR);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (wq->ring == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "Failed to create WQ ring ");
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan goto wq_ringfail;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* Initialize WQ lock */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mutex_init(&wq->tx_lock, NULL, MUTEX_DRIVER,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan DDI_INTR_PRI(dev->intr_pri));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* Initialize WQ lock */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mutex_init(&wq->txc_lock, NULL, MUTEX_DRIVER,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan DDI_INTR_PRI(dev->intr_pri));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan atomic_inc_32(&dev->nwqs);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan OCE_LIST_CREATE(&wq->wqe_desc_list, DDI_INTR_PRI(dev->intr_pri));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (wq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanwqcq_fail:
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan destroy_ring_buffer(dev, wq->ring);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanwq_ringfail:
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan kmem_cache_destroy(wq->wqed_cache);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanwqed_fail:
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_wqm_cache_destroy(wq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanwqm_fail:
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_wqb_cache_destroy(wq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanwqb_fail:
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan kmem_free(wq, sizeof (struct oce_wq));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (NULL);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan} /* oce_wq_create */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan/*
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan * function to delete a WQ
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan * dev - software handle to the device
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan * wq - WQ to delete
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan * return 0 => success, failure otherwise
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic void
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_wq_fini(struct oce_dev *dev, struct oce_wq *wq)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* destroy cq */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_wqb_cache_destroy(wq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_wqm_cache_destroy(wq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan kmem_cache_destroy(wq->wqed_cache);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* Free the packet descriptor list */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan OCE_LIST_DESTROY(&wq->wqe_desc_list);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan destroy_ring_buffer(dev, wq->ring);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan wq->ring = NULL;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* Destroy the Mutex */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mutex_destroy(&wq->tx_lock);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mutex_destroy(&wq->txc_lock);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan kmem_free(wq, sizeof (struct oce_wq));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan atomic_dec_32(&dev->nwqs);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan} /* oce_wq_del */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic int
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_wq_create(struct oce_wq *wq, struct oce_eq *eq)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_mbx mbx;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct mbx_create_nic_wq *fwcmd;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_dev *dev = wq->parent;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_cq *cq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan int ret;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* create the CQ */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan cq = oce_cq_create(dev, eq, CQ_LEN_1024,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan sizeof (struct oce_nic_tx_cqe),
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan B_FALSE, B_TRUE, B_FALSE, 3);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan if (cq == NULL) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan "WCCQ create failed ");
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (DDI_FAILURE);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* now fill the command */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan bzero(&mbx, sizeof (struct oce_mbx));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd = (struct mbx_create_nic_wq *)&mbx.payload;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan MBX_SUBSYSTEM_NIC,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan OPCODE_CREATE_NIC_WQ, MBX_TIMEOUT_SEC,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan sizeof (struct mbx_create_nic_wq));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd->params.req.nic_wq_type = (uint8_t)wq->cfg.wq_type;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.num_pages = wq->ring->dbuf->num_pages;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_NOTE, MOD_CONFIG, "NUM_PAGES = 0x%d size = %lu",
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan (uint32_t)wq->ring->dbuf->num_pages,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan wq->ring->dbuf->size);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* workaround: fill 0x01 for ulp_mask in rsvd0 */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.rsvd0 = 0x01;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd->params.req.wq_size = OCE_LOG2(wq->cfg.q_len) + 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.valid = 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.pd_id = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.pci_function_id = dev->fn;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.cq_id = cq->cq_id;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_page_list(wq->ring->dbuf, fwcmd->params.req.pages,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan wq->ring->dbuf->num_pages);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* fill rest of mbx */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx.u0.s.embedded = 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx.payload_length = sizeof (struct mbx_create_nic_wq);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* now post the command */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan ret = oce_mbox_post(dev, &mbx, NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (ret != DDI_SUCCESS) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "WQ create failed: %d", ret);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_cq_del(dev, cq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (ret);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* interpret the response */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan wq->wq_id = LE_16(fwcmd->params.rsp.wq_id);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan wq->qstate = QCREATED;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan wq->cq = cq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* set the WQCQ handlers */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan wq->cq->cq_handler = oce_drain_wq_cq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan wq->cq->cb_arg = (void *)wq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* All are free to start with */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan wq->wq_free = wq->cfg.q_len;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* reset indicies */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan wq->ring->cidx = 0;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan wq->ring->pidx = 0;
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore oce_log(dev, CE_NOTE, MOD_CONFIG, "WQ CREATED WQID = %d",
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore wq->wq_id);
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (0);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan}
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to delete a WQ
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * wq - WQ to delete
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan * return none
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic void
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_wq_del(struct oce_dev *dev, struct oce_wq *wq)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_mbx mbx;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct mbx_delete_nic_wq *fwcmd;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan ASSERT(dev != NULL);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan ASSERT(wq != NULL);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan if (wq->qstate == QCREATED) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan bzero(&mbx, sizeof (struct oce_mbx));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* now fill the command */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd = (struct mbx_delete_nic_wq *)&mbx.payload;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd->params.req.wq_id = wq->wq_id;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan (void) oce_destroy_q(dev, &mbx,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan sizeof (struct mbx_delete_nic_wq),
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan QTYPE_WQ);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan wq->qstate = QDELETED;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_cq_del(dev, wq->cq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan wq->cq = NULL;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_wq_del */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan * function to allocate RQ resources
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rqcfg - configuration structure providing RQ config parameters
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return pointer to the RQ created. NULL on failure
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic struct oce_rq *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_rq_init(struct oce_dev *dev, uint32_t q_len,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan uint32_t frag_size, uint32_t mtu,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan boolean_t rss)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_rq *rq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int ret;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* validate q creation parameters */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (!OCE_LOG2(frag_size))
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if ((q_len == 0) || (q_len > 1024))
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* allocate the rq */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq = kmem_zalloc(sizeof (struct oce_rq), KM_NOSLEEP);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (rq == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "RQ allocation failed");
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq->cfg.q_len = q_len;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq->cfg.frag_size = frag_size;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq->cfg.mtu = mtu;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq->cfg.eqd = 0;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->cfg.nbufs = dev->rq_max_bufs;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->cfg.is_rss_queue = rss;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* assign parent */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq->parent = (void *)dev;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->rq_bdesc_array =
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan kmem_zalloc((sizeof (oce_rq_bdesc_t) * rq->cfg.nbufs), KM_NOSLEEP);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (rq->rq_bdesc_array == NULL) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan "RQ bdesc alloc failed");
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan goto rqbd_alloc_fail;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* create the rq buffer descriptor ring */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->shadow_ring =
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan kmem_zalloc((rq->cfg.q_len * sizeof (oce_rq_bdesc_t *)),
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan KM_NOSLEEP);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (rq->shadow_ring == NULL) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan "RQ shadow ring alloc failed ");
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan goto rq_shdw_fail;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* allocate the free list array */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->rqb_freelist =
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan kmem_zalloc(rq->cfg.nbufs * sizeof (oce_rq_bdesc_t *), KM_NOSLEEP);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (rq->rqb_freelist == NULL) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan goto rqb_free_list_fail;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* create the buffer pool */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan ret = oce_rqb_cache_create(rq, dev->rq_frag_size +
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan OCE_RQE_BUF_HEADROOM);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (ret != DDI_SUCCESS) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan goto rqb_fail;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* create the ring buffer */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq->ring = create_ring_buffer(dev, q_len,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan sizeof (struct oce_nic_rqe), DDI_DMA_CONSISTENT | DDI_DMA_RDWR);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (rq->ring == NULL) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "RQ ring create failed ");
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan goto rq_ringfail;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* Initialize the RQ lock */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mutex_init(&rq->rx_lock, NULL, MUTEX_DRIVER,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan DDI_INTR_PRI(dev->intr_pri));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* Initialize the recharge lock */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mutex_init(&rq->rc_lock, NULL, MUTEX_DRIVER,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan DDI_INTR_PRI(dev->intr_pri));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan atomic_inc_32(&dev->nrqs);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (rq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanrq_ringfail:
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_rqb_cache_destroy(rq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanrqb_fail:
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan kmem_free(rq->rqb_freelist,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (rq->cfg.nbufs * sizeof (oce_rq_bdesc_t *)));
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amorerqb_free_list_fail:
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore kmem_free(rq->shadow_ring,
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore (rq->cfg.q_len * sizeof (oce_rq_bdesc_t *)));
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanrq_shdw_fail:
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan kmem_free(rq->rq_bdesc_array,
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore (sizeof (oce_rq_bdesc_t) * rq->cfg.nbufs));
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathanrqbd_alloc_fail:
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan kmem_free(rq, sizeof (struct oce_rq));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (NULL);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan} /* oce_rq_create */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan/*
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan * function to delete an RQ
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan * dev - software handle to the device
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan * rq - RQ to delete
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan * return none
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic void
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_rq_fini(struct oce_dev *dev, struct oce_rq *rq)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* Destroy buffer cache */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_rqb_cache_destroy(rq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan destroy_ring_buffer(dev, rq->ring);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rq->ring = NULL;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan kmem_free(rq->shadow_ring,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan sizeof (oce_rq_bdesc_t *) * rq->cfg.q_len);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rq->shadow_ring = NULL;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan kmem_free(rq->rq_bdesc_array,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (sizeof (oce_rq_bdesc_t) * rq->cfg.nbufs));
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->rq_bdesc_array = NULL;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan kmem_free(rq->rqb_freelist,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan (rq->cfg.nbufs * sizeof (oce_rq_bdesc_t *)));
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->rqb_freelist = NULL;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mutex_destroy(&rq->rx_lock);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mutex_destroy(&rq->rc_lock);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan kmem_free(rq, sizeof (struct oce_rq));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan atomic_dec_32(&dev->nrqs);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan} /* oce_rq_del */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic int
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_mbx mbx;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct mbx_create_nic_rq *fwcmd;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_dev *dev = rq->parent;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_cq *cq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan int ret;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan cq = oce_cq_create(dev, eq, CQ_LEN_1024, sizeof (struct oce_nic_rx_cqe),
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan B_FALSE, B_TRUE, B_FALSE, 3);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan if (cq == NULL) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (DDI_FAILURE);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* now fill the command */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan bzero(&mbx, sizeof (struct oce_mbx));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd = (struct mbx_create_nic_rq *)&mbx.payload;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan MBX_SUBSYSTEM_NIC,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan OPCODE_CREATE_NIC_RQ, MBX_TIMEOUT_SEC,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan sizeof (struct mbx_create_nic_rq));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.num_pages = rq->ring->dbuf->num_pages;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd->params.req.frag_size = OCE_LOG2(rq->cfg.frag_size);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.cq_id = cq->cq_id;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_page_list(rq->ring->dbuf, fwcmd->params.req.pages,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq->ring->dbuf->num_pages);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.if_id = if_id;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd->params.req.max_frame_size = (uint16_t)rq->cfg.mtu;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd->params.req.is_rss_queue = rq->cfg.is_rss_queue;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* fill rest of mbx */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx.u0.s.embedded = 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx.payload_length = sizeof (struct mbx_create_nic_rq);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* now post the command */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan ret = oce_mbox_post(dev, &mbx, NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (ret != 0) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "RQ create failed: %d", ret);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_cq_del(dev, cq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (ret);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* interpret the response */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq->rq_id = LE_16(fwcmd->params.rsp.u0.s.rq_id);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan rq->rss_cpuid = fwcmd->params.rsp.u0.s.rss_cpuid;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rq->cfg.if_id = if_id;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rq->qstate = QCREATED;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan rq->cq = cq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* set the Completion Handler */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rq->cq->cq_handler = oce_drain_rq_cq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rq->cq->cb_arg = (void *)rq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* reset the indicies */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rq->ring->cidx = 0;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rq->ring->pidx = 0;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rq->buf_avail = 0;
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore oce_log(dev, CE_NOTE, MOD_CONFIG, "RQ created, RQID : %d", rq->rq_id);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (0);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan}
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to delete an RQ
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rq - RQ to delete
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan * return none
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanstatic void
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_rq_del(struct oce_dev *dev, struct oce_rq *rq)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_mbx mbx;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct mbx_delete_nic_rq *fwcmd;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan ASSERT(dev != NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan ASSERT(rq != NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan bzero(&mbx, sizeof (struct oce_mbx));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* delete the Queue */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan if (rq->qstate == QCREATED) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan fwcmd->params.req.rq_id = rq->rq_id;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan (void) oce_destroy_q(dev, &mbx,
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan sizeof (struct mbx_delete_nic_rq), QTYPE_RQ);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rq->qstate = QDELETED;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_clean_rq(rq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* Delete the associated CQ */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_cq_del(dev, rq->cq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan rq->cq = NULL;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan /* free up the posted buffers */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_rq_discharge(rq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_rq_del */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to arm an EQ so that it can generate events
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * qid - id of the EQ returned by the fw at the time of creation
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * npopped - number of EQEs to arm with
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rearm - rearm bit
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * clearint - bit to clear the interrupt condition because of which
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * EQEs are generated
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return none
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanvoid
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_arm_eq(struct oce_dev *dev, int16_t qid, int npopped,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan boolean_t rearm, boolean_t clearint)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq_db_t eq_db = {0};
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq_db.bits.rearm = rearm;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq_db.bits.event = B_TRUE;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq_db.bits.num_popped = npopped;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq_db.bits.clrint = clearint;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eq_db.bits.qid = qid;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan OCE_DB_WRITE32(dev, PD_EQ_DB, eq_db.dw0);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan}
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to arm a CQ with CQEs
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * qid - the id of the CQ returned by the fw at the time of creation
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * npopped - number of CQEs to arm with
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * rearm - rearm bit enable/disable
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return none
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanvoid
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_arm_cq(struct oce_dev *dev, int16_t qid, int npopped,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan boolean_t rearm)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq_db_t cq_db = {0};
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq_db.bits.rearm = rearm;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq_db.bits.num_popped = npopped;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq_db.bits.event = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq_db.bits.qid = qid;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan OCE_DB_WRITE32(dev, PD_CQ_DB, cq_db.dw0);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan}
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to delete a EQ, CQ, MQ, WQ or RQ
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - sofware handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * mbx - mbox command to send to the fw to delete the queue
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * mbx contains the queue information to delete
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * req_size - the size of the mbx payload dependent on the qtype
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * qtype - the type of queue i.e. EQ, CQ, MQ, WQ or RQ
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return DDI_SUCCESS => success, failure otherwise
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanint
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_destroy_q(struct oce_dev *dev, struct oce_mbx *mbx, size_t req_size,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan enum qtype qtype)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct mbx_hdr *hdr = (struct mbx_hdr *)&mbx->payload;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int opcode;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int subsys;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int ret;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan switch (qtype) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan case QTYPE_EQ: {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan opcode = OPCODE_DESTROY_COMMON_EQ;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan subsys = MBX_SUBSYSTEM_COMMON;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan break;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan case QTYPE_CQ: {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan opcode = OPCODE_DESTROY_COMMON_CQ;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan subsys = MBX_SUBSYSTEM_COMMON;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan break;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan case QTYPE_MQ: {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan opcode = OPCODE_DESTROY_COMMON_MQ;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan subsys = MBX_SUBSYSTEM_COMMON;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan break;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan case QTYPE_WQ: {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan opcode = OPCODE_DELETE_NIC_WQ;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan subsys = MBX_SUBSYSTEM_NIC;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan break;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan case QTYPE_RQ: {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan opcode = OPCODE_DELETE_NIC_RQ;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan subsys = MBX_SUBSYSTEM_NIC;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan break;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan default: {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan ASSERT(0);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan break;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx_common_req_hdr_init(hdr, 0, 0, subsys,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan opcode, MBX_TIMEOUT_SEC, req_size);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* fill rest of mbx */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx->u0.s.embedded = 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx->payload_length = (uint32_t)req_size;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan DW_SWAP(u32ptr(mbx), mbx->payload_length + OCE_BMBX_RHDR_SZ);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* send command */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan ret = oce_mbox_post(dev, mbx, NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (ret != 0) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "Failed to del q ");
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (ret);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan}
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to set the delay parameter in the EQ for interrupt coalescing
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * eq_arr - array of EQ ids to delete
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * eq_cnt - number of elements in eq_arr
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * eq_delay - delay parameter
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return DDI_SUCCESS => success, failure otherwise
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanint
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_set_eq_delay(struct oce_dev *dev, uint32_t *eq_arr,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan uint32_t eq_cnt, uint32_t eq_delay)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_mbx mbx;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct mbx_modify_common_eq_delay *fwcmd;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int ret;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan int neq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan bzero(&mbx, sizeof (struct oce_mbx));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd = (struct mbx_modify_common_eq_delay *)&mbx.payload;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* fill the command */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.num_eq = eq_cnt;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan for (neq = 0; neq < eq_cnt; neq++) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.delay[neq].eq_id = eq_arr[neq];
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.delay[neq].phase = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan fwcmd->params.req.delay[neq].dm = eq_delay;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* initialize the ioctl header */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan MBX_SUBSYSTEM_COMMON,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan OPCODE_MODIFY_COMMON_EQ_DELAY,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan MBX_TIMEOUT_SEC,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan sizeof (struct mbx_modify_common_eq_delay));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* fill rest of mbx */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx.u0.s.embedded = 1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mbx.payload_length = sizeof (struct mbx_modify_common_eq_delay);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* post the command */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan ret = oce_mbox_post(dev, &mbx, NULL);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (ret != 0) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_log(dev, CE_WARN, MOD_CONFIG,
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan "Failed to set EQ delay %d", ret);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (ret);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_set_eq_delay */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to cleanup the eqs used during stop
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * eq - pointer to event queue structure
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return none
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanvoid
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_drain_eq(struct oce_eq *eq)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_eqe *eqe;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan uint16_t num_eqe = 0;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_dev *dev;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan dev = eq->parent;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* get the first item in eq to process */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eqe = RING_GET_CONSUMER_ITEM_VA(eq->ring, struct oce_eqe);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan while (eqe->u0.dw0) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eqe->u0.dw0 = LE_32(eqe->u0.dw0);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* clear valid bit */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eqe->u0.dw0 = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* process next eqe */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan RING_GET(eq->ring, 1);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan eqe = RING_GET_CONSUMER_ITEM_VA(eq->ring, struct oce_eqe);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan num_eqe++;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan } /* for all EQEs */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan if (num_eqe) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_arm_eq(dev, eq->eq_id, num_eqe, B_FALSE, B_TRUE);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_drain_eq */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanint
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_init_txrx(struct oce_dev *dev)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan{
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan int qid = 0;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* enable RSS if rx queues > 1 */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->rss_enable = (dev->rx_rings > 1) ? B_TRUE : B_FALSE;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (qid = 0; qid < dev->tx_rings; qid++) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->wq[qid] = oce_wq_init(dev, dev->tx_ring_size,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan NIC_WQ_TYPE_STANDARD);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (dev->wq[qid] == NULL) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan goto queue_fail;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* Now create the Rx Queues */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* qid 0 is always default non rss queue for rss */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->rq[0] = oce_rq_init(dev, dev->rx_ring_size, dev->rq_frag_size,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan OCE_MAX_JUMBO_FRAME_SIZE, B_FALSE);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan if (dev->rq[0] == NULL) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan goto queue_fail;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (qid = 1; qid < dev->rx_rings; qid++) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->rq[qid] = oce_rq_init(dev, dev->rx_ring_size,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->rq_frag_size, OCE_MAX_JUMBO_FRAME_SIZE,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->rss_enable);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (dev->rq[qid] == NULL) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan goto queue_fail;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (DDI_SUCCESS);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanqueue_fail:
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_fini_txrx(dev);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (DDI_FAILURE);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan}
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanvoid
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_fini_txrx(struct oce_dev *dev)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan{
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan int qid;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan int nqs;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* free all the tx rings */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* nwqs is decremented in fini so copy count first */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan nqs = dev->nwqs;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (qid = 0; qid < nqs; qid++) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (dev->wq[qid] != NULL) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_wq_fini(dev, dev->wq[qid]);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->wq[qid] = NULL;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* free all the rx rings */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan nqs = dev->nrqs;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (qid = 0; qid < nqs; qid++) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (dev->rq[qid] != NULL) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan oce_rq_fini(dev, dev->rq[qid]);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->rq[qid] = NULL;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan}
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanint
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_create_queues(struct oce_dev *dev)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan int i;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_eq *eq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_mq *mq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan for (i = 0; i < dev->num_vectors; i++) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan eq = oce_eq_create(dev, EQ_LEN_1024, EQE_SIZE_4, 0);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan if (eq == NULL) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan goto rings_fail;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan dev->eq[i] = eq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (i = 0; i < dev->nwqs; i++) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (oce_wq_create(dev->wq[i], dev->eq[0]) != 0)
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan goto rings_fail;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (i = 0; i < dev->nrqs; i++) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan if (oce_rq_create(dev->rq[i], dev->if_id,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->neqs > 1 ? dev->eq[1 + i] : dev->eq[0]) != 0)
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan goto rings_fail;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mq = oce_mq_create(dev, dev->eq[0], 64);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan if (mq == NULL)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan goto rings_fail;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan dev->mq = mq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (DDI_SUCCESS);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanrings_fail:
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_delete_queues(dev);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (DDI_FAILURE);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan}
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanvoid
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_delete_queues(struct oce_dev *dev)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan int i;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan int neqs = dev->neqs;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan if (dev->mq != NULL) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_mq_del(dev, dev->mq);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan dev->mq = NULL;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan for (i = 0; i < dev->nrqs; i++) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_rq_del(dev, dev->rq[i]);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan for (i = 0; i < dev->nwqs; i++) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_wq_del(dev, dev->wq[i]);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /* delete as many eqs as the number of vectors */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan for (i = 0; i < neqs; i++) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_eq_del(dev, dev->eq[i]);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan dev->eq[i] = NULL;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan }
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan}
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amorevoid
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amoreoce_dev_rss_ready(struct oce_dev *dev)
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore{
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore uint8_t dev_index = 0;
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore uint8_t adapter_rss = 0;
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore /* Return if rx_rings <= 1 (No RSS) */
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore if (dev->rx_rings <= 1) {
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore oce_log(dev, CE_NOTE, MOD_CONFIG,
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore "Rx rings = %d, Not enabling RSS", dev->rx_rings);
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore return;
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore }
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore /*
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore * Count the number of PCI functions enabling RSS on this
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore * adapter
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore */
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore while (dev_index < MAX_DEVS) {
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore if ((oce_dev_list[dev_index] != NULL) &&
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore (dev->pci_bus == oce_dev_list[dev_index]->pci_bus) &&
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore (dev->pci_device == oce_dev_list[dev_index]->pci_device) &&
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore (oce_dev_list[dev_index]->rss_enable)) {
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore adapter_rss++;
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore }
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore dev_index++;
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore }
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore /*
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore * If there are already MAX_RSS_PER_ADAPTER PCI functions using
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore * RSS on this adapter, reduce the number of rx rings to 1
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore * (No RSS)
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore */
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore if (adapter_rss >= MAX_RSS_PER_ADAPTER) {
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore dev->rx_rings = 1;
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore }
3abb112f8485b33b6b9b52b340bede0a333c10bfGarrett D'Amore}