14d0e5007SSukumar Swaminathan /*
24d0e5007SSukumar Swaminathan  * CDDL HEADER START
34d0e5007SSukumar Swaminathan  *
44d0e5007SSukumar Swaminathan  * The contents of this file are subject to the terms of the
54d0e5007SSukumar Swaminathan  * Common Development and Distribution License (the "License").
64d0e5007SSukumar Swaminathan  * You may not use this file except in compliance with the License.
74d0e5007SSukumar Swaminathan  *
84d0e5007SSukumar Swaminathan  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94d0e5007SSukumar Swaminathan  * or http://www.opensolaris.org/os/licensing.
104d0e5007SSukumar Swaminathan  * See the License for the specific language governing permissions
114d0e5007SSukumar Swaminathan  * and limitations under the License.
124d0e5007SSukumar Swaminathan  *
134d0e5007SSukumar Swaminathan  * When distributing Covered Code, include this CDDL HEADER in each
144d0e5007SSukumar Swaminathan  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154d0e5007SSukumar Swaminathan  * If applicable, add the following below this CDDL HEADER, with the
164d0e5007SSukumar Swaminathan  * fields enclosed by brackets "[]" replaced with your own identifying
174d0e5007SSukumar Swaminathan  * information: Portions Copyright [yyyy] [name of copyright owner]
184d0e5007SSukumar Swaminathan  *
194d0e5007SSukumar Swaminathan  * CDDL HEADER END
204d0e5007SSukumar Swaminathan  */
214d0e5007SSukumar Swaminathan 
22*3abb112fSGarrett D'Amore /* Copyright © 2003-2011 Emulex. All rights reserved.  */
234d0e5007SSukumar Swaminathan 
244d0e5007SSukumar Swaminathan /*
254d0e5007SSukumar Swaminathan  * Source file interrupt registration
264d0e5007SSukumar Swaminathan  * and related helper functions
274d0e5007SSukumar Swaminathan  */
284d0e5007SSukumar Swaminathan 
294d0e5007SSukumar Swaminathan #include <oce_impl.h>
304d0e5007SSukumar Swaminathan 
31*3abb112fSGarrett D'Amore 
324d0e5007SSukumar Swaminathan static uint_t oce_isr(caddr_t arg1, caddr_t arg2);
334d0e5007SSukumar Swaminathan 
344d0e5007SSukumar Swaminathan /*
354d0e5007SSukumar Swaminathan  * top level function to setup interrupts
364d0e5007SSukumar Swaminathan  *
374d0e5007SSukumar Swaminathan  * dev - software handle to the device
384d0e5007SSukumar Swaminathan  *
394d0e5007SSukumar Swaminathan  * return DDI_SUCCESS => success, failure otherwise
404d0e5007SSukumar Swaminathan  */
414d0e5007SSukumar Swaminathan int
oce_setup_intr(struct oce_dev * dev)424d0e5007SSukumar Swaminathan oce_setup_intr(struct oce_dev *dev)
434d0e5007SSukumar Swaminathan {
444d0e5007SSukumar Swaminathan 	int ret;
458d738d7dSSukumar Swaminathan 	int intr_types = 0;
465b9d3151SSukumar Swaminathan 	int navail = 0;
475b9d3151SSukumar Swaminathan 	int nsupported = 0;
485b9d3151SSukumar Swaminathan 	int min = 0;
495b9d3151SSukumar Swaminathan 	int nreqd = 0;
505b9d3151SSukumar Swaminathan 	int nallocd = 0;
514d0e5007SSukumar Swaminathan 
528d738d7dSSukumar Swaminathan 	/* get supported intr types */
538d738d7dSSukumar Swaminathan 	ret = ddi_intr_get_supported_types(dev->dip, &intr_types);
548d738d7dSSukumar Swaminathan 	if (ret != DDI_SUCCESS) {
558d738d7dSSukumar Swaminathan 		oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
568d738d7dSSukumar Swaminathan 		    "Failed to retrieve intr types ");
578d738d7dSSukumar Swaminathan 		return (DDI_FAILURE);
584d0e5007SSukumar Swaminathan 	}
594d0e5007SSukumar Swaminathan 
605b9d3151SSukumar Swaminathan retry_intr:
618d738d7dSSukumar Swaminathan 	if (intr_types & DDI_INTR_TYPE_MSIX) {
625b9d3151SSukumar Swaminathan 		dev->intr_type = DDI_INTR_TYPE_MSIX;
635b9d3151SSukumar Swaminathan 		/* one vector is shared by MCC and Tx */
645b9d3151SSukumar Swaminathan 		nreqd = dev->rx_rings + 1;
655b9d3151SSukumar Swaminathan 		min = OCE_MIN_VECTORS;
665b9d3151SSukumar Swaminathan 	} else if (intr_types & DDI_INTR_TYPE_FIXED) {
675b9d3151SSukumar Swaminathan 		dev->intr_type = DDI_INTR_TYPE_FIXED;
685b9d3151SSukumar Swaminathan 		nreqd = OCE_MIN_VECTORS;
695b9d3151SSukumar Swaminathan 		min = OCE_MIN_VECTORS;
708d738d7dSSukumar Swaminathan 	}
718d738d7dSSukumar Swaminathan 
725b9d3151SSukumar Swaminathan 	ret = ddi_intr_get_nintrs(dev->dip, dev->intr_type, &nsupported);
735b9d3151SSukumar Swaminathan 	if (ret != DDI_SUCCESS) {
745b9d3151SSukumar Swaminathan 		oce_log(dev, CE_WARN, MOD_CONFIG,
755b9d3151SSukumar Swaminathan 		    "Could not get nintrs:0x%d", ret);
765b9d3151SSukumar Swaminathan 		return (DDI_FAILURE);
778d738d7dSSukumar Swaminathan 	}
788d738d7dSSukumar Swaminathan 
795b9d3151SSukumar Swaminathan 	/* get the number of vectors available */
805b9d3151SSukumar Swaminathan 	ret = ddi_intr_get_navail(dev->dip, dev->intr_type, &navail);
815b9d3151SSukumar Swaminathan 	if (ret != DDI_SUCCESS || navail < min) {
825b9d3151SSukumar Swaminathan 		oce_log(dev, CE_WARN, MOD_CONFIG,
835b9d3151SSukumar Swaminathan 		    "Could not get msix vectors:0x%x",
845b9d3151SSukumar Swaminathan 		    navail);
855b9d3151SSukumar Swaminathan 		return (DDI_FAILURE);
868d738d7dSSukumar Swaminathan 	}
875b9d3151SSukumar Swaminathan 
885b9d3151SSukumar Swaminathan 	if (navail < min) {
895b9d3151SSukumar Swaminathan 		return (DDI_FAILURE);
904d0e5007SSukumar Swaminathan 	}
914d0e5007SSukumar Swaminathan 
925b9d3151SSukumar Swaminathan 	/* if the requested number is more than available reset reqd */
935b9d3151SSukumar Swaminathan 	if (navail < nreqd) {
945b9d3151SSukumar Swaminathan 		nreqd = navail;
955b9d3151SSukumar Swaminathan 	}
965b9d3151SSukumar Swaminathan 
975b9d3151SSukumar Swaminathan 	/* allocate htable */
985b9d3151SSukumar Swaminathan 	dev->hsize  = nreqd *  sizeof (ddi_intr_handle_t);
995b9d3151SSukumar Swaminathan 	dev->htable = kmem_zalloc(dev->hsize,  KM_NOSLEEP);
1005b9d3151SSukumar Swaminathan 
1015b9d3151SSukumar Swaminathan 	if (dev->htable == NULL)
1025b9d3151SSukumar Swaminathan 		return (DDI_FAILURE);
1035b9d3151SSukumar Swaminathan 
1045b9d3151SSukumar Swaminathan 	nallocd = 0;
1055b9d3151SSukumar Swaminathan 	/* allocate interrupt handlers */
1065b9d3151SSukumar Swaminathan 	ret = ddi_intr_alloc(dev->dip, dev->htable, dev->intr_type,
1075b9d3151SSukumar Swaminathan 	    0, nreqd, &nallocd, DDI_INTR_ALLOC_NORMAL);
1085b9d3151SSukumar Swaminathan 
1095b9d3151SSukumar Swaminathan 	if (ret != DDI_SUCCESS) {
1105b9d3151SSukumar Swaminathan 		goto fail_intr;
1115b9d3151SSukumar Swaminathan 	}
1125b9d3151SSukumar Swaminathan 
1135b9d3151SSukumar Swaminathan 	dev->num_vectors = nallocd;
1145b9d3151SSukumar Swaminathan 	if (nallocd < min) {
1155b9d3151SSukumar Swaminathan 		goto fail_intr;
1165b9d3151SSukumar Swaminathan 	}
1175b9d3151SSukumar Swaminathan 
1185b9d3151SSukumar Swaminathan 	/*
1195b9d3151SSukumar Swaminathan 	 * get the interrupt priority. Assumption is that all handlers have
1205b9d3151SSukumar Swaminathan 	 * equal priority
1215b9d3151SSukumar Swaminathan 	 */
1225b9d3151SSukumar Swaminathan 
1235b9d3151SSukumar Swaminathan 	ret = ddi_intr_get_pri(dev->htable[0], &dev->intr_pri);
1245b9d3151SSukumar Swaminathan 
1255b9d3151SSukumar Swaminathan 	if (ret != DDI_SUCCESS) {
1265b9d3151SSukumar Swaminathan 		goto fail_intr;
1275b9d3151SSukumar Swaminathan 	}
1285b9d3151SSukumar Swaminathan 
1295b9d3151SSukumar Swaminathan 	(void) ddi_intr_get_cap(dev->htable[0], &dev->intr_cap);
1305b9d3151SSukumar Swaminathan 
1315b9d3151SSukumar Swaminathan 	if ((intr_types & DDI_INTR_TYPE_MSIX) && (nallocd > 1)) {
1325b9d3151SSukumar Swaminathan 		dev->rx_rings = nallocd - 1;
1335b9d3151SSukumar Swaminathan 	} else {
1345b9d3151SSukumar Swaminathan 		dev->rx_rings = 1;
1355b9d3151SSukumar Swaminathan 	}
1365b9d3151SSukumar Swaminathan 
1375b9d3151SSukumar Swaminathan 	return (DDI_SUCCESS);
1385b9d3151SSukumar Swaminathan 
1395b9d3151SSukumar Swaminathan fail_intr:
1405b9d3151SSukumar Swaminathan 	(void) oce_teardown_intr(dev);
1415b9d3151SSukumar Swaminathan 	if ((dev->intr_type == DDI_INTR_TYPE_MSIX) &&
1425b9d3151SSukumar Swaminathan 	    (intr_types & DDI_INTR_TYPE_FIXED)) {
1435b9d3151SSukumar Swaminathan 		intr_types &= ~DDI_INTR_TYPE_MSIX;
1445b9d3151SSukumar Swaminathan 		oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
1455b9d3151SSukumar Swaminathan 		    "Could not get MSIX vectors, trying for FIXED vectors");
1465b9d3151SSukumar Swaminathan 		goto retry_intr;
1475b9d3151SSukumar Swaminathan 	}
1484d0e5007SSukumar Swaminathan 	return (DDI_FAILURE);
1494d0e5007SSukumar Swaminathan }
1504d0e5007SSukumar Swaminathan 
1514d0e5007SSukumar Swaminathan /*
1524d0e5007SSukumar Swaminathan  * top level function to undo initialization in oce_setup_intr
1534d0e5007SSukumar Swaminathan  *
1544d0e5007SSukumar Swaminathan  * dev - software handle to the device
1554d0e5007SSukumar Swaminathan  *
1564d0e5007SSukumar Swaminathan  * return DDI_SUCCESS => success, failure otherwise
1574d0e5007SSukumar Swaminathan  */
1584d0e5007SSukumar Swaminathan int
oce_teardown_intr(struct oce_dev * dev)1594d0e5007SSukumar Swaminathan oce_teardown_intr(struct oce_dev *dev)
1604d0e5007SSukumar Swaminathan {
1615b9d3151SSukumar Swaminathan 	int i;
1624d0e5007SSukumar Swaminathan 
1635b9d3151SSukumar Swaminathan 	/* release handlers */
1645b9d3151SSukumar Swaminathan 	for (i = 0; i < dev->num_vectors; i++) {
1655b9d3151SSukumar Swaminathan 		(void) ddi_intr_free(dev->htable[i]);
1664d0e5007SSukumar Swaminathan 	}
1674d0e5007SSukumar Swaminathan 
1685b9d3151SSukumar Swaminathan 	/* release htable */
1695b9d3151SSukumar Swaminathan 	kmem_free(dev->htable, dev->hsize);
1705b9d3151SSukumar Swaminathan 	dev->htable = NULL;
1715b9d3151SSukumar Swaminathan 
1725b9d3151SSukumar Swaminathan 	return (DDI_SUCCESS);
1734d0e5007SSukumar Swaminathan }
1744d0e5007SSukumar Swaminathan 
1754d0e5007SSukumar Swaminathan /*
1764d0e5007SSukumar Swaminathan  * helper function to add ISR based on interrupt type
1774d0e5007SSukumar Swaminathan  *
1784d0e5007SSukumar Swaminathan  * dev - software handle to the device
1794d0e5007SSukumar Swaminathan  *
1804d0e5007SSukumar Swaminathan  * return DDI_SUCCESS => success, failure otherwise
1814d0e5007SSukumar Swaminathan  */
1824d0e5007SSukumar Swaminathan int
oce_setup_handlers(struct oce_dev * dev)1834d0e5007SSukumar Swaminathan oce_setup_handlers(struct oce_dev *dev)
1844d0e5007SSukumar Swaminathan {
1855b9d3151SSukumar Swaminathan 	int i = 0;
1865b9d3151SSukumar Swaminathan 	int ret;
1875b9d3151SSukumar Swaminathan 	for (i = 0; i < dev->num_vectors; i++) {
1885b9d3151SSukumar Swaminathan 		ret = ddi_intr_add_handler(dev->htable[i], oce_isr,
1895b9d3151SSukumar Swaminathan 		    (caddr_t)dev->eq[i], NULL);
1905b9d3151SSukumar Swaminathan 		if (ret != DDI_SUCCESS) {
1915b9d3151SSukumar Swaminathan 			oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
1925b9d3151SSukumar Swaminathan 			    "Failed to add interrupt handlers");
1935b9d3151SSukumar Swaminathan 			for (i--; i >= 0; i--) {
1945b9d3151SSukumar Swaminathan 				(void) ddi_intr_remove_handler(dev->htable[i]);
1955b9d3151SSukumar Swaminathan 			}
1965b9d3151SSukumar Swaminathan 			return (DDI_FAILURE);
1975b9d3151SSukumar Swaminathan 		}
1984d0e5007SSukumar Swaminathan 	}
1995b9d3151SSukumar Swaminathan 	return (DDI_SUCCESS);
2004d0e5007SSukumar Swaminathan }
2014d0e5007SSukumar Swaminathan 
2024d0e5007SSukumar Swaminathan /*
2034d0e5007SSukumar Swaminathan  * helper function to remove ISRs added in oce_setup_handlers
2044d0e5007SSukumar Swaminathan  *
2054d0e5007SSukumar Swaminathan  * dev - software handle to the device
2064d0e5007SSukumar Swaminathan  *
2074d0e5007SSukumar Swaminathan  * return DDI_SUCCESS => success, failure otherwise
2084d0e5007SSukumar Swaminathan  */
2094d0e5007SSukumar Swaminathan void
oce_remove_handler(struct oce_dev * dev)2104d0e5007SSukumar Swaminathan oce_remove_handler(struct oce_dev *dev)
2114d0e5007SSukumar Swaminathan {
2125b9d3151SSukumar Swaminathan 	int nvec;
2135b9d3151SSukumar Swaminathan 	for (nvec = 0; nvec < dev->num_vectors; nvec++) {
2145b9d3151SSukumar Swaminathan 		(void) ddi_intr_remove_handler(dev->htable[nvec]);
2154d0e5007SSukumar Swaminathan 	}
2164d0e5007SSukumar Swaminathan }
2174d0e5007SSukumar Swaminathan 
2184d0e5007SSukumar Swaminathan void
oce_chip_ei(struct oce_dev * dev)2194d0e5007SSukumar Swaminathan oce_chip_ei(struct oce_dev *dev)
2204d0e5007SSukumar Swaminathan {
2214d0e5007SSukumar Swaminathan 	uint32_t reg;
2224d0e5007SSukumar Swaminathan 
2234d0e5007SSukumar Swaminathan 	reg =  OCE_CFG_READ32(dev, PCICFG_INTR_CTRL);
2244d0e5007SSukumar Swaminathan 	reg |= HOSTINTR_MASK;
2254d0e5007SSukumar Swaminathan 	OCE_CFG_WRITE32(dev, PCICFG_INTR_CTRL, reg);
2264d0e5007SSukumar Swaminathan }
2274d0e5007SSukumar Swaminathan 
2284d0e5007SSukumar Swaminathan /*
2294d0e5007SSukumar Swaminathan  * function to enable interrupts
2304d0e5007SSukumar Swaminathan  *
2314d0e5007SSukumar Swaminathan  * dev - software handle to the device
2324d0e5007SSukumar Swaminathan  *
2334d0e5007SSukumar Swaminathan  * return DDI_SUCCESS => success, failure otherwise
2344d0e5007SSukumar Swaminathan  */
2354d0e5007SSukumar Swaminathan void
oce_ei(struct oce_dev * dev)2364d0e5007SSukumar Swaminathan oce_ei(struct oce_dev *dev)
2374d0e5007SSukumar Swaminathan {
2384d0e5007SSukumar Swaminathan 	int i;
2394d0e5007SSukumar Swaminathan 	int ret;
2404d0e5007SSukumar Swaminathan 
2414d0e5007SSukumar Swaminathan 	if (dev->intr_cap & DDI_INTR_FLAG_BLOCK) {
2424d0e5007SSukumar Swaminathan 		(void) ddi_intr_block_enable(dev->htable, dev->num_vectors);
2434d0e5007SSukumar Swaminathan 	} else {
2444d0e5007SSukumar Swaminathan 
2454d0e5007SSukumar Swaminathan 		for (i = 0; i < dev->num_vectors; i++) {
2464d0e5007SSukumar Swaminathan 			ret = ddi_intr_enable(dev->htable[i]);
2474d0e5007SSukumar Swaminathan 			if (ret != DDI_SUCCESS) {
2484d0e5007SSukumar Swaminathan 				for (i--; i >= 0; i--) {
2494d0e5007SSukumar Swaminathan 					(void) ddi_intr_disable(dev->htable[i]);
2504d0e5007SSukumar Swaminathan 				}
2514d0e5007SSukumar Swaminathan 			}
2524d0e5007SSukumar Swaminathan 		}
2534d0e5007SSukumar Swaminathan 	}
2544d0e5007SSukumar Swaminathan 	oce_chip_ei(dev);
2554d0e5007SSukumar Swaminathan } /* oce_ei */
2564d0e5007SSukumar Swaminathan 
2574d0e5007SSukumar Swaminathan void
oce_chip_di(struct oce_dev * dev)2584d0e5007SSukumar Swaminathan oce_chip_di(struct oce_dev *dev)
2594d0e5007SSukumar Swaminathan {
2604d0e5007SSukumar Swaminathan 	uint32_t reg;
2614d0e5007SSukumar Swaminathan 
2624d0e5007SSukumar Swaminathan 	reg =  OCE_CFG_READ32(dev, PCICFG_INTR_CTRL);
2634d0e5007SSukumar Swaminathan 	reg &= ~HOSTINTR_MASK;
2644d0e5007SSukumar Swaminathan 	OCE_CFG_WRITE32(dev, PCICFG_INTR_CTRL, reg);
2654d0e5007SSukumar Swaminathan }
2664d0e5007SSukumar Swaminathan 
2674d0e5007SSukumar Swaminathan /*
2684d0e5007SSukumar Swaminathan  * function to disable interrupts
2694d0e5007SSukumar Swaminathan  *
2704d0e5007SSukumar Swaminathan  * dev - software handle to the device
2714d0e5007SSukumar Swaminathan  *
2724d0e5007SSukumar Swaminathan  * return DDI_SUCCESS => success, failure otherwise
2734d0e5007SSukumar Swaminathan  */
2744d0e5007SSukumar Swaminathan void
oce_di(struct oce_dev * dev)2754d0e5007SSukumar Swaminathan oce_di(struct oce_dev *dev)
2764d0e5007SSukumar Swaminathan {
2774d0e5007SSukumar Swaminathan 	int i;
2784d0e5007SSukumar Swaminathan 	int ret;
2794d0e5007SSukumar Swaminathan 
2805b9d3151SSukumar Swaminathan 	oce_chip_di(dev);
2814d0e5007SSukumar Swaminathan 	if (dev->intr_cap & DDI_INTR_FLAG_BLOCK) {
2824d0e5007SSukumar Swaminathan 		(void) ddi_intr_block_disable(dev->htable, dev->num_vectors);
2834d0e5007SSukumar Swaminathan 	} else {
2844d0e5007SSukumar Swaminathan 		for (i = 0; i < dev->num_vectors; i++) {
2854d0e5007SSukumar Swaminathan 			ret = ddi_intr_disable(dev->htable[i]);
2864d0e5007SSukumar Swaminathan 			if (ret != DDI_SUCCESS) {
2874d0e5007SSukumar Swaminathan 				oce_log(dev, CE_WARN, MOD_CONFIG,
2884d0e5007SSukumar Swaminathan 				    "Failed to disable interrupts 0x%x", ret);
2894d0e5007SSukumar Swaminathan 			}
2904d0e5007SSukumar Swaminathan 		}
2914d0e5007SSukumar Swaminathan 	}
292*3abb112fSGarrett D'Amore 
2934d0e5007SSukumar Swaminathan } /* oce_di */
2944d0e5007SSukumar Swaminathan 
2954d0e5007SSukumar Swaminathan /*
2964d0e5007SSukumar Swaminathan  * command interrupt handler routine added to all vectors
2974d0e5007SSukumar Swaminathan  *
2984d0e5007SSukumar Swaminathan  * arg1 = callback data
2994d0e5007SSukumar Swaminathan  * arg2 - callback data
3004d0e5007SSukumar Swaminathan  *
3014d0e5007SSukumar Swaminathan  * return DDI_INTR_CLAIMED => interrupt was claimed by the ISR
3024d0e5007SSukumar Swaminathan  */
3034d0e5007SSukumar Swaminathan static uint_t
oce_isr(caddr_t arg1,caddr_t arg2)3044d0e5007SSukumar Swaminathan oce_isr(caddr_t arg1, caddr_t arg2)
3054d0e5007SSukumar Swaminathan {
3064d0e5007SSukumar Swaminathan 	struct oce_eq *eq;
3074d0e5007SSukumar Swaminathan 	struct oce_eqe *eqe;
3084d0e5007SSukumar Swaminathan 	uint16_t num_eqe = 0;
3094d0e5007SSukumar Swaminathan 	uint16_t cq_id;
3104d0e5007SSukumar Swaminathan 	struct oce_cq *cq;
3114d0e5007SSukumar Swaminathan 	struct oce_dev  *dev;
3124d0e5007SSukumar Swaminathan 
3134d0e5007SSukumar Swaminathan 	_NOTE(ARGUNUSED(arg2));
3144d0e5007SSukumar Swaminathan 
3154d0e5007SSukumar Swaminathan 	eq = (struct oce_eq *)(void *)(arg1);
3164d0e5007SSukumar Swaminathan 
3174d0e5007SSukumar Swaminathan 	dev = eq->parent;
3184d0e5007SSukumar Swaminathan 
3194d0e5007SSukumar Swaminathan 	eqe = RING_GET_CONSUMER_ITEM_VA(eq->ring, struct oce_eqe);
3204d0e5007SSukumar Swaminathan 
3214d0e5007SSukumar Swaminathan 	while (eqe->u0.dw0) {
3224d0e5007SSukumar Swaminathan 
3234d0e5007SSukumar Swaminathan 		eqe->u0.dw0 = LE_32(eqe->u0.dw0);
3244d0e5007SSukumar Swaminathan 
3254d0e5007SSukumar Swaminathan 		/* if not CQ then continue else flag an error */
3264d0e5007SSukumar Swaminathan 		if (EQ_MAJOR_CODE_COMPLETION != eqe->u0.s.major_code) {
3274d0e5007SSukumar Swaminathan 			oce_log(dev, CE_WARN, MOD_ISR,
3284d0e5007SSukumar Swaminathan 			    "NOT a CQ event. 0x%x",
3294d0e5007SSukumar Swaminathan 			    eqe->u0.s.major_code);
3304d0e5007SSukumar Swaminathan 		}
3314d0e5007SSukumar Swaminathan 
3324d0e5007SSukumar Swaminathan 		/* get the cq from the eqe */
3335b9d3151SSukumar Swaminathan 		cq_id = eqe->u0.s.resource_id % OCE_MAX_CQ;
3344d0e5007SSukumar Swaminathan 		cq = dev->cq[cq_id];
3354d0e5007SSukumar Swaminathan 
3364d0e5007SSukumar Swaminathan 		/* Call the completion handler */
3374d0e5007SSukumar Swaminathan 		(void) cq->cq_handler(cq->cb_arg);
3384d0e5007SSukumar Swaminathan 
3394d0e5007SSukumar Swaminathan 		/* clear valid bit and progress eqe */
3404d0e5007SSukumar Swaminathan 		eqe->u0.dw0 = 0;
3414d0e5007SSukumar Swaminathan 		RING_GET(eq->ring, 1);
3424d0e5007SSukumar Swaminathan 		eqe = RING_GET_CONSUMER_ITEM_VA(eq->ring, struct oce_eqe);
3434d0e5007SSukumar Swaminathan 		num_eqe++;
3444d0e5007SSukumar Swaminathan 	} /* for all EQEs */
3454d0e5007SSukumar Swaminathan 
3464d0e5007SSukumar Swaminathan 	/* ring the eq doorbell, signify that it's done processing  */
3475b9d3151SSukumar Swaminathan 	oce_arm_eq(dev, eq->eq_id, num_eqe, B_TRUE, B_TRUE);
3484d0e5007SSukumar Swaminathan 	if (num_eqe > 0) {
3494d0e5007SSukumar Swaminathan 		return (DDI_INTR_CLAIMED);
3504d0e5007SSukumar Swaminathan 	} else {
3514d0e5007SSukumar Swaminathan 		return (DDI_INTR_UNCLAIMED);
3524d0e5007SSukumar Swaminathan 	}
3534d0e5007SSukumar Swaminathan } /* oce_msix_handler */
354