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 the implementation of the MailBox queue handling
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * and related helper functions
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan#include <oce_impl.h>
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan/*
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * function to drain a MCQ and process its CQEs
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * dev - software handle to the device
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * cq - pointer to the cq to drain
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan *
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan * return the number of CQEs processed
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanuint16_t
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanoce_drain_mq_cq(void *arg)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_mq_cqe *cqe = NULL;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan uint16_t num_cqe = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan link_state_t link_status;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_async_cqe_link_state *acqe;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_mq *mq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_cq *cq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan struct oce_dev *dev;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* do while we do not reach a cqe that is not valid */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mq = (struct oce_mq *)arg;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cq = mq->cq;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan dev = mq->parent;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mutex_enter(&mq->lock);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan while (cqe->u0.dw[3]) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan DW_SWAP(u32ptr(cqe), sizeof (struct oce_mq_cqe));
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (cqe->u0.s.async_event) {
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan acqe = (struct oce_async_cqe_link_state *)cqe;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan if (acqe->u0.s.event_code ==
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan ASYNC_EVENT_CODE_LINK_STATE) {
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan /*
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan * don't care logical or not,
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan * just check up down
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan */
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan link_status = ((acqe->u0.s.link_status &
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan ~ASYNC_EVENT_LOGICAL) ==
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan ASYNC_EVENT_LINK_UP) ?
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan LINK_STATE_UP: LINK_STATE_DOWN;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan mac_link_update(dev->mac_handle, link_status);
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->link_status = link_status;
5b9d3151a4426af9ad6ef2c2a178f13476b884b3Sukumar Swaminathan dev->link_speed = -1;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan }
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cqe->u0.dw[3] = 0;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan RING_GET(cq->ring, 1);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan num_cqe++;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan } /* for all valid CQE */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan mutex_exit(&mq->lock);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_arm_cq(dev, cq->cq_id, num_cqe, B_TRUE);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan return (num_cqe);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan} /* oce_drain_mq_cq */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanint
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_start_mq(struct oce_mq *mq)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_arm_cq(mq->parent, mq->cq->cq_id, 0, B_TRUE);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan return (0);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan}
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathanvoid
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathanoce_clean_mq(struct oce_mq *mq)
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan{
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_cq *cq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_dev *dev;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan uint16_t num_cqe = 0;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan struct oce_mq_cqe *cqe = NULL;
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan cq = mq->cq;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan dev = mq->parent;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan while (cqe->u0.dw[3]) {
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan DW_SWAP(u32ptr(cqe), sizeof (struct oce_mq_cqe));
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan cqe->u0.dw[3] = 0;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan RING_GET(cq->ring, 1);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan num_cqe++;
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan } /* for all valid CQE */
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan if (num_cqe)
8d738d7d1f42180d941afa8b9a7310a2a437d17cSukumar Swaminathan oce_arm_cq(dev, cq->cq_id, num_cqe, B_FALSE);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan /* Drain the Event queue now */
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan oce_drain_eq(mq->cq->eq);
4d0e50075058332ce0cd62bc2669a8a4dea45da0Sukumar Swaminathan}