xref: /illumos-gate/usr/src/uts/common/io/bnxe/bnxe_intr.c (revision 55fea89d)
1d14abf15SRobert Mustacchi /*
2d14abf15SRobert Mustacchi  * CDDL HEADER START
3d14abf15SRobert Mustacchi  *
4d14abf15SRobert Mustacchi  * The contents of this file are subject to the terms of the
5d14abf15SRobert Mustacchi  * Common Development and Distribution License (the "License").
6d14abf15SRobert Mustacchi  * You may not use this file except in compliance with the License.
7d14abf15SRobert Mustacchi  *
8d14abf15SRobert Mustacchi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d14abf15SRobert Mustacchi  * or http://www.opensolaris.org/os/licensing.
10d14abf15SRobert Mustacchi  * See the License for the specific language governing permissions
11d14abf15SRobert Mustacchi  * and limitations under the License.
12d14abf15SRobert Mustacchi  *
13d14abf15SRobert Mustacchi  * When distributing Covered Code, include this CDDL HEADER in each
14d14abf15SRobert Mustacchi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d14abf15SRobert Mustacchi  * If applicable, add the following below this CDDL HEADER, with the
16d14abf15SRobert Mustacchi  * fields enclosed by brackets "[]" replaced with your own identifying
17d14abf15SRobert Mustacchi  * information: Portions Copyright [yyyy] [name of copyright owner]
18d14abf15SRobert Mustacchi  *
19d14abf15SRobert Mustacchi  * CDDL HEADER END
20d14abf15SRobert Mustacchi  */
21d14abf15SRobert Mustacchi 
22d14abf15SRobert Mustacchi /*
23d14abf15SRobert Mustacchi  * Copyright 2014 QLogic Corporation
24d14abf15SRobert Mustacchi  * The contents of this file are subject to the terms of the
25d14abf15SRobert Mustacchi  * QLogic End User License (the "License").
26d14abf15SRobert Mustacchi  * You may not use this file except in compliance with the License.
27d14abf15SRobert Mustacchi  *
28d14abf15SRobert Mustacchi  * You can obtain a copy of the License at
29d14abf15SRobert Mustacchi  * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/
30d14abf15SRobert Mustacchi  * QLogic_End_User_Software_License.txt
31d14abf15SRobert Mustacchi  * See the License for the specific language governing permissions
32d14abf15SRobert Mustacchi  * and limitations under the License.
33d14abf15SRobert Mustacchi  */
34d14abf15SRobert Mustacchi 
35d14abf15SRobert Mustacchi /*
36d14abf15SRobert Mustacchi  * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
37d14abf15SRobert Mustacchi  */
38d14abf15SRobert Mustacchi 
39d14abf15SRobert Mustacchi #include "bnxe.h"
40d14abf15SRobert Mustacchi 
41d14abf15SRobert Mustacchi /*
42d14abf15SRobert Mustacchi  * The interrupt status bit vector is as follows:
43d14abf15SRobert Mustacchi  *
44d14abf15SRobert Mustacchi  *   bit 0: default interrupt
45d14abf15SRobert Mustacchi  *
46d14abf15SRobert Mustacchi  * Single Mode:
47d14abf15SRobert Mustacchi  *
48d14abf15SRobert Mustacchi  *   bits 1-16:  Function 1 (RSS 0-15)
49d14abf15SRobert Mustacchi  *
50d14abf15SRobert Mustacchi  * Multi-Function Mode:
51d14abf15SRobert Mustacchi  *
52d14abf15SRobert Mustacchi  *   bits 1-4:   Virtual Function 1 (RSS 0-3)
53d14abf15SRobert Mustacchi  *   bits 5-8:   Virtual Function 2 (RSS 4-7)
54d14abf15SRobert Mustacchi  *   bits 9-12:  Virtual Function 3 (RSS 8-11)
55d14abf15SRobert Mustacchi  *   bits 13-16: Virtual Function 4 (RSS 12-15)
56d14abf15SRobert Mustacchi  *
57d14abf15SRobert Mustacchi  * While processing interrupts the programmatic index used for the default
58d14abf15SRobert Mustacchi  * status block is 16 and the RSS status blocks are shifted down one (i.e.
59d14abf15SRobert Mustacchi  * 0-15).
60d14abf15SRobert Mustacchi  *
61d14abf15SRobert Mustacchi  * Solaris defaults to 2 MSIX interrupts per function so only the default
62d14abf15SRobert Mustacchi  * interrupt plus one RSS interrupt is used.  This default behavior can be
63d14abf15SRobert Mustacchi  * modified via the /etc/system configuration file.
64d14abf15SRobert Mustacchi  */
65d14abf15SRobert Mustacchi 
66d14abf15SRobert Mustacchi 
BnxeIntrTypeName(int intrType)67d14abf15SRobert Mustacchi static inline char * BnxeIntrTypeName(int intrType)
68d14abf15SRobert Mustacchi {
69d14abf15SRobert Mustacchi     return (intrType == DDI_INTR_TYPE_MSIX)  ? "MSIX"  :
70d14abf15SRobert Mustacchi            (intrType == DDI_INTR_TYPE_MSI)   ? "MSI"   :
71d14abf15SRobert Mustacchi            (intrType == DDI_INTR_TYPE_FIXED) ? "FIXED" :
72d14abf15SRobert Mustacchi                                                "UNKNOWN";
73d14abf15SRobert Mustacchi }
74d14abf15SRobert Mustacchi 
75d14abf15SRobert Mustacchi 
BnxeFindDmaHandles(um_device_t * pUM)76d14abf15SRobert Mustacchi static void BnxeFindDmaHandles(um_device_t * pUM)
77d14abf15SRobert Mustacchi {
78d14abf15SRobert Mustacchi     lm_address_t physAddr;
79d14abf15SRobert Mustacchi     BnxeMemDma * pTmp;
80d14abf15SRobert Mustacchi     u32_t idx;
81d14abf15SRobert Mustacchi 
82d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_MEM(pUM);
83d14abf15SRobert Mustacchi 
84d14abf15SRobert Mustacchi     /* find the RSS status blocks */
85d14abf15SRobert Mustacchi 
86d14abf15SRobert Mustacchi     LM_FOREACH_SB_ID(&pUM->lm_dev, idx)
87d14abf15SRobert Mustacchi     {
88d14abf15SRobert Mustacchi         if (CHIP_IS_E1x(&pUM->lm_dev))
89d14abf15SRobert Mustacchi         {
90d14abf15SRobert Mustacchi             physAddr.as_u32.low =
91d14abf15SRobert Mustacchi                 pUM->lm_dev.vars.status_blocks_arr[idx].hc_status_block_data.e1x_sb_data.common.host_sb_addr.lo;
92d14abf15SRobert Mustacchi             physAddr.as_u32.high =
93d14abf15SRobert Mustacchi                 pUM->lm_dev.vars.status_blocks_arr[idx].hc_status_block_data.e1x_sb_data.common.host_sb_addr.hi;
94d14abf15SRobert Mustacchi         }
95d14abf15SRobert Mustacchi         else
96d14abf15SRobert Mustacchi         {
97d14abf15SRobert Mustacchi             physAddr.as_u32.low =
98d14abf15SRobert Mustacchi                 pUM->lm_dev.vars.status_blocks_arr[idx].hc_status_block_data.e2_sb_data.common.host_sb_addr.lo;
99d14abf15SRobert Mustacchi             physAddr.as_u32.high =
100d14abf15SRobert Mustacchi                 pUM->lm_dev.vars.status_blocks_arr[idx].hc_status_block_data.e2_sb_data.common.host_sb_addr.hi;
101d14abf15SRobert Mustacchi         }
102d14abf15SRobert Mustacchi 
103d14abf15SRobert Mustacchi         pTmp = (BnxeMemDma *)d_list_peek_head(&pUM->memDmaList);
104d14abf15SRobert Mustacchi         while (pTmp)
105d14abf15SRobert Mustacchi         {
106d14abf15SRobert Mustacchi             if (pTmp->physAddr.as_ptr == physAddr.as_ptr)
107d14abf15SRobert Mustacchi             {
108d14abf15SRobert Mustacchi                 break;
109d14abf15SRobert Mustacchi             }
110d14abf15SRobert Mustacchi 
111d14abf15SRobert Mustacchi             pTmp = (BnxeMemDma *)d_list_next_entry(&pTmp->link);
112d14abf15SRobert Mustacchi         }
113d14abf15SRobert Mustacchi 
114d14abf15SRobert Mustacchi         if (pTmp == NULL)
115d14abf15SRobert Mustacchi         {
116d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Failed to find DMA handle for RSS status block %d", idx);
117d14abf15SRobert Mustacchi         }
118d14abf15SRobert Mustacchi 
119d14abf15SRobert Mustacchi         pUM->statusBlocks[idx] = pTmp;
120d14abf15SRobert Mustacchi     }
121d14abf15SRobert Mustacchi 
122d14abf15SRobert Mustacchi     /* find the default status block */
123d14abf15SRobert Mustacchi 
124d14abf15SRobert Mustacchi     pTmp = (BnxeMemDma *)d_list_peek_head(&pUM->memDmaList);
125d14abf15SRobert Mustacchi     while (pTmp)
126d14abf15SRobert Mustacchi     {
127d14abf15SRobert Mustacchi         if (pTmp->physAddr.as_ptr ==
128d14abf15SRobert Mustacchi             pUM->lm_dev.vars.gen_sp_status_block.blk_phy_address.as_ptr)
129d14abf15SRobert Mustacchi         {
130d14abf15SRobert Mustacchi             break;
131d14abf15SRobert Mustacchi         }
132d14abf15SRobert Mustacchi 
133d14abf15SRobert Mustacchi         pTmp = (BnxeMemDma *)d_list_next_entry(&pTmp->link);
134d14abf15SRobert Mustacchi     }
135d14abf15SRobert Mustacchi 
136d14abf15SRobert Mustacchi     if (pTmp == NULL)
137d14abf15SRobert Mustacchi     {
138d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to find DMA handle for default status block");
139d14abf15SRobert Mustacchi     }
140d14abf15SRobert Mustacchi 
141d14abf15SRobert Mustacchi     pUM->statusBlocks[DEF_STATUS_BLOCK_IGU_INDEX] = pTmp;
142d14abf15SRobert Mustacchi 
143d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_MEM(pUM);
144d14abf15SRobert Mustacchi }
145d14abf15SRobert Mustacchi 
146d14abf15SRobert Mustacchi 
BnxeIntrIguSbEnable(um_device_t * pUM,u32_t idx,boolean_t fromISR)147d14abf15SRobert Mustacchi void BnxeIntrIguSbEnable(um_device_t * pUM,
148d14abf15SRobert Mustacchi                          u32_t         idx,
149d14abf15SRobert Mustacchi                          boolean_t     fromISR)
150d14abf15SRobert Mustacchi {
151d14abf15SRobert Mustacchi     RxQueue * pRxQ = &pUM->rxq[idx];
152d14abf15SRobert Mustacchi     u32_t igu_id = (FCOE_CID(&pUM->lm_dev) == idx) ?
153d14abf15SRobert Mustacchi                        LM_NON_RSS_SB(&pUM->lm_dev) : idx;
154d14abf15SRobert Mustacchi 
155d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_INTR_FLIP(pUM, igu_id);
156d14abf15SRobert Mustacchi 
157d14abf15SRobert Mustacchi     if (fromISR)
158d14abf15SRobert Mustacchi     {
159d14abf15SRobert Mustacchi         /*
160d14abf15SRobert Mustacchi          * If in an ISR and poll mode is ON then poll mode was flipped in the
161d14abf15SRobert Mustacchi          * ISR which can occur during Rx processing.  If this is the case then
162d14abf15SRobert Mustacchi          * don't do anything.  Only re-enable the IGU when poll mode is OFF.
163d14abf15SRobert Mustacchi          */
164d14abf15SRobert Mustacchi         if (!pRxQ->inPollMode)
165d14abf15SRobert Mustacchi         {
166d14abf15SRobert Mustacchi             lm_int_ack_sb_enable(&pUM->lm_dev, igu_id);
167d14abf15SRobert Mustacchi         }
168d14abf15SRobert Mustacchi     }
169d14abf15SRobert Mustacchi     else
170d14abf15SRobert Mustacchi     {
171d14abf15SRobert Mustacchi         if (!pRxQ->inPollMode)
172d14abf15SRobert Mustacchi         {
173d14abf15SRobert Mustacchi             /* Why are intrs getting enabled on the ring twice...? */
174d14abf15SRobert Mustacchi             cmn_err(CE_PANIC,
175d14abf15SRobert Mustacchi                     "%s: Ring %d, enable intrs and NOT in poll mode!",
176d14abf15SRobert Mustacchi                     BnxeDevName(pUM), igu_id);
177d14abf15SRobert Mustacchi         }
178d14abf15SRobert Mustacchi 
179d14abf15SRobert Mustacchi         atomic_swap_32(&pRxQ->inPollMode, B_FALSE);
180d14abf15SRobert Mustacchi         pRxQ->intrEnableCnt++;
181d14abf15SRobert Mustacchi 
182d14abf15SRobert Mustacchi         lm_int_ack_sb_enable(&pUM->lm_dev, igu_id);
183d14abf15SRobert Mustacchi     }
184d14abf15SRobert Mustacchi 
185d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_INTR_FLIP(pUM, igu_id);
186d14abf15SRobert Mustacchi }
187d14abf15SRobert Mustacchi 
188d14abf15SRobert Mustacchi 
BnxeIntrIguSbDisable(um_device_t * pUM,u32_t idx,boolean_t fromISR)189d14abf15SRobert Mustacchi void BnxeIntrIguSbDisable(um_device_t * pUM,
190d14abf15SRobert Mustacchi                           u32_t         idx,
191d14abf15SRobert Mustacchi                           boolean_t     fromISR)
192d14abf15SRobert Mustacchi {
193d14abf15SRobert Mustacchi     RxQueue * pRxQ = &pUM->rxq[idx];
194d14abf15SRobert Mustacchi     u32_t igu_id = (FCOE_CID(&pUM->lm_dev) == idx) ?
195d14abf15SRobert Mustacchi                        LM_NON_RSS_SB(&pUM->lm_dev) : idx;
196d14abf15SRobert Mustacchi 
197d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_INTR_FLIP(pUM, igu_id);
198d14abf15SRobert Mustacchi 
199d14abf15SRobert Mustacchi     if (fromISR)
200d14abf15SRobert Mustacchi     {
201d14abf15SRobert Mustacchi         /* we should never get here when in poll mode... */
202d14abf15SRobert Mustacchi         ASSERT(pRxQ->inPollMode == B_FALSE);
203d14abf15SRobert Mustacchi         lm_int_ack_sb_disable(&pUM->lm_dev, igu_id);
204d14abf15SRobert Mustacchi     }
205d14abf15SRobert Mustacchi     else
206d14abf15SRobert Mustacchi     {
207d14abf15SRobert Mustacchi         if (pRxQ->inPollMode)
208d14abf15SRobert Mustacchi         {
209d14abf15SRobert Mustacchi             /* Why are intrs getting disabled on the ring twice...? */
210d14abf15SRobert Mustacchi             cmn_err(CE_PANIC,
211d14abf15SRobert Mustacchi                     "%s: Ring %d, disable intrs and ALREADY in poll mode!",
212d14abf15SRobert Mustacchi                     BnxeDevName(pUM), igu_id);
213d14abf15SRobert Mustacchi         }
214d14abf15SRobert Mustacchi 
215d14abf15SRobert Mustacchi         /*
216d14abf15SRobert Mustacchi          * Note here that the interrupt can already be disabled if GLDv3
217d14abf15SRobert Mustacchi          * is disabling the interrupt under the context of an ISR.  This is
218d14abf15SRobert Mustacchi          * OK as the inPollMode flag will tell the ISR not to re-enable the
219d14abf15SRobert Mustacchi          * interrupt upon return.
220d14abf15SRobert Mustacchi          */
221d14abf15SRobert Mustacchi 
222d14abf15SRobert Mustacchi         lm_int_ack_sb_disable(&pUM->lm_dev, igu_id);
223d14abf15SRobert Mustacchi 
224d14abf15SRobert Mustacchi         atomic_swap_32(&pRxQ->inPollMode, B_TRUE);
225d14abf15SRobert Mustacchi         pRxQ->intrDisableCnt++;
226d14abf15SRobert Mustacchi     }
227d14abf15SRobert Mustacchi 
228d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_INTR_FLIP(pUM, igu_id);
229d14abf15SRobert Mustacchi }
230d14abf15SRobert Mustacchi 
231d14abf15SRobert Mustacchi 
BnxeServiceDefSbIntr(um_device_t * pUM,boolean_t * pPktsRxed,boolean_t * pPktsTxed)232d14abf15SRobert Mustacchi static void BnxeServiceDefSbIntr(um_device_t * pUM,
233d14abf15SRobert Mustacchi                                  boolean_t *   pPktsRxed,
234d14abf15SRobert Mustacchi                                  boolean_t *   pPktsTxed)
235d14abf15SRobert Mustacchi {
236d14abf15SRobert Mustacchi     lm_device_t * pLM = (lm_device_t *)pUM;
237d14abf15SRobert Mustacchi     u32_t         activity_flg         = 0;
238d14abf15SRobert Mustacchi     u16_t         lcl_attn_bits        = 0;
239d14abf15SRobert Mustacchi     u16_t         lcl_attn_ack         = 0;
240d14abf15SRobert Mustacchi     u16_t         asserted_proc_grps   = 0;
241d14abf15SRobert Mustacchi     u16_t         deasserted_proc_grps = 0;
242d14abf15SRobert Mustacchi 
243d14abf15SRobert Mustacchi     *pPktsRxed = B_FALSE;
244d14abf15SRobert Mustacchi     *pPktsTxed = B_FALSE;
245d14abf15SRobert Mustacchi 
246d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "Default INTR: Handling default status block %d", DEF_STATUS_BLOCK_INDEX);
247d14abf15SRobert Mustacchi 
248d14abf15SRobert Mustacchi     ddi_dma_sync(pUM->statusBlocks[DEF_STATUS_BLOCK_IGU_INDEX]->dmaHandle,
249d14abf15SRobert Mustacchi                  0, 0, DDI_DMA_SYNC_FORKERNEL);
250d14abf15SRobert Mustacchi 
251d14abf15SRobert Mustacchi     if (pUM->fmCapabilities &&
252d14abf15SRobert Mustacchi         BnxeCheckDmaHandle(pUM->statusBlocks[DEF_STATUS_BLOCK_IGU_INDEX]->dmaHandle) != DDI_FM_OK)
253d14abf15SRobert Mustacchi     {
254d14abf15SRobert Mustacchi         ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
255d14abf15SRobert Mustacchi     }
256d14abf15SRobert Mustacchi 
257d14abf15SRobert Mustacchi     pUM->intrSbCnt[DEF_STATUS_BLOCK_IGU_INDEX]++;
258d14abf15SRobert Mustacchi 
259d14abf15SRobert Mustacchi     if (lm_is_def_sb_updated(pLM) == 0)
260d14abf15SRobert Mustacchi     {
261d14abf15SRobert Mustacchi         BnxeLogDbg(pUM, "Default INTR: No change in default status index so bail!");
262d14abf15SRobert Mustacchi         pUM->intrSbNoChangeCnt[DEF_STATUS_BLOCK_IGU_INDEX]++;
263d14abf15SRobert Mustacchi 
264d14abf15SRobert Mustacchi         if (pUM->fmCapabilities &&
265d14abf15SRobert Mustacchi             BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
266d14abf15SRobert Mustacchi         {
267d14abf15SRobert Mustacchi             ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
268d14abf15SRobert Mustacchi         }
269d14abf15SRobert Mustacchi 
270d14abf15SRobert Mustacchi         return;
271d14abf15SRobert Mustacchi     }
272d14abf15SRobert Mustacchi 
273d14abf15SRobert Mustacchi     /* get a local copy of the indices from the status block */
274d14abf15SRobert Mustacchi     lm_update_def_hc_indices(pLM, DEF_STATUS_BLOCK_INDEX, &activity_flg);
275d14abf15SRobert Mustacchi 
276d14abf15SRobert Mustacchi     BnxeDbgBreakIfFastPath(pUM, !(activity_flg & LM_DEF_EVENT_MASK));
277d14abf15SRobert Mustacchi 
278d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "Default INTR: processing events on sb: %x, events: 0x%x",
279d14abf15SRobert Mustacchi                DEF_STATUS_BLOCK_INDEX, activity_flg);
280d14abf15SRobert Mustacchi 
281d14abf15SRobert Mustacchi     if (activity_flg & LM_DEF_ATTN_ACTIVE)
282d14abf15SRobert Mustacchi     {
283d14abf15SRobert Mustacchi         /* Attentions! Usually these are bad things we don't want to see */
284d14abf15SRobert Mustacchi 
285d14abf15SRobert Mustacchi         lm_get_attn_info(pLM, &lcl_attn_bits, &lcl_attn_ack);
286d14abf15SRobert Mustacchi 
287d14abf15SRobert Mustacchi         // NOTE: in case the status index of the attention has changed
288d14abf15SRobert Mustacchi         // already (while processing), we could override with it our local
289d14abf15SRobert Mustacchi         // copy. However, this is not a must, since it will be caught at the
290d14abf15SRobert Mustacchi         // end of the loop with the call to lm_is_sb_updated(). In case the
291d14abf15SRobert Mustacchi         // dpc_loop_cnt has exhausted, no worry, since will get an interrupt
292d14abf15SRobert Mustacchi         // for that at a later time.
293d14abf15SRobert Mustacchi 
294d14abf15SRobert Mustacchi         // find out which lines are asserted/deasserted with account to
295d14abf15SRobert Mustacchi         // their states, ASSERT if necessary.
296d14abf15SRobert Mustacchi         GET_ATTN_CHNG_GROUPS(pLM, lcl_attn_bits, lcl_attn_ack,
297d14abf15SRobert Mustacchi                              &asserted_proc_grps, &deasserted_proc_grps);
298d14abf15SRobert Mustacchi 
299d14abf15SRobert Mustacchi         BnxeLogDbg(pUM, "Default INTR: asserted_proc_grps: 0x%x, deasserted_proc_grps:0x%x",
300d14abf15SRobert Mustacchi                    asserted_proc_grps, deasserted_proc_grps);
301d14abf15SRobert Mustacchi 
302d14abf15SRobert Mustacchi         if (asserted_proc_grps)
303d14abf15SRobert Mustacchi         {
304d14abf15SRobert Mustacchi             lm_handle_assertion_processing(pLM, asserted_proc_grps);
305d14abf15SRobert Mustacchi 
306d14abf15SRobert Mustacchi             if (pUM->fmCapabilities &&
307d14abf15SRobert Mustacchi                 BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
308d14abf15SRobert Mustacchi             {
309d14abf15SRobert Mustacchi                 ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
310d14abf15SRobert Mustacchi             }
311d14abf15SRobert Mustacchi         }
312d14abf15SRobert Mustacchi 
313d14abf15SRobert Mustacchi         // keep in mind that in the same round, it is possible that this
314d14abf15SRobert Mustacchi         // func will have processing to do regarding deassertion on bits
315d14abf15SRobert Mustacchi         // that are different than the ones processed earlier for assertion
316d14abf15SRobert Mustacchi         // processing.
317d14abf15SRobert Mustacchi 
318d14abf15SRobert Mustacchi         if (deasserted_proc_grps)
319d14abf15SRobert Mustacchi         {
320d14abf15SRobert Mustacchi             lm_handle_deassertion_processing(pLM, deasserted_proc_grps);
321d14abf15SRobert Mustacchi 
322d14abf15SRobert Mustacchi             if (pUM->fmCapabilities &&
323d14abf15SRobert Mustacchi                 BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
324d14abf15SRobert Mustacchi             {
325d14abf15SRobert Mustacchi                 ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
326d14abf15SRobert Mustacchi             }
327d14abf15SRobert Mustacchi         }
328d14abf15SRobert Mustacchi     }
329d14abf15SRobert Mustacchi 
330d14abf15SRobert Mustacchi     if (activity_flg & LM_DEF_USTORM_ACTIVE)
331d14abf15SRobert Mustacchi     {
332d14abf15SRobert Mustacchi         /* Check for L4 TOE/iSCSI/FCoE Rx completions. */
333d14abf15SRobert Mustacchi 
334*55fea89dSDan Cross         if (lm_is_rx_completion(pLM, ISCSI_CID(pLM)))
335d14abf15SRobert Mustacchi         {
336d14abf15SRobert Mustacchi             BnxeDbgBreakMsg(pUM, "Unknown iSCSI Rx completion!");
337d14abf15SRobert Mustacchi         }
338d14abf15SRobert Mustacchi 
339*55fea89dSDan Cross         if (lm_is_rx_completion(pLM, FCOE_CID(pLM)))
340d14abf15SRobert Mustacchi         {
341d14abf15SRobert Mustacchi             *pPktsRxed = B_TRUE;
342d14abf15SRobert Mustacchi         }
343d14abf15SRobert Mustacchi     }
344d14abf15SRobert Mustacchi 
345d14abf15SRobert Mustacchi     if (activity_flg & LM_DEF_CSTORM_ACTIVE)
346d14abf15SRobert Mustacchi     {
347d14abf15SRobert Mustacchi         if (lm_is_eq_completion(pLM))
348d14abf15SRobert Mustacchi         {
349d14abf15SRobert Mustacchi             lm_service_eq_intr(pLM);
350d14abf15SRobert Mustacchi         }
351d14abf15SRobert Mustacchi 
352d14abf15SRobert Mustacchi         if (lm_is_tx_completion(pLM, FWD_CID(pLM)))
353d14abf15SRobert Mustacchi         {
354d14abf15SRobert Mustacchi             /* XXX Possible? */
355d14abf15SRobert Mustacchi             *pPktsTxed = B_TRUE;
356d14abf15SRobert Mustacchi         }
357d14abf15SRobert Mustacchi 
358d14abf15SRobert Mustacchi         if (lm_is_tx_completion(pLM, ISCSI_CID(pLM)))
359d14abf15SRobert Mustacchi         {
360d14abf15SRobert Mustacchi             /* XXX iSCSI Tx. NO! */
361d14abf15SRobert Mustacchi             BnxeDbgBreakMsg(pUM, "Unknown iSCSI Tx completion!");
362d14abf15SRobert Mustacchi         }
363d14abf15SRobert Mustacchi 
364d14abf15SRobert Mustacchi         if (lm_is_tx_completion(pLM, FCOE_CID(pLM)))
365d14abf15SRobert Mustacchi         {
366d14abf15SRobert Mustacchi             *pPktsTxed = B_TRUE;
367d14abf15SRobert Mustacchi         }
368d14abf15SRobert Mustacchi     }
369d14abf15SRobert Mustacchi }
370d14abf15SRobert Mustacchi 
371d14abf15SRobert Mustacchi 
372d14abf15SRobert Mustacchi /*
373d14abf15SRobert Mustacchi  * This is the polling path for an individual Rx Ring.  Here we simply pull
374d14abf15SRobert Mustacchi  * any pending packets out of the hardware and put them into the wait queue.
375d14abf15SRobert Mustacchi  * Note that there might already be packets in the wait queue which is OK as
376d14abf15SRobert Mustacchi  * the caller will call BnxeRxRingProcess() next to process the queue.
377d14abf15SRobert Mustacchi  */
BnxePollRxRing(um_device_t * pUM,u32_t idx,boolean_t * pPktsRxed,boolean_t * pPktsTxed)378d14abf15SRobert Mustacchi void BnxePollRxRing(um_device_t * pUM,
379d14abf15SRobert Mustacchi                     u32_t         idx,
380d14abf15SRobert Mustacchi                     boolean_t *   pPktsRxed,
381d14abf15SRobert Mustacchi                     boolean_t *   pPktsTxed)
382d14abf15SRobert Mustacchi {
383d14abf15SRobert Mustacchi     lm_device_t * pLM = (lm_device_t *)pUM;
384d14abf15SRobert Mustacchi     u32_t         activity_flg = 0;
385d14abf15SRobert Mustacchi     u8_t          drv_rss_id = (u8_t)idx;
386d14abf15SRobert Mustacchi 
387d14abf15SRobert Mustacchi     *pPktsRxed = B_FALSE;
388d14abf15SRobert Mustacchi     *pPktsTxed = B_FALSE;
389d14abf15SRobert Mustacchi 
390d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "Ring Poll: Handling status block sb_id:%d drv_rss_id:%d",
391d14abf15SRobert Mustacchi                idx, drv_rss_id);
392d14abf15SRobert Mustacchi 
393d14abf15SRobert Mustacchi     /* use drv_rss_id for mapping into status block array (from LM) */
394d14abf15SRobert Mustacchi     ddi_dma_sync(pUM->statusBlocks[drv_rss_id]->dmaHandle,
395d14abf15SRobert Mustacchi                  0, 0, DDI_DMA_SYNC_FORKERNEL);
396d14abf15SRobert Mustacchi 
397d14abf15SRobert Mustacchi     if (pUM->fmCapabilities &&
398d14abf15SRobert Mustacchi         BnxeCheckDmaHandle(pUM->statusBlocks[drv_rss_id]->dmaHandle) != DDI_FM_OK)
399d14abf15SRobert Mustacchi     {
400d14abf15SRobert Mustacchi         ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
401d14abf15SRobert Mustacchi     }
402d14abf15SRobert Mustacchi 
403d14abf15SRobert Mustacchi     pUM->intrSbPollCnt[drv_rss_id]++;
404d14abf15SRobert Mustacchi 
405d14abf15SRobert Mustacchi     if (lm_is_sb_updated(pLM, drv_rss_id) == 0)
406d14abf15SRobert Mustacchi     {
407d14abf15SRobert Mustacchi         BnxeLogDbg(pUM, "Ring Poll: No change in status index so bail!");
408d14abf15SRobert Mustacchi         pUM->intrSbPollNoChangeCnt[drv_rss_id]++;
409d14abf15SRobert Mustacchi         return;
410d14abf15SRobert Mustacchi     }
411d14abf15SRobert Mustacchi 
412d14abf15SRobert Mustacchi     /* get a local copy of the indices from the status block */
413d14abf15SRobert Mustacchi     lm_update_fp_hc_indices(pLM, drv_rss_id, &activity_flg, &drv_rss_id);
414d14abf15SRobert Mustacchi 
415d14abf15SRobert Mustacchi     BnxeDbgBreakIf(pUM, !(activity_flg & LM_NON_DEF_EVENT_MASK));
416d14abf15SRobert Mustacchi 
417d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "Ring Poll: processing events on sb: %x, events: 0x%x",
418d14abf15SRobert Mustacchi                drv_rss_id, activity_flg);
419d14abf15SRobert Mustacchi 
420d14abf15SRobert Mustacchi     if (activity_flg & LM_NON_DEF_USTORM_ACTIVE)
421d14abf15SRobert Mustacchi     {
422d14abf15SRobert Mustacchi         /* Rx Completions */
423d14abf15SRobert Mustacchi         if (lm_is_rx_completion(pLM, drv_rss_id))
424d14abf15SRobert Mustacchi         {
425d14abf15SRobert Mustacchi             *pPktsRxed = B_TRUE;
426d14abf15SRobert Mustacchi         }
427d14abf15SRobert Mustacchi 
428d14abf15SRobert Mustacchi         /* XXX Check for L4 TOE/FCoE Rx completions. NO! */
429d14abf15SRobert Mustacchi     }
430d14abf15SRobert Mustacchi 
431d14abf15SRobert Mustacchi     if (activity_flg & LM_NON_DEF_CSTORM_ACTIVE)
432d14abf15SRobert Mustacchi     {
433d14abf15SRobert Mustacchi         /* Tx completions */
434d14abf15SRobert Mustacchi         if (lm_is_tx_completion(pLM, drv_rss_id))
435d14abf15SRobert Mustacchi         {
436d14abf15SRobert Mustacchi             *pPktsTxed = B_TRUE;
437d14abf15SRobert Mustacchi         }
438d14abf15SRobert Mustacchi 
439d14abf15SRobert Mustacchi         /* XXX Check for L4 Tx and L5 EQ completions. NO! */
440d14abf15SRobert Mustacchi     }
441d14abf15SRobert Mustacchi }
442d14abf15SRobert Mustacchi 
443d14abf15SRobert Mustacchi 
444d14abf15SRobert Mustacchi /*
445d14abf15SRobert Mustacchi  * This is the polling path for the FCoE Ring.  Here we don't pull any
446d14abf15SRobert Mustacchi  * pending packets out of the hardware.  We only care about FCoE Fast Path
447d14abf15SRobert Mustacchi  * completions.  FCoE slow path L2 packets are processed via the default
448d14abf15SRobert Mustacchi  * status block not the LM_NON_RSS_SB.  In this path we're assuming that
449d14abf15SRobert Mustacchi  * the FCoE driver is performing a crashdump.
450d14abf15SRobert Mustacchi  */
BnxePollRxRingFCOE(um_device_t * pUM)451d14abf15SRobert Mustacchi void BnxePollRxRingFCOE(um_device_t * pUM)
452d14abf15SRobert Mustacchi {
453d14abf15SRobert Mustacchi     lm_device_t * pLM = (lm_device_t *)pUM;
454d14abf15SRobert Mustacchi     u32_t         activity_flg = 0;
455d14abf15SRobert Mustacchi 
456d14abf15SRobert Mustacchi     u8_t sb_id = LM_NON_RSS_SB(pLM);
457d14abf15SRobert Mustacchi     u8_t drv_rss_id = FCOE_CID(pLM);
458d14abf15SRobert Mustacchi 
459d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "Ring Poll FCoE: Handling status block sb_id:%d drv_rss_id:%d",
460d14abf15SRobert Mustacchi                sb_id, drv_rss_id);
461d14abf15SRobert Mustacchi 
462d14abf15SRobert Mustacchi     /* use sb_id for mapping into status block array (from LM) */
463d14abf15SRobert Mustacchi     ddi_dma_sync(pUM->statusBlocks[sb_id]->dmaHandle,
464d14abf15SRobert Mustacchi                  0, 0, DDI_DMA_SYNC_FORKERNEL);
465d14abf15SRobert Mustacchi 
466d14abf15SRobert Mustacchi     if (pUM->fmCapabilities &&
467d14abf15SRobert Mustacchi         BnxeCheckDmaHandle(pUM->statusBlocks[sb_id]->dmaHandle) != DDI_FM_OK)
468d14abf15SRobert Mustacchi     {
469d14abf15SRobert Mustacchi         ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
470d14abf15SRobert Mustacchi     }
471d14abf15SRobert Mustacchi 
472d14abf15SRobert Mustacchi     pUM->intrSbPollCnt[sb_id]++;
473d14abf15SRobert Mustacchi 
474d14abf15SRobert Mustacchi     if (lm_is_sb_updated(pLM, sb_id) == 0)
475d14abf15SRobert Mustacchi     {
476d14abf15SRobert Mustacchi         BnxeLogDbg(pUM, "Ring Poll FCoE: No change in status index so bail!");
477d14abf15SRobert Mustacchi         pUM->intrSbPollNoChangeCnt[sb_id]++;
478d14abf15SRobert Mustacchi         return;
479d14abf15SRobert Mustacchi     }
480d14abf15SRobert Mustacchi 
481d14abf15SRobert Mustacchi     /* get a local copy of the indices from the status block */
482d14abf15SRobert Mustacchi     lm_update_fp_hc_indices(pLM, sb_id, &activity_flg, &drv_rss_id);
483d14abf15SRobert Mustacchi 
484d14abf15SRobert Mustacchi     BnxeDbgBreakIf(pUM, !(activity_flg & LM_NON_DEF_EVENT_MASK));
485d14abf15SRobert Mustacchi 
486d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "Ring Poll FCoE: processing events on sb: %x, events: 0x%x",
487d14abf15SRobert Mustacchi                sb_id, activity_flg);
488d14abf15SRobert Mustacchi 
489d14abf15SRobert Mustacchi     if (activity_flg & LM_NON_DEF_USTORM_ACTIVE)
490d14abf15SRobert Mustacchi     {
491d14abf15SRobert Mustacchi         if (lm_fc_is_eq_completion(pLM, drv_rss_id))
492d14abf15SRobert Mustacchi         {
493d14abf15SRobert Mustacchi             lm_fc_service_eq_intr(pLM, drv_rss_id);
494d14abf15SRobert Mustacchi         }
495d14abf15SRobert Mustacchi     }
496d14abf15SRobert Mustacchi }
497d14abf15SRobert Mustacchi 
498d14abf15SRobert Mustacchi 
BnxeServiceSbIntr(um_device_t * pUM,u8_t sb_id,boolean_t * pPktsRxed,boolean_t * pPktsTxed)499d14abf15SRobert Mustacchi static void BnxeServiceSbIntr(um_device_t * pUM,
500d14abf15SRobert Mustacchi                               u8_t          sb_id,
501d14abf15SRobert Mustacchi                               boolean_t *   pPktsRxed,
502d14abf15SRobert Mustacchi                               boolean_t *   pPktsTxed)
503d14abf15SRobert Mustacchi {
504d14abf15SRobert Mustacchi     lm_device_t * pLM = (lm_device_t *)pUM;
505d14abf15SRobert Mustacchi     u32_t         activity_flg = 0;
506d14abf15SRobert Mustacchi     u8_t          drv_rss_id;
507d14abf15SRobert Mustacchi 
508d14abf15SRobert Mustacchi     *pPktsRxed = B_FALSE;
509d14abf15SRobert Mustacchi     *pPktsTxed = B_FALSE;
510d14abf15SRobert Mustacchi 
511d14abf15SRobert Mustacchi     drv_rss_id = lm_map_igu_sb_id_to_drv_rss(pLM, sb_id);
512d14abf15SRobert Mustacchi 
513d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "Ring INTR: Handling status block sb_id:%d drv_rss_id:%d",
514d14abf15SRobert Mustacchi                sb_id, drv_rss_id);
515d14abf15SRobert Mustacchi 
516d14abf15SRobert Mustacchi     /* use sb_id for mapping into status block array (from LM) */
517d14abf15SRobert Mustacchi     ddi_dma_sync(pUM->statusBlocks[sb_id]->dmaHandle,
518d14abf15SRobert Mustacchi                  0, 0, DDI_DMA_SYNC_FORKERNEL);
519d14abf15SRobert Mustacchi 
520d14abf15SRobert Mustacchi     if (pUM->fmCapabilities &&
521d14abf15SRobert Mustacchi         BnxeCheckDmaHandle(pUM->statusBlocks[sb_id]->dmaHandle) != DDI_FM_OK)
522d14abf15SRobert Mustacchi     {
523d14abf15SRobert Mustacchi         ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
524d14abf15SRobert Mustacchi     }
525d14abf15SRobert Mustacchi 
526d14abf15SRobert Mustacchi     pUM->intrSbCnt[sb_id]++;
527d14abf15SRobert Mustacchi 
528d14abf15SRobert Mustacchi     if (lm_is_sb_updated(pLM, sb_id) == 0)
529d14abf15SRobert Mustacchi     {
530d14abf15SRobert Mustacchi         BnxeLogDbg(pUM, "Ring INTR: No change in status index so bail!");
531d14abf15SRobert Mustacchi         pUM->intrSbNoChangeCnt[sb_id]++;
532d14abf15SRobert Mustacchi         return;
533d14abf15SRobert Mustacchi     }
534d14abf15SRobert Mustacchi 
535d14abf15SRobert Mustacchi     /*
536d14abf15SRobert Mustacchi      * get a local copy of the indices from the status block
537d14abf15SRobert Mustacchi      * XXX note that here drv_rss_id is assigned to the sb_id
538d14abf15SRobert Mustacchi      */
539d14abf15SRobert Mustacchi     lm_update_fp_hc_indices(pLM, sb_id, &activity_flg, &drv_rss_id);
540d14abf15SRobert Mustacchi 
541d14abf15SRobert Mustacchi     BnxeDbgBreakIf(pUM, !(activity_flg & LM_NON_DEF_EVENT_MASK));
542d14abf15SRobert Mustacchi 
543d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "Ring INTR: processing events on sb: %x, events: 0x%x",
544d14abf15SRobert Mustacchi                drv_rss_id, activity_flg);
545d14abf15SRobert Mustacchi 
546d14abf15SRobert Mustacchi     if (activity_flg & LM_NON_DEF_USTORM_ACTIVE)
547d14abf15SRobert Mustacchi     {
548d14abf15SRobert Mustacchi         /* Rx Completions */
549d14abf15SRobert Mustacchi         if (lm_is_rx_completion(pLM, drv_rss_id))
550d14abf15SRobert Mustacchi         {
551d14abf15SRobert Mustacchi             *pPktsRxed = B_TRUE;
552d14abf15SRobert Mustacchi         }
553d14abf15SRobert Mustacchi 
554d14abf15SRobert Mustacchi         if (lm_fc_is_eq_completion(pLM, drv_rss_id))
555d14abf15SRobert Mustacchi         {
556d14abf15SRobert Mustacchi             lm_fc_service_eq_intr(pLM, drv_rss_id);
557d14abf15SRobert Mustacchi         }
558d14abf15SRobert Mustacchi 
559d14abf15SRobert Mustacchi         /* XXX Check for ISCSI-OOO and L4 TOE Rx completions. NO! */
560d14abf15SRobert Mustacchi     }
561d14abf15SRobert Mustacchi 
562d14abf15SRobert Mustacchi     if (activity_flg & LM_NON_DEF_CSTORM_ACTIVE)
563d14abf15SRobert Mustacchi     {
564d14abf15SRobert Mustacchi         /* Tx completions */
565d14abf15SRobert Mustacchi         if (lm_is_tx_completion(pLM, drv_rss_id))
566d14abf15SRobert Mustacchi         {
567d14abf15SRobert Mustacchi             *pPktsTxed = B_TRUE;
568d14abf15SRobert Mustacchi         }
569d14abf15SRobert Mustacchi 
570d14abf15SRobert Mustacchi         /* XXX Check for L4 Tx and L5 EQ completions. NO! */
571d14abf15SRobert Mustacchi 
572d14abf15SRobert Mustacchi         /* L4 Tx completions */
573d14abf15SRobert Mustacchi         if (lm_toe_is_tx_completion(pLM, drv_rss_id))
574d14abf15SRobert Mustacchi         {
575d14abf15SRobert Mustacchi             BnxeDbgBreakMsg(pUM, "Unknown TOE Tx completion!");
576d14abf15SRobert Mustacchi         }
577d14abf15SRobert Mustacchi 
578d14abf15SRobert Mustacchi         /* L5 EQ completions */
579d14abf15SRobert Mustacchi         if (lm_sc_is_eq_completion(pLM, drv_rss_id))
580d14abf15SRobert Mustacchi         {
581d14abf15SRobert Mustacchi             BnxeDbgBreakMsg(pUM, "Unknown iSCSI EQ completion!");
582d14abf15SRobert Mustacchi             //lm_sc_service_eq_intr(pLM, drv_rss_id);
583d14abf15SRobert Mustacchi         }
584d14abf15SRobert Mustacchi     }
585d14abf15SRobert Mustacchi }
586d14abf15SRobert Mustacchi 
587d14abf15SRobert Mustacchi 
BnxeIntrISR(caddr_t arg1,caddr_t arg2)588d14abf15SRobert Mustacchi uint_t BnxeIntrISR(caddr_t arg1, caddr_t arg2)
589d14abf15SRobert Mustacchi {
590d14abf15SRobert Mustacchi     um_device_t *         pUM = (um_device_t *)arg1;
591d14abf15SRobert Mustacchi     lm_device_t *         pLM = &pUM->lm_dev;
592d14abf15SRobert Mustacchi     lm_interrupt_status_t intrStatus = 0;
593d14abf15SRobert Mustacchi     boolean_t             pktsRxed   = 0;
594d14abf15SRobert Mustacchi     boolean_t             pktsTxed   = 0;
595d14abf15SRobert Mustacchi     u32_t                 rss_id     = 0;
596d14abf15SRobert Mustacchi     int                   idx        = (int)(uintptr_t)arg2;
597d14abf15SRobert Mustacchi 
598d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_INTR(pUM, idx);
599d14abf15SRobert Mustacchi 
600d14abf15SRobert Mustacchi     if (!pUM->intrEnabled)
601d14abf15SRobert Mustacchi     {
602d14abf15SRobert Mustacchi         pLM->vars.dbg_intr_in_wrong_state++;
603d14abf15SRobert Mustacchi 
604d14abf15SRobert Mustacchi         BNXE_LOCK_EXIT_INTR(pUM, idx);
605d14abf15SRobert Mustacchi         return DDI_INTR_UNCLAIMED;
606d14abf15SRobert Mustacchi     }
607d14abf15SRobert Mustacchi 
608d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "-> BNXE INTA Interrupt <-");
609d14abf15SRobert Mustacchi 
610d14abf15SRobert Mustacchi     if (pLM->vars.enable_intr)
611d14abf15SRobert Mustacchi     {
612d14abf15SRobert Mustacchi         intrStatus = lm_get_interrupt_status(pLM);
613d14abf15SRobert Mustacchi 
614d14abf15SRobert Mustacchi         if (pUM->fmCapabilities &&
615d14abf15SRobert Mustacchi             BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
616d14abf15SRobert Mustacchi         {
617d14abf15SRobert Mustacchi             ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
618d14abf15SRobert Mustacchi         }
619d14abf15SRobert Mustacchi 
620d14abf15SRobert Mustacchi         if (intrStatus == 0)
621d14abf15SRobert Mustacchi         {
622d14abf15SRobert Mustacchi             pLM->vars.dbg_intr_zero_status++;
623d14abf15SRobert Mustacchi 
624d14abf15SRobert Mustacchi             BNXE_LOCK_EXIT_INTR(pUM, idx);
625d14abf15SRobert Mustacchi             return DDI_INTR_UNCLAIMED;
626d14abf15SRobert Mustacchi         }
627d14abf15SRobert Mustacchi     }
628d14abf15SRobert Mustacchi     else
629d14abf15SRobert Mustacchi     {
630d14abf15SRobert Mustacchi         pLM->vars.dbg_intr_in_disabled++;
631d14abf15SRobert Mustacchi         BnxeLogDbg(pUM, "INTA INTR: we got an interrupt when disabled");
632d14abf15SRobert Mustacchi 
633d14abf15SRobert Mustacchi         BNXE_LOCK_EXIT_INTR(pUM, idx);
634d14abf15SRobert Mustacchi         return DDI_INTR_CLAIMED;
635d14abf15SRobert Mustacchi     }
636d14abf15SRobert Mustacchi 
637d14abf15SRobert Mustacchi     atomic_add_64((volatile uint64_t *)&pUM->intrFired, 1);
638d14abf15SRobert Mustacchi 
639d14abf15SRobert Mustacchi     while (intrStatus)
640d14abf15SRobert Mustacchi     {
641d14abf15SRobert Mustacchi         if (intrStatus & 0x1)
642d14abf15SRobert Mustacchi         {
643d14abf15SRobert Mustacchi             if (rss_id == 0)
644d14abf15SRobert Mustacchi             {
645d14abf15SRobert Mustacchi                 lm_int_ack_def_sb_disable(pLM);
646d14abf15SRobert Mustacchi 
647d14abf15SRobert Mustacchi                 BnxeServiceDefSbIntr(pUM, &pktsRxed, &pktsTxed);
648d14abf15SRobert Mustacchi 
649d14abf15SRobert Mustacchi                 /*
650d14abf15SRobert Mustacchi                  * Default sb only handles FCoE only right now.  If this changes
651d14abf15SRobert Mustacchi                  * BnxeServiceDefSbIntr will have to change to return which CIDs
652d14abf15SRobert Mustacchi                  * have packets pending.
653d14abf15SRobert Mustacchi                  */
654d14abf15SRobert Mustacchi 
655d14abf15SRobert Mustacchi                 if (pktsTxed) BnxeTxRingProcess(pUM, FCOE_CID(pLM));
656d14abf15SRobert Mustacchi                 if (pktsRxed) BnxeRxRingProcess(pUM, FCOE_CID(pLM), B_FALSE, 0);
657d14abf15SRobert Mustacchi 
658d14abf15SRobert Mustacchi                 lm_sq_post_pending(pLM);
659d14abf15SRobert Mustacchi 
660d14abf15SRobert Mustacchi                 lm_int_ack_def_sb_enable(pLM);
661d14abf15SRobert Mustacchi             }
662d14abf15SRobert Mustacchi             else
663d14abf15SRobert Mustacchi             {
664d14abf15SRobert Mustacchi                 /*
665d14abf15SRobert Mustacchi                  * (rss_id - 1) is used because the non-default sbs are located
666d14abf15SRobert Mustacchi                  * in lm_device at indices 0-15.
667d14abf15SRobert Mustacchi                  */
668d14abf15SRobert Mustacchi 
669d14abf15SRobert Mustacchi                 lm_int_ack_sb_disable(pLM, (rss_id - 1));
670d14abf15SRobert Mustacchi 
671d14abf15SRobert Mustacchi                 BnxeServiceSbIntr(pUM, (rss_id - 1), &pktsRxed, &pktsTxed);
672d14abf15SRobert Mustacchi 
673d14abf15SRobert Mustacchi                 if (pktsTxed) BnxeTxRingProcess(pUM, (rss_id - 1));
674d14abf15SRobert Mustacchi                 if (pktsRxed) BnxeRxRingProcess(pUM, (rss_id - 1), B_FALSE, 0);
675d14abf15SRobert Mustacchi 
676d14abf15SRobert Mustacchi                 lm_sq_post_pending(pLM);
677d14abf15SRobert Mustacchi 
678d14abf15SRobert Mustacchi                 lm_int_ack_sb_enable(pLM, (rss_id - 1));
679d14abf15SRobert Mustacchi             }
680d14abf15SRobert Mustacchi         }
681d14abf15SRobert Mustacchi 
682d14abf15SRobert Mustacchi         intrStatus >>= 1;
683d14abf15SRobert Mustacchi         rss_id++;
684d14abf15SRobert Mustacchi     }
685d14abf15SRobert Mustacchi 
686d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_INTR(pUM, idx);
687d14abf15SRobert Mustacchi 
688d14abf15SRobert Mustacchi     return DDI_INTR_CLAIMED;
689d14abf15SRobert Mustacchi }
690d14abf15SRobert Mustacchi 
691d14abf15SRobert Mustacchi 
BnxeIntrMISR(caddr_t arg1,caddr_t arg2)692d14abf15SRobert Mustacchi uint_t BnxeIntrMISR(caddr_t arg1, caddr_t arg2)
693d14abf15SRobert Mustacchi {
694d14abf15SRobert Mustacchi     um_device_t * pUM = (um_device_t *)arg1;
695d14abf15SRobert Mustacchi     lm_device_t * pLM = &pUM->lm_dev;
696d14abf15SRobert Mustacchi     boolean_t     pktsRxed = 0;
697d14abf15SRobert Mustacchi     boolean_t     pktsTxed = 0;
698d14abf15SRobert Mustacchi     int           sb_id    = (int)(uintptr_t)arg2;
699d14abf15SRobert Mustacchi     u32_t         idx;
700d14abf15SRobert Mustacchi 
701d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_INTR(pUM, sb_id);
702d14abf15SRobert Mustacchi 
703d14abf15SRobert Mustacchi     if (!pUM->intrEnabled)
704d14abf15SRobert Mustacchi     {
705d14abf15SRobert Mustacchi         pLM->vars.dbg_intr_in_wrong_state++;
706d14abf15SRobert Mustacchi 
707d14abf15SRobert Mustacchi         BNXE_LOCK_EXIT_INTR(pUM, sb_id);
708d14abf15SRobert Mustacchi         return DDI_INTR_UNCLAIMED;
709d14abf15SRobert Mustacchi     }
710d14abf15SRobert Mustacchi 
711d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "-> BNXE MSIX Interrupt SB %d <-", sb_id);
712d14abf15SRobert Mustacchi 
713d14abf15SRobert Mustacchi     if (!pLM->vars.enable_intr)
714d14abf15SRobert Mustacchi     {
715d14abf15SRobert Mustacchi         pLM->vars.dbg_intr_in_disabled++;
716d14abf15SRobert Mustacchi         BnxeLogDbg(pUM, "MISR INTR: we got an interrupt when disabled");
717d14abf15SRobert Mustacchi 
718d14abf15SRobert Mustacchi         BNXE_LOCK_EXIT_INTR(pUM, sb_id);
719d14abf15SRobert Mustacchi         return DDI_INTR_CLAIMED;
720d14abf15SRobert Mustacchi     }
721d14abf15SRobert Mustacchi 
722d14abf15SRobert Mustacchi     atomic_add_64((volatile uint64_t *)&pUM->intrFired, 1);
723d14abf15SRobert Mustacchi 
724d14abf15SRobert Mustacchi     if (sb_id == DEF_STATUS_BLOCK_IGU_INDEX)
725d14abf15SRobert Mustacchi     {
726d14abf15SRobert Mustacchi         lm_int_ack_def_sb_disable(pLM);
727d14abf15SRobert Mustacchi 
728d14abf15SRobert Mustacchi         BnxeServiceDefSbIntr(pUM, &pktsRxed, &pktsTxed);
729d14abf15SRobert Mustacchi 
730d14abf15SRobert Mustacchi         /*
731d14abf15SRobert Mustacchi          * Default sb only handles FCoE only right now.  If this changes
732d14abf15SRobert Mustacchi          * BnxeServiceDefSbIntr will have to change to return which CIDs
733d14abf15SRobert Mustacchi          * have packets pending.
734d14abf15SRobert Mustacchi          */
735d14abf15SRobert Mustacchi 
736d14abf15SRobert Mustacchi         if (pktsTxed) BnxeTxRingProcess(pUM, FCOE_CID(pLM));
737d14abf15SRobert Mustacchi 	if (pktsRxed) BnxeRxRingProcess(pUM, FCOE_CID(pLM), FALSE, 0);
738d14abf15SRobert Mustacchi 
739d14abf15SRobert Mustacchi         lm_sq_post_pending(pLM);
740d14abf15SRobert Mustacchi 
741d14abf15SRobert Mustacchi         lm_int_ack_def_sb_enable(pLM);
742d14abf15SRobert Mustacchi     }
743d14abf15SRobert Mustacchi     else
744d14abf15SRobert Mustacchi     {
745d14abf15SRobert Mustacchi         /*
746d14abf15SRobert Mustacchi          * Note that polling is not allowed by GLDv3 on the LM_NON_RSS_SB when
747d14abf15SRobert Mustacchi          * overlapped with FCoE. This is enforced by the BnxeRxRingIntrEnable
748d14abf15SRobert Mustacchi          * and BnxeRxRingIntrDisable routines. The FCoE driver IS ALLOWED to
749d14abf15SRobert Mustacchi          * put the SB into poll mode. FCoE trumps GLDv3/L2 and it's assumed
750d14abf15SRobert Mustacchi          * the FCoE driver is performing a crashdump in this case.
751d14abf15SRobert Mustacchi          */
752d14abf15SRobert Mustacchi 
753d14abf15SRobert Mustacchi         idx = ((sb_id == LM_NON_RSS_SB(pLM)) &&
754d14abf15SRobert Mustacchi                CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE) &&
755d14abf15SRobert Mustacchi                (pUM->rssIntr.intrCount == LM_MAX_RSS_CHAINS(&pUM->lm_dev))) ?
756d14abf15SRobert Mustacchi                    FCOE_CID(pLM) : sb_id;
757d14abf15SRobert Mustacchi 
758d14abf15SRobert Mustacchi         if (pUM->rxq[idx].inPollMode)
759d14abf15SRobert Mustacchi         {
760d14abf15SRobert Mustacchi             /* Shouldn't be here! */
761d14abf15SRobert Mustacchi             cmn_err(CE_PANIC,
762d14abf15SRobert Mustacchi                     "%s: Interupt on RSS/MSIX ring %d when in poll mode!",
763d14abf15SRobert Mustacchi                     BnxeDevName(pUM), idx);
764d14abf15SRobert Mustacchi         }
765d14abf15SRobert Mustacchi 
766d14abf15SRobert Mustacchi         /* accounts for poll mode */
767d14abf15SRobert Mustacchi         BnxeIntrIguSbDisable(pUM, idx, B_TRUE);
768d14abf15SRobert Mustacchi 
769d14abf15SRobert Mustacchi         BnxeServiceSbIntr(pUM, sb_id, &pktsRxed, &pktsTxed);
770*55fea89dSDan Cross 
771d14abf15SRobert Mustacchi         if (pktsTxed) BnxeTxRingProcess(pUM, sb_id);
772d14abf15SRobert Mustacchi         if (pktsRxed) BnxeRxRingProcess(pUM, sb_id, B_FALSE, 0);
773d14abf15SRobert Mustacchi 
774d14abf15SRobert Mustacchi         lm_sq_post_pending(pLM);
775d14abf15SRobert Mustacchi 
776d14abf15SRobert Mustacchi         /* accounts for poll mode */
777d14abf15SRobert Mustacchi         BnxeIntrIguSbEnable(pUM, idx, B_TRUE);
778d14abf15SRobert Mustacchi     }
779d14abf15SRobert Mustacchi 
780d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_INTR(pUM, sb_id);
781d14abf15SRobert Mustacchi 
782d14abf15SRobert Mustacchi     return DDI_INTR_CLAIMED;
783d14abf15SRobert Mustacchi }
784d14abf15SRobert Mustacchi 
785d14abf15SRobert Mustacchi 
BnxeGetInterruptCount(dev_info_t * pDev,int type,int intrTypes)786d14abf15SRobert Mustacchi static int BnxeGetInterruptCount(dev_info_t * pDev, int type, int intrTypes)
787d14abf15SRobert Mustacchi {
788d14abf15SRobert Mustacchi     int nintrs = 0;
789d14abf15SRobert Mustacchi 
790d14abf15SRobert Mustacchi     if (intrTypes & type)
791d14abf15SRobert Mustacchi     {
792d14abf15SRobert Mustacchi         return (ddi_intr_get_nintrs(pDev, type, &nintrs) != DDI_SUCCESS) ?
793d14abf15SRobert Mustacchi                -1 : nintrs;
794d14abf15SRobert Mustacchi     }
795d14abf15SRobert Mustacchi 
796d14abf15SRobert Mustacchi     return -1;
797d14abf15SRobert Mustacchi }
798d14abf15SRobert Mustacchi 
799d14abf15SRobert Mustacchi 
BnxeIntrBlockAlloc(um_device_t * pUM,int intrInum,int intrCnt,BnxeIntrBlock * pBlock)800d14abf15SRobert Mustacchi static boolean_t BnxeIntrBlockAlloc(um_device_t *   pUM,
801d14abf15SRobert Mustacchi                                     int             intrInum,
802d14abf15SRobert Mustacchi                                     int             intrCnt,
803d14abf15SRobert Mustacchi                                     BnxeIntrBlock * pBlock)
804d14abf15SRobert Mustacchi 
805d14abf15SRobert Mustacchi {
806d14abf15SRobert Mustacchi     dev_info_t * pDev = pUM->pDev;
807d14abf15SRobert Mustacchi     int intrRequest;
808d14abf15SRobert Mustacchi     int intrActual;
809d14abf15SRobert Mustacchi     int rc, i;
810d14abf15SRobert Mustacchi 
811d14abf15SRobert Mustacchi     if ((pUM->intrType == DDI_INTR_TYPE_FIXED) && (intrCnt != 1))
812d14abf15SRobert Mustacchi     {
813d14abf15SRobert Mustacchi         return B_FALSE;
814d14abf15SRobert Mustacchi     }
815d14abf15SRobert Mustacchi 
816d14abf15SRobert Mustacchi     intrRequest = intrCnt;
817d14abf15SRobert Mustacchi     intrActual  = 0;
818d14abf15SRobert Mustacchi 
819d14abf15SRobert Mustacchi     /*
820d14abf15SRobert Mustacchi      * We need to allocate an interrupt block array of maximum size which is
821d14abf15SRobert Mustacchi      * MAX_RSS_CHAINS plus one for the default interrupt.  Even though we
822d14abf15SRobert Mustacchi      * won't allocate all of those handlers the "inum" value passed to
823d14abf15SRobert Mustacchi      * ddi_intr_alloc() determines the starting index where the handlers
824d14abf15SRobert Mustacchi      * will be allocated.  See the multi-function block offset documentation
825d14abf15SRobert Mustacchi      * at the top of this file.
826d14abf15SRobert Mustacchi      */
827d14abf15SRobert Mustacchi     pBlock->intrHandleBlockSize =
828d14abf15SRobert Mustacchi         ((MAX_RSS_CHAINS + 1) * sizeof(ddi_intr_handle_t));
829d14abf15SRobert Mustacchi 
830d14abf15SRobert Mustacchi     if ((pBlock->pIntrHandleBlockAlloc =
831d14abf15SRobert Mustacchi          (ddi_intr_handle_t *)kmem_zalloc(pBlock->intrHandleBlockSize,
832d14abf15SRobert Mustacchi                                           KM_SLEEP)) == NULL)
833d14abf15SRobert Mustacchi     {
834d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Memory alloc failed for isr handle block (inum=%d)!",
835d14abf15SRobert Mustacchi                     intrInum);
836d14abf15SRobert Mustacchi         return B_FALSE;
837d14abf15SRobert Mustacchi     }
838d14abf15SRobert Mustacchi 
839d14abf15SRobert Mustacchi     if ((rc = ddi_intr_alloc(pDev,
840d14abf15SRobert Mustacchi                              pBlock->pIntrHandleBlockAlloc,
841d14abf15SRobert Mustacchi                              pUM->intrType,
842d14abf15SRobert Mustacchi                              intrInum,
843d14abf15SRobert Mustacchi                              intrRequest,
844d14abf15SRobert Mustacchi                              &intrActual,
845d14abf15SRobert Mustacchi                              DDI_INTR_ALLOC_NORMAL)) != DDI_SUCCESS)
846d14abf15SRobert Mustacchi     {
847d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to allocate isr handle block (%d) (inum=%d cnt=%d)!",
848d14abf15SRobert Mustacchi                     rc, intrInum, intrRequest);
849d14abf15SRobert Mustacchi         kmem_free(pBlock->pIntrHandleBlockAlloc, pBlock->intrHandleBlockSize);
850d14abf15SRobert Mustacchi         return B_FALSE;
851d14abf15SRobert Mustacchi     }
852d14abf15SRobert Mustacchi 
853d14abf15SRobert Mustacchi     /*
854d14abf15SRobert Mustacchi      * Point 'pIntrHandleBlock' to the starting interrupt index in the
855d14abf15SRobert Mustacchi      * allocated interrupt block array.  This is done so we can easily enable,
856d14abf15SRobert Mustacchi      * disable, free, etc the interrupts.  For 10u8 and beyond the inum value
857d14abf15SRobert Mustacchi      * is also used as an index into the interrupt block so we point
858d14abf15SRobert Mustacchi      * pIntrHandleBlock to the inum'th index.  For 10u7 and below all
859d14abf15SRobert Mustacchi      * interrupt allocations start at index 0 per block.
860d14abf15SRobert Mustacchi      */
861d14abf15SRobert Mustacchi #if 0
862d14abf15SRobert Mustacchi 
863d14abf15SRobert Mustacchi #ifdef DDI_INTR_IRM
864d14abf15SRobert Mustacchi     pBlock->pIntrHandleBlock =
865d14abf15SRobert Mustacchi         &pBlock->pIntrHandleBlockAlloc[intrInum];
866d14abf15SRobert Mustacchi #else
867d14abf15SRobert Mustacchi     pBlock->pIntrHandleBlock =
868d14abf15SRobert Mustacchi         &pBlock->pIntrHandleBlockAlloc[0];
869d14abf15SRobert Mustacchi #endif
870d14abf15SRobert Mustacchi 
871d14abf15SRobert Mustacchi #else
872d14abf15SRobert Mustacchi 
873d14abf15SRobert Mustacchi     if (pBlock->pIntrHandleBlockAlloc[0])
874d14abf15SRobert Mustacchi     {
875d14abf15SRobert Mustacchi         pBlock->pIntrHandleBlock =
876d14abf15SRobert Mustacchi             &pBlock->pIntrHandleBlockAlloc[0];
877d14abf15SRobert Mustacchi     }
878d14abf15SRobert Mustacchi     else
879d14abf15SRobert Mustacchi     {
880d14abf15SRobert Mustacchi         pBlock->pIntrHandleBlock =
881d14abf15SRobert Mustacchi             &pBlock->pIntrHandleBlockAlloc[intrInum];
882d14abf15SRobert Mustacchi     }
883d14abf15SRobert Mustacchi 
884d14abf15SRobert Mustacchi #endif
885d14abf15SRobert Mustacchi 
886d14abf15SRobert Mustacchi     if (intrRequest != intrActual)
887d14abf15SRobert Mustacchi     {
888d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to allocate desired isr count (%d/%d)!",
889d14abf15SRobert Mustacchi                     intrActual, intrRequest);
890d14abf15SRobert Mustacchi 
891d14abf15SRobert Mustacchi #if 0
892d14abf15SRobert Mustacchi         for (i = 0; i < intrActual; i++)
893d14abf15SRobert Mustacchi         {
894d14abf15SRobert Mustacchi             ddi_intr_free(pBlock->pIntrHandleBlock[i]);
895d14abf15SRobert Mustacchi         }
896d14abf15SRobert Mustacchi 
897d14abf15SRobert Mustacchi         kmem_free(pBlock->pIntrHandleBlockAlloc, pBlock->intrHandleBlockSize);
898d14abf15SRobert Mustacchi         return B_FALSE;
899d14abf15SRobert Mustacchi #else
900d14abf15SRobert Mustacchi         if (intrActual == 0)
901d14abf15SRobert Mustacchi         {
902d14abf15SRobert Mustacchi             kmem_free(pBlock->pIntrHandleBlockAlloc, pBlock->intrHandleBlockSize);
903d14abf15SRobert Mustacchi             return B_FALSE;
904d14abf15SRobert Mustacchi         }
905d14abf15SRobert Mustacchi #endif
906d14abf15SRobert Mustacchi     }
907d14abf15SRobert Mustacchi 
908d14abf15SRobert Mustacchi     pBlock->intrCount = intrActual;
909d14abf15SRobert Mustacchi 
910d14abf15SRobert Mustacchi     if ((rc = ddi_intr_get_cap(pBlock->pIntrHandleBlock[0],
911d14abf15SRobert Mustacchi                                &pBlock->intrCapability)) != DDI_SUCCESS)
912d14abf15SRobert Mustacchi     {
913d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to get isr capability (%d)!", rc);
914d14abf15SRobert Mustacchi         goto BnxeIntrBlockAlloc_fail;
915d14abf15SRobert Mustacchi     }
916d14abf15SRobert Mustacchi 
917d14abf15SRobert Mustacchi     if ((rc = ddi_intr_get_pri(pBlock->pIntrHandleBlock[0],
918d14abf15SRobert Mustacchi                                &pBlock->intrPriority)) != DDI_SUCCESS)
919d14abf15SRobert Mustacchi     {
920d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to get isr priority (%d)!", rc);
921d14abf15SRobert Mustacchi         goto BnxeIntrBlockAlloc_fail;
922d14abf15SRobert Mustacchi     }
923d14abf15SRobert Mustacchi 
924d14abf15SRobert Mustacchi     if (pBlock->intrPriority >= ddi_intr_get_hilevel_pri())
925d14abf15SRobert Mustacchi     {
926d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Interrupt priority is too high!");
927d14abf15SRobert Mustacchi         goto BnxeIntrBlockAlloc_fail;
928d14abf15SRobert Mustacchi     }
929d14abf15SRobert Mustacchi 
930d14abf15SRobert Mustacchi     return B_TRUE;
931d14abf15SRobert Mustacchi 
932d14abf15SRobert Mustacchi BnxeIntrBlockAlloc_fail:
933d14abf15SRobert Mustacchi 
934d14abf15SRobert Mustacchi     for (i = 0; i < intrActual; i++)
935d14abf15SRobert Mustacchi     {
936d14abf15SRobert Mustacchi         ddi_intr_free(pBlock->pIntrHandleBlock[i]);
937d14abf15SRobert Mustacchi     }
938d14abf15SRobert Mustacchi 
939d14abf15SRobert Mustacchi     kmem_free(pBlock->pIntrHandleBlockAlloc, pBlock->intrHandleBlockSize);
940d14abf15SRobert Mustacchi 
941d14abf15SRobert Mustacchi     memset(pBlock, 0, sizeof(BnxeIntrBlock));
942d14abf15SRobert Mustacchi 
943d14abf15SRobert Mustacchi     return B_FALSE;
944d14abf15SRobert Mustacchi }
945d14abf15SRobert Mustacchi 
946d14abf15SRobert Mustacchi 
BnxeIntrBlockFree(um_device_t * pUM,BnxeIntrBlock * pBlock)947d14abf15SRobert Mustacchi static void BnxeIntrBlockFree(um_device_t *   pUM,
948d14abf15SRobert Mustacchi                               BnxeIntrBlock * pBlock)
949d14abf15SRobert Mustacchi 
950d14abf15SRobert Mustacchi {
951d14abf15SRobert Mustacchi     int i;
952d14abf15SRobert Mustacchi 
953d14abf15SRobert Mustacchi     if (pBlock->intrCount == 0)
954d14abf15SRobert Mustacchi     {
955d14abf15SRobert Mustacchi         memset(pBlock, 0, sizeof(BnxeIntrBlock));
956d14abf15SRobert Mustacchi         return;
957d14abf15SRobert Mustacchi     }
958d14abf15SRobert Mustacchi 
959d14abf15SRobert Mustacchi     for (i = 0; i < pBlock->intrCount; i++)
960d14abf15SRobert Mustacchi     {
961d14abf15SRobert Mustacchi         ddi_intr_free(pBlock->pIntrHandleBlock[i]);
962d14abf15SRobert Mustacchi     }
963d14abf15SRobert Mustacchi 
964d14abf15SRobert Mustacchi     kmem_free(pBlock->pIntrHandleBlockAlloc, pBlock->intrHandleBlockSize);
965d14abf15SRobert Mustacchi 
966d14abf15SRobert Mustacchi     memset(pBlock, 0, sizeof(BnxeIntrBlock));
967d14abf15SRobert Mustacchi }
968d14abf15SRobert Mustacchi 
969d14abf15SRobert Mustacchi 
BnxeIntrAddHandlers(um_device_t * pUM)970d14abf15SRobert Mustacchi static boolean_t BnxeIntrAddHandlers(um_device_t * pUM)
971d14abf15SRobert Mustacchi {
972d14abf15SRobert Mustacchi     int rc, i, j;
973d14abf15SRobert Mustacchi 
974d14abf15SRobert Mustacchi     switch (pUM->intrType)
975d14abf15SRobert Mustacchi     {
976d14abf15SRobert Mustacchi     case DDI_INTR_TYPE_MSIX:
977d14abf15SRobert Mustacchi 
978d14abf15SRobert Mustacchi         if ((rc = ddi_intr_add_handler(
979d14abf15SRobert Mustacchi                       pUM->defIntr.pIntrHandleBlock[0],
980d14abf15SRobert Mustacchi                       BnxeIntrMISR,
981d14abf15SRobert Mustacchi                       (caddr_t)pUM,
982d14abf15SRobert Mustacchi                       (caddr_t)(uintptr_t)DEF_STATUS_BLOCK_IGU_INDEX)) !=
983d14abf15SRobert Mustacchi             DDI_SUCCESS)
984d14abf15SRobert Mustacchi         {
985d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Failed to add the MSIX default isr handler (%d)", rc);
986d14abf15SRobert Mustacchi             return B_FALSE;
987d14abf15SRobert Mustacchi         }
988d14abf15SRobert Mustacchi 
989d14abf15SRobert Mustacchi         for (i = 0; i < pUM->rssIntr.intrCount; i++)
990d14abf15SRobert Mustacchi         {
991d14abf15SRobert Mustacchi             if ((rc = ddi_intr_add_handler(
992d14abf15SRobert Mustacchi                           pUM->rssIntr.pIntrHandleBlock[i],
993d14abf15SRobert Mustacchi                           BnxeIntrMISR,
994d14abf15SRobert Mustacchi                           (caddr_t)pUM,
995d14abf15SRobert Mustacchi                           (caddr_t)(uintptr_t)i)) !=
996d14abf15SRobert Mustacchi                 DDI_SUCCESS)
997d14abf15SRobert Mustacchi             {
998d14abf15SRobert Mustacchi                 BnxeLogWarn(pUM, "Failed to add the MSIX RSS isr handler %d (%d)",
999d14abf15SRobert Mustacchi                             (i + NDIS_CID(&pUM->lm_dev)), rc);
1000d14abf15SRobert Mustacchi 
1001d14abf15SRobert Mustacchi                 ddi_intr_remove_handler(pUM->defIntr.pIntrHandleBlock[0]);
1002d14abf15SRobert Mustacchi 
1003d14abf15SRobert Mustacchi                 for (j = 0; j < i; j++) /* unwind */
1004d14abf15SRobert Mustacchi                 {
1005d14abf15SRobert Mustacchi                     ddi_intr_remove_handler(pUM->rssIntr.pIntrHandleBlock[j]);
1006d14abf15SRobert Mustacchi                 }
1007d14abf15SRobert Mustacchi 
1008d14abf15SRobert Mustacchi                 return B_FALSE;
1009d14abf15SRobert Mustacchi             }
1010d14abf15SRobert Mustacchi         }
1011d14abf15SRobert Mustacchi 
1012d14abf15SRobert Mustacchi         /*
1013d14abf15SRobert Mustacchi          * fcoeIntr.intrCount == 1 implies LM_NON_RSS_SB (last) status block
1014d14abf15SRobert Mustacchi          * was allocated for FCoE and there was no overlap with the RSS
1015d14abf15SRobert Mustacchi          * allocation.
1016d14abf15SRobert Mustacchi          */
1017d14abf15SRobert Mustacchi         if (pUM->fcoeIntr.intrCount == 1)
1018d14abf15SRobert Mustacchi         {
1019d14abf15SRobert Mustacchi             if ((rc = ddi_intr_add_handler(
1020d14abf15SRobert Mustacchi                           pUM->fcoeIntr.pIntrHandleBlock[0],
1021d14abf15SRobert Mustacchi                           BnxeIntrMISR,
1022d14abf15SRobert Mustacchi                           (caddr_t)pUM,
1023d14abf15SRobert Mustacchi                           (caddr_t)(uintptr_t)LM_NON_RSS_SB(&pUM->lm_dev))) !=
1024d14abf15SRobert Mustacchi                 DDI_SUCCESS)
1025d14abf15SRobert Mustacchi             {
1026d14abf15SRobert Mustacchi                 BnxeLogWarn(pUM, "Failed to add the MSIX FCoE isr handler (%d)", rc);
1027d14abf15SRobert Mustacchi 
1028d14abf15SRobert Mustacchi                 ddi_intr_remove_handler(pUM->defIntr.pIntrHandleBlock[0]);
1029d14abf15SRobert Mustacchi 
1030d14abf15SRobert Mustacchi                 for (i = 0; i < pUM->rssIntr.intrCount; i++)
1031d14abf15SRobert Mustacchi                 {
1032d14abf15SRobert Mustacchi                     ddi_intr_remove_handler(pUM->rssIntr.pIntrHandleBlock[i]);
1033d14abf15SRobert Mustacchi                 }
1034d14abf15SRobert Mustacchi 
1035d14abf15SRobert Mustacchi                 return B_FALSE;
1036d14abf15SRobert Mustacchi             }
1037d14abf15SRobert Mustacchi         }
1038d14abf15SRobert Mustacchi 
1039d14abf15SRobert Mustacchi         break;
1040d14abf15SRobert Mustacchi 
1041d14abf15SRobert Mustacchi     case DDI_INTR_TYPE_FIXED:
1042d14abf15SRobert Mustacchi 
1043d14abf15SRobert Mustacchi         if ((rc = ddi_intr_add_handler(
1044d14abf15SRobert Mustacchi                                pUM->defIntr.pIntrHandleBlock[0],
1045d14abf15SRobert Mustacchi                                BnxeIntrISR,
1046d14abf15SRobert Mustacchi                                (caddr_t)pUM,
1047d14abf15SRobert Mustacchi                                (caddr_t)(uintptr_t)DEF_STATUS_BLOCK_IGU_INDEX)) !=
1048d14abf15SRobert Mustacchi             DDI_SUCCESS)
1049d14abf15SRobert Mustacchi         {
1050d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Failed to add the fixed default isr handler (%d)", rc);
1051d14abf15SRobert Mustacchi             return B_FALSE;
1052d14abf15SRobert Mustacchi         }
1053d14abf15SRobert Mustacchi 
1054d14abf15SRobert Mustacchi         break;
1055d14abf15SRobert Mustacchi 
1056d14abf15SRobert Mustacchi     default:
1057d14abf15SRobert Mustacchi 
1058d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to add isr handler (unsupported type %d)!",
1059d14abf15SRobert Mustacchi                     pUM->intrType);
1060d14abf15SRobert Mustacchi         return B_FALSE;
1061d14abf15SRobert Mustacchi     }
1062d14abf15SRobert Mustacchi 
1063d14abf15SRobert Mustacchi     return B_TRUE;
1064d14abf15SRobert Mustacchi }
1065d14abf15SRobert Mustacchi 
1066d14abf15SRobert Mustacchi 
BnxeIntrBlockRemoveHandler(um_device_t * pUM,BnxeIntrBlock * pBlock)1067d14abf15SRobert Mustacchi static void BnxeIntrBlockRemoveHandler(um_device_t *   pUM,
1068d14abf15SRobert Mustacchi                                        BnxeIntrBlock * pBlock)
1069d14abf15SRobert Mustacchi {
1070d14abf15SRobert Mustacchi     int i;
1071d14abf15SRobert Mustacchi 
1072d14abf15SRobert Mustacchi     (void)pUM;
1073d14abf15SRobert Mustacchi 
1074d14abf15SRobert Mustacchi     if (pBlock->intrCount == 0)
1075d14abf15SRobert Mustacchi     {
1076d14abf15SRobert Mustacchi         return;
1077d14abf15SRobert Mustacchi     }
1078d14abf15SRobert Mustacchi 
1079d14abf15SRobert Mustacchi     for (i = 0; i < pBlock->intrCount; i++)
1080d14abf15SRobert Mustacchi     {
1081d14abf15SRobert Mustacchi         ddi_intr_remove_handler(pBlock->pIntrHandleBlock[i]);
1082d14abf15SRobert Mustacchi     }
1083d14abf15SRobert Mustacchi }
1084d14abf15SRobert Mustacchi 
1085d14abf15SRobert Mustacchi 
BnxeIntrBlockEnable(um_device_t * pUM,BnxeIntrBlock * pBlock)1086d14abf15SRobert Mustacchi static boolean_t BnxeIntrBlockEnable(um_device_t *   pUM,
1087d14abf15SRobert Mustacchi                                      BnxeIntrBlock * pBlock)
1088d14abf15SRobert Mustacchi {
1089d14abf15SRobert Mustacchi     int rc, i, j;
1090d14abf15SRobert Mustacchi 
1091d14abf15SRobert Mustacchi     if (pBlock->intrCount == 0)
1092d14abf15SRobert Mustacchi     {
1093d14abf15SRobert Mustacchi         return B_TRUE;
1094d14abf15SRobert Mustacchi     }
1095d14abf15SRobert Mustacchi 
1096d14abf15SRobert Mustacchi     if (pBlock->intrCapability & DDI_INTR_FLAG_BLOCK)
1097d14abf15SRobert Mustacchi     {
1098d14abf15SRobert Mustacchi         if ((rc = ddi_intr_block_enable(pBlock->pIntrHandleBlock,
1099d14abf15SRobert Mustacchi                                         pBlock->intrCount)) != DDI_SUCCESS)
1100d14abf15SRobert Mustacchi         {
1101d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Failed to enable isr block (%d)", rc);
1102d14abf15SRobert Mustacchi             return B_FALSE;
1103d14abf15SRobert Mustacchi         }
1104d14abf15SRobert Mustacchi     }
1105d14abf15SRobert Mustacchi     else
1106d14abf15SRobert Mustacchi     {
1107d14abf15SRobert Mustacchi         for (i = 0; i < pBlock->intrCount; i++)
1108d14abf15SRobert Mustacchi         {
1109d14abf15SRobert Mustacchi             if ((rc = ddi_intr_enable(pBlock->pIntrHandleBlock[i])) !=
1110d14abf15SRobert Mustacchi                 DDI_SUCCESS)
1111d14abf15SRobert Mustacchi             {
1112d14abf15SRobert Mustacchi                 BnxeLogWarn(pUM, "Failed to enable isr %d (%d)", i, rc);
1113d14abf15SRobert Mustacchi 
1114d14abf15SRobert Mustacchi                 for (j = 0; j < i; j++) /* unwind */
1115d14abf15SRobert Mustacchi                 {
1116d14abf15SRobert Mustacchi                     ddi_intr_disable(pBlock->pIntrHandleBlock[j]);
1117d14abf15SRobert Mustacchi                 }
1118d14abf15SRobert Mustacchi 
1119d14abf15SRobert Mustacchi                 return B_FALSE;
1120d14abf15SRobert Mustacchi             }
1121d14abf15SRobert Mustacchi         }
1122d14abf15SRobert Mustacchi     }
1123d14abf15SRobert Mustacchi 
1124d14abf15SRobert Mustacchi     return B_TRUE;
1125d14abf15SRobert Mustacchi }
1126d14abf15SRobert Mustacchi 
1127d14abf15SRobert Mustacchi 
BnxeIntrBlockDisable(um_device_t * pUM,BnxeIntrBlock * pBlock)1128d14abf15SRobert Mustacchi static void BnxeIntrBlockDisable(um_device_t *   pUM,
1129d14abf15SRobert Mustacchi                                  BnxeIntrBlock * pBlock)
1130d14abf15SRobert Mustacchi {
1131d14abf15SRobert Mustacchi     int i;
1132d14abf15SRobert Mustacchi 
1133d14abf15SRobert Mustacchi     if (pBlock->intrCount == 0)
1134d14abf15SRobert Mustacchi     {
1135d14abf15SRobert Mustacchi         return;
1136d14abf15SRobert Mustacchi     }
1137d14abf15SRobert Mustacchi 
1138d14abf15SRobert Mustacchi     if (pBlock->intrCapability & DDI_INTR_FLAG_BLOCK)
1139d14abf15SRobert Mustacchi     {
1140d14abf15SRobert Mustacchi         ddi_intr_block_disable(pBlock->pIntrHandleBlock, pBlock->intrCount);
1141d14abf15SRobert Mustacchi     }
1142d14abf15SRobert Mustacchi     else
1143d14abf15SRobert Mustacchi     {
1144d14abf15SRobert Mustacchi         for (i = 0; i < pBlock->intrCount; i++)
1145d14abf15SRobert Mustacchi         {
1146d14abf15SRobert Mustacchi             ddi_intr_disable(pBlock->pIntrHandleBlock[i]);
1147d14abf15SRobert Mustacchi         }
1148d14abf15SRobert Mustacchi     }
1149d14abf15SRobert Mustacchi }
1150d14abf15SRobert Mustacchi 
1151d14abf15SRobert Mustacchi 
BnxeIntrEnable(um_device_t * pUM)1152d14abf15SRobert Mustacchi int BnxeIntrEnable(um_device_t * pUM)
1153d14abf15SRobert Mustacchi {
1154d14abf15SRobert Mustacchi     BnxeMemDma * pDma;
1155d14abf15SRobert Mustacchi     int rc, i, j;
1156d14abf15SRobert Mustacchi 
1157d14abf15SRobert Mustacchi     atomic_swap_64((volatile uint64_t *)&pUM->intrFired, 0);
1158d14abf15SRobert Mustacchi 
1159d14abf15SRobert Mustacchi     for (i = 0; i < (MAX_RSS_CHAINS + 1); i++)
1160d14abf15SRobert Mustacchi     {
1161d14abf15SRobert Mustacchi         pUM->intrSbCnt[i]         = 0;
1162d14abf15SRobert Mustacchi         pUM->intrSbNoChangeCnt[i] = 0;
1163d14abf15SRobert Mustacchi     }
1164d14abf15SRobert Mustacchi 
1165d14abf15SRobert Mustacchi     /* get the DMA handles for quick access to the status blocks for sync */
1166d14abf15SRobert Mustacchi     BnxeFindDmaHandles(pUM);
1167d14abf15SRobert Mustacchi 
1168d14abf15SRobert Mustacchi     /* Enable the default interrupt... */
1169d14abf15SRobert Mustacchi 
1170d14abf15SRobert Mustacchi     if (!BnxeIntrBlockEnable(pUM, &pUM->defIntr))
1171d14abf15SRobert Mustacchi     {
1172d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to enable the default interrupt");
1173d14abf15SRobert Mustacchi         return -1;
1174d14abf15SRobert Mustacchi     }
1175d14abf15SRobert Mustacchi 
1176d14abf15SRobert Mustacchi     /* Enable the FCoE interrupt... */
1177d14abf15SRobert Mustacchi 
1178d14abf15SRobert Mustacchi     if (!BnxeIntrBlockEnable(pUM, &pUM->fcoeIntr))
1179d14abf15SRobert Mustacchi     {
1180d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to enable the FCoE interrupt");
1181d14abf15SRobert Mustacchi         BnxeIntrBlockDisable(pUM, &pUM->defIntr);
1182d14abf15SRobert Mustacchi         return -1;
1183d14abf15SRobert Mustacchi     }
1184d14abf15SRobert Mustacchi 
1185d14abf15SRobert Mustacchi     /* Enable the RSS interrupts... */
1186d14abf15SRobert Mustacchi 
1187d14abf15SRobert Mustacchi     if (!BnxeIntrBlockEnable(pUM, &pUM->rssIntr))
1188d14abf15SRobert Mustacchi     {
1189d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to enable the RSS interrupt");
1190d14abf15SRobert Mustacchi         BnxeIntrBlockDisable(pUM, &pUM->defIntr);
1191d14abf15SRobert Mustacchi         BnxeIntrBlockDisable(pUM, &pUM->fcoeIntr);
1192d14abf15SRobert Mustacchi         return -1;
1193d14abf15SRobert Mustacchi     }
1194d14abf15SRobert Mustacchi 
1195d14abf15SRobert Mustacchi     /* allow the hardware to generate interrupts */
1196d14abf15SRobert Mustacchi     atomic_swap_32(&pUM->intrEnabled, B_TRUE);
1197d14abf15SRobert Mustacchi     lm_enable_int(&pUM->lm_dev);
1198d14abf15SRobert Mustacchi 
1199d14abf15SRobert Mustacchi     if (pUM->fmCapabilities &&
1200d14abf15SRobert Mustacchi         BnxeCheckAccHandle(pUM->lm_dev.vars.reg_handle[BAR_0]) != DDI_FM_OK)
1201d14abf15SRobert Mustacchi     {
1202d14abf15SRobert Mustacchi         ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
1203d14abf15SRobert Mustacchi     }
1204d14abf15SRobert Mustacchi 
1205d14abf15SRobert Mustacchi /* XXX do not remove this... edavis */
1206d14abf15SRobert Mustacchi drv_usecwait(1000000); /* :-( */
1207d14abf15SRobert Mustacchi 
1208d14abf15SRobert Mustacchi     return 0;
1209d14abf15SRobert Mustacchi }
1210d14abf15SRobert Mustacchi 
1211d14abf15SRobert Mustacchi 
BnxeIntrDisable(um_device_t * pUM)1212d14abf15SRobert Mustacchi void BnxeIntrDisable(um_device_t * pUM)
1213d14abf15SRobert Mustacchi {
1214d14abf15SRobert Mustacchi     int rc, i;
1215d14abf15SRobert Mustacchi 
1216d14abf15SRobert Mustacchi     /* stop the device from generating any interrupts */
1217d14abf15SRobert Mustacchi     lm_disable_int(&pUM->lm_dev);
1218d14abf15SRobert Mustacchi 
1219d14abf15SRobert Mustacchi     if (pUM->fmCapabilities &&
1220d14abf15SRobert Mustacchi         BnxeCheckAccHandle(pUM->lm_dev.vars.reg_handle[BAR_0]) != DDI_FM_OK)
1221d14abf15SRobert Mustacchi     {
1222d14abf15SRobert Mustacchi         ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
1223d14abf15SRobert Mustacchi     }
1224d14abf15SRobert Mustacchi 
1225d14abf15SRobert Mustacchi     atomic_swap_32(&pUM->intrEnabled, B_FALSE);
1226d14abf15SRobert Mustacchi 
1227d14abf15SRobert Mustacchi     /*
1228d14abf15SRobert Mustacchi      * Ensure the ISR no longer touches the hardware by making sure the ISR
1229d14abf15SRobert Mustacchi      * is not running or the current run completes.   Since interrupts were
1230d14abf15SRobert Mustacchi      * disabled before here and intrEnabled is FALSE, we can be sure
1231d14abf15SRobert Mustacchi      * interrupts will no longer be processed.
1232d14abf15SRobert Mustacchi      */
1233d14abf15SRobert Mustacchi     for (i = 0; i < (MAX_RSS_CHAINS + 1); i++)
1234d14abf15SRobert Mustacchi     {
1235d14abf15SRobert Mustacchi         BNXE_LOCK_ENTER_INTR(pUM, i);
1236d14abf15SRobert Mustacchi         BNXE_LOCK_EXIT_INTR(pUM, i);
1237d14abf15SRobert Mustacchi     }
1238d14abf15SRobert Mustacchi 
1239d14abf15SRobert Mustacchi     /* Disable the default interrupt... */
1240d14abf15SRobert Mustacchi 
1241d14abf15SRobert Mustacchi     BnxeIntrBlockDisable(pUM, &pUM->defIntr);
1242d14abf15SRobert Mustacchi 
1243d14abf15SRobert Mustacchi     /* Disable the FCoE interrupt... */
1244d14abf15SRobert Mustacchi 
1245d14abf15SRobert Mustacchi     BnxeIntrBlockDisable(pUM, &pUM->fcoeIntr);
1246d14abf15SRobert Mustacchi 
1247d14abf15SRobert Mustacchi     /* Disable the RSS interrupts... */
1248d14abf15SRobert Mustacchi 
1249d14abf15SRobert Mustacchi     BnxeIntrBlockDisable(pUM, &pUM->rssIntr);
1250d14abf15SRobert Mustacchi }
1251d14abf15SRobert Mustacchi 
1252d14abf15SRobert Mustacchi 
BnxeIntrInit(um_device_t * pUM)1253d14abf15SRobert Mustacchi boolean_t BnxeIntrInit(um_device_t * pUM)
1254d14abf15SRobert Mustacchi {
1255d14abf15SRobert Mustacchi     dev_info_t * pDev;
1256d14abf15SRobert Mustacchi     int intrTypes = 0;
1257d14abf15SRobert Mustacchi     int intrTotalAlloc = 0;
1258d14abf15SRobert Mustacchi     int numMSIX, numMSI, numFIX;
1259d14abf15SRobert Mustacchi     int rc, i;
1260d14abf15SRobert Mustacchi 
1261d14abf15SRobert Mustacchi     pDev = pUM->pDev;
1262d14abf15SRobert Mustacchi 
1263d14abf15SRobert Mustacchi     atomic_swap_32(&pUM->intrEnabled, B_FALSE);
1264d14abf15SRobert Mustacchi 
1265d14abf15SRobert Mustacchi     if ((rc = ddi_intr_get_supported_types(pDev, &intrTypes)) != DDI_SUCCESS)
1266d14abf15SRobert Mustacchi     {
1267d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to get supported interrupt types (%d)", rc);
1268d14abf15SRobert Mustacchi         return B_FALSE;
1269d14abf15SRobert Mustacchi     }
1270d14abf15SRobert Mustacchi 
1271d14abf15SRobert Mustacchi     numMSIX = BnxeGetInterruptCount(pDev, DDI_INTR_TYPE_MSIX, intrTypes);
1272d14abf15SRobert Mustacchi     numMSI  = BnxeGetInterruptCount(pDev, DDI_INTR_TYPE_MSI, intrTypes);
1273d14abf15SRobert Mustacchi     numFIX  = BnxeGetInterruptCount(pDev, DDI_INTR_TYPE_FIXED, intrTypes);
1274d14abf15SRobert Mustacchi 
1275d14abf15SRobert Mustacchi     if (numFIX <= 0)
1276d14abf15SRobert Mustacchi     {
1277d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Fixed interrupt not supported!");
1278d14abf15SRobert Mustacchi         return B_FALSE;
1279d14abf15SRobert Mustacchi     }
1280d14abf15SRobert Mustacchi 
1281d14abf15SRobert Mustacchi     memset(&pUM->defIntr,  0, sizeof(BnxeIntrBlock));
1282d14abf15SRobert Mustacchi     memset(&pUM->rssIntr,  0, sizeof(BnxeIntrBlock));
1283d14abf15SRobert Mustacchi     memset(&pUM->fcoeIntr, 0, sizeof(BnxeIntrBlock));
1284d14abf15SRobert Mustacchi 
1285d14abf15SRobert Mustacchi     if (pUM->devParams.disableMsix)
1286d14abf15SRobert Mustacchi     {
1287d14abf15SRobert Mustacchi         BnxeLogInfo(pUM, "Forcing fixed level interrupts.");
1288d14abf15SRobert Mustacchi         pUM->lm_dev.params.interrupt_mode = LM_INT_MODE_INTA;
1289d14abf15SRobert Mustacchi         pUM->intrType                     = DDI_INTR_TYPE_FIXED;
1290d14abf15SRobert Mustacchi     }
1291d14abf15SRobert Mustacchi     else if (numMSIX > 0)
1292d14abf15SRobert Mustacchi     {
1293d14abf15SRobert Mustacchi         pUM->lm_dev.params.interrupt_mode = LM_INT_MODE_MIMD;
1294d14abf15SRobert Mustacchi         pUM->intrType                     = DDI_INTR_TYPE_MSIX;
1295d14abf15SRobert Mustacchi     }
1296d14abf15SRobert Mustacchi     else /* numFIX */
1297d14abf15SRobert Mustacchi     {
1298d14abf15SRobert Mustacchi         pUM->lm_dev.params.interrupt_mode = LM_INT_MODE_INTA;
1299d14abf15SRobert Mustacchi         pUM->intrType                     = DDI_INTR_TYPE_FIXED;
1300d14abf15SRobert Mustacchi     }
1301d14abf15SRobert Mustacchi 
1302d14abf15SRobert Mustacchi     while (1)
1303d14abf15SRobert Mustacchi     {
1304d14abf15SRobert Mustacchi         /* allocate the default interrupt */
1305d14abf15SRobert Mustacchi 
1306d14abf15SRobert Mustacchi         if (!BnxeIntrBlockAlloc(pUM,
1307d14abf15SRobert Mustacchi                                 0,
1308d14abf15SRobert Mustacchi                                 1,
1309d14abf15SRobert Mustacchi                                 &pUM->defIntr))
1310d14abf15SRobert Mustacchi         {
1311d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Failed to allocate default %s interrupt!",
1312d14abf15SRobert Mustacchi                         BnxeIntrTypeName(pUM->intrType));
1313d14abf15SRobert Mustacchi             goto BnxeIntrInit_alloc_fail;
1314d14abf15SRobert Mustacchi         }
1315d14abf15SRobert Mustacchi 
1316d14abf15SRobert Mustacchi         intrTotalAlloc++;
1317d14abf15SRobert Mustacchi 
1318d14abf15SRobert Mustacchi         if (pUM->intrType == DDI_INTR_TYPE_FIXED)
1319d14abf15SRobert Mustacchi         {
1320d14abf15SRobert Mustacchi             /* only one interrupt allocated for fixed (default) */
1321d14abf15SRobert Mustacchi             break;
1322d14abf15SRobert Mustacchi         }
1323d14abf15SRobert Mustacchi 
1324d14abf15SRobert Mustacchi         if (BnxeProtoFcoeAfex(pUM))
1325d14abf15SRobert Mustacchi         {
1326d14abf15SRobert Mustacchi             pUM->devParams.numRings = 0;
1327d14abf15SRobert Mustacchi         }
1328d14abf15SRobert Mustacchi         else
1329d14abf15SRobert Mustacchi         {
1330d14abf15SRobert Mustacchi             /* allocate the RSS interrupts */
1331d14abf15SRobert Mustacchi 
1332d14abf15SRobert Mustacchi             while (pUM->devParams.numRings > 0)
1333d14abf15SRobert Mustacchi             {
1334d14abf15SRobert Mustacchi                 if (!BnxeIntrBlockAlloc(pUM,
1335d14abf15SRobert Mustacchi                                         (NDIS_CID(&pUM->lm_dev) + 1),
1336d14abf15SRobert Mustacchi                                         pUM->devParams.numRings,
1337d14abf15SRobert Mustacchi                                         &pUM->rssIntr))
1338d14abf15SRobert Mustacchi                 {
1339d14abf15SRobert Mustacchi                     BnxeLogWarn(pUM, "Failed to allocate %d RSS %s interrupts!",
1340d14abf15SRobert Mustacchi                                 pUM->devParams.numRings,
1341d14abf15SRobert Mustacchi                                 BnxeIntrTypeName(pUM->intrType));
1342d14abf15SRobert Mustacchi                     pUM->devParams.numRings >>= 1;
1343d14abf15SRobert Mustacchi                     continue;
1344d14abf15SRobert Mustacchi                 }
1345d14abf15SRobert Mustacchi 
1346d14abf15SRobert Mustacchi                 break;
1347d14abf15SRobert Mustacchi             }
1348d14abf15SRobert Mustacchi 
1349d14abf15SRobert Mustacchi             if (pUM->devParams.numRings == 0)
1350d14abf15SRobert Mustacchi             {
1351d14abf15SRobert Mustacchi                 BnxeIntrBlockFree(pUM, &pUM->defIntr);
1352d14abf15SRobert Mustacchi                 goto BnxeIntrInit_alloc_fail;
1353d14abf15SRobert Mustacchi             }
1354d14abf15SRobert Mustacchi 
1355d14abf15SRobert Mustacchi             BnxeLogInfo(pUM, "Allocated %d RSS %s interrupts.",
1356d14abf15SRobert Mustacchi                         pUM->rssIntr.intrCount,
1357d14abf15SRobert Mustacchi                         BnxeIntrTypeName(pUM->intrType));
1358d14abf15SRobert Mustacchi 
1359d14abf15SRobert Mustacchi             intrTotalAlloc += pUM->rssIntr.intrCount; /* intrCount <= numRings */
1360d14abf15SRobert Mustacchi         }
1361d14abf15SRobert Mustacchi 
1362d14abf15SRobert Mustacchi         /*
1363d14abf15SRobert Mustacchi          * Allocate the FCoE interrupt only if all available status blocks
1364d14abf15SRobert Mustacchi          * were not taken up by the RSS chains.  If they were then the last
1365d14abf15SRobert Mustacchi          * status block (LM_NON_RSS_SB) is overloaded for both RSS and FCoE.
1366d14abf15SRobert Mustacchi          */
1367d14abf15SRobert Mustacchi 
1368d14abf15SRobert Mustacchi         if (BNXE_FCOE(pUM))
1369d14abf15SRobert Mustacchi         {
1370d14abf15SRobert Mustacchi             if (pUM->rssIntr.intrCount < LM_MAX_RSS_CHAINS(&pUM->lm_dev))
1371d14abf15SRobert Mustacchi             {
1372d14abf15SRobert Mustacchi                 if (!BnxeIntrBlockAlloc(pUM,
1373d14abf15SRobert Mustacchi                                         (LM_NON_RSS_SB(&pUM->lm_dev) + 1),
1374d14abf15SRobert Mustacchi                                         1,
1375d14abf15SRobert Mustacchi                                         &pUM->fcoeIntr))
1376d14abf15SRobert Mustacchi                 {
1377d14abf15SRobert Mustacchi                     BnxeLogWarn(pUM, "Failed to allocate FCoE %s interrupt!",
1378d14abf15SRobert Mustacchi                                 BnxeIntrTypeName(pUM->intrType));
1379d14abf15SRobert Mustacchi                     BnxeIntrBlockFree(pUM, &pUM->defIntr);
1380d14abf15SRobert Mustacchi                     BnxeIntrBlockFree(pUM, &pUM->rssIntr);
1381d14abf15SRobert Mustacchi                     goto BnxeIntrInit_alloc_fail;
1382d14abf15SRobert Mustacchi                 }
1383d14abf15SRobert Mustacchi 
1384d14abf15SRobert Mustacchi                 intrTotalAlloc++;
1385d14abf15SRobert Mustacchi             }
1386d14abf15SRobert Mustacchi             else
1387d14abf15SRobert Mustacchi             {
1388d14abf15SRobert Mustacchi                 /* to be safe, sets fcoeIntr.intrCount to 0 */
1389d14abf15SRobert Mustacchi                 memset(&pUM->fcoeIntr, 0, sizeof(BnxeIntrBlock));
1390d14abf15SRobert Mustacchi             }
1391d14abf15SRobert Mustacchi         }
1392d14abf15SRobert Mustacchi 
1393d14abf15SRobert Mustacchi         break;
1394d14abf15SRobert Mustacchi 
1395d14abf15SRobert Mustacchi BnxeIntrInit_alloc_fail:
1396d14abf15SRobert Mustacchi 
1397d14abf15SRobert Mustacchi         if (pUM->intrType == DDI_INTR_TYPE_FIXED)
1398d14abf15SRobert Mustacchi         {
1399d14abf15SRobert Mustacchi             return B_FALSE;
1400d14abf15SRobert Mustacchi         }
1401d14abf15SRobert Mustacchi 
1402d14abf15SRobert Mustacchi         /* fall back to fixed a retry allocation */
1403d14abf15SRobert Mustacchi         intrTotalAlloc = 0;
1404d14abf15SRobert Mustacchi         pUM->lm_dev.params.interrupt_mode = LM_INT_MODE_INTA;
1405d14abf15SRobert Mustacchi         pUM->intrType                     = DDI_INTR_TYPE_FIXED;
1406d14abf15SRobert Mustacchi     }
1407d14abf15SRobert Mustacchi 
1408d14abf15SRobert Mustacchi     if (pUM->intrType == DDI_INTR_TYPE_MSIX)
1409d14abf15SRobert Mustacchi     {
1410d14abf15SRobert Mustacchi         pUM->devParams.numRings          = pUM->rssIntr.intrCount;
1411d14abf15SRobert Mustacchi         pUM->lm_dev.params.rss_chain_cnt = pUM->rssIntr.intrCount;
1412d14abf15SRobert Mustacchi         pUM->lm_dev.params.tss_chain_cnt = pUM->rssIntr.intrCount;
1413d14abf15SRobert Mustacchi     }
1414d14abf15SRobert Mustacchi     else
1415d14abf15SRobert Mustacchi     {
1416d14abf15SRobert Mustacchi         /* fixed level (no rings)... */
1417d14abf15SRobert Mustacchi         pUM->devParams.numRings          = 0;
1418d14abf15SRobert Mustacchi         pUM->lm_dev.params.rss_chain_cnt = 1;
1419d14abf15SRobert Mustacchi         pUM->lm_dev.params.tss_chain_cnt = 1;
1420d14abf15SRobert Mustacchi 
1421d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Using Fixed Level Interrupts! (set ddi_msix_alloc_limit in /etc/system)");
1422d14abf15SRobert Mustacchi     }
1423d14abf15SRobert Mustacchi 
1424d14abf15SRobert Mustacchi     BnxeLogInfo(pUM, "Interrupts (Supported - %d Fixed / %d MSI / %d MSIX) (Allocated - %d %s)",
1425d14abf15SRobert Mustacchi                 numFIX, numMSI, numMSIX, intrTotalAlloc, BnxeIntrTypeName(pUM->intrType));
1426d14abf15SRobert Mustacchi 
1427d14abf15SRobert Mustacchi     if (!BnxeIntrAddHandlers(pUM))
1428d14abf15SRobert Mustacchi     {
1429d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to add interrupts!");
1430d14abf15SRobert Mustacchi         BnxeIntrBlockFree(pUM, &pUM->defIntr);
1431d14abf15SRobert Mustacchi         BnxeIntrBlockFree(pUM, &pUM->fcoeIntr);
1432d14abf15SRobert Mustacchi         BnxeIntrBlockFree(pUM, &pUM->rssIntr);
1433d14abf15SRobert Mustacchi         return B_FALSE;
1434d14abf15SRobert Mustacchi     }
1435d14abf15SRobert Mustacchi 
1436d14abf15SRobert Mustacchi     /* copy default priority and assume rest are the same (for mutex) */
1437d14abf15SRobert Mustacchi     pUM->intrPriority = pUM->defIntr.intrPriority;
1438d14abf15SRobert Mustacchi 
1439d14abf15SRobert Mustacchi     return B_TRUE;
1440d14abf15SRobert Mustacchi }
1441d14abf15SRobert Mustacchi 
1442d14abf15SRobert Mustacchi 
BnxeIntrFini(um_device_t * pUM)1443d14abf15SRobert Mustacchi void BnxeIntrFini(um_device_t * pUM)
1444d14abf15SRobert Mustacchi {
1445d14abf15SRobert Mustacchi     int i;
1446d14abf15SRobert Mustacchi 
1447d14abf15SRobert Mustacchi     BnxeIntrBlockDisable(pUM, &pUM->defIntr);
1448d14abf15SRobert Mustacchi     BnxeIntrBlockRemoveHandler(pUM, &pUM->defIntr);
1449d14abf15SRobert Mustacchi     BnxeIntrBlockFree(pUM, &pUM->defIntr);
1450d14abf15SRobert Mustacchi 
1451d14abf15SRobert Mustacchi     BnxeIntrBlockDisable(pUM, &pUM->fcoeIntr);
1452d14abf15SRobert Mustacchi     BnxeIntrBlockRemoveHandler(pUM, &pUM->fcoeIntr);
1453d14abf15SRobert Mustacchi     BnxeIntrBlockFree(pUM, &pUM->fcoeIntr);
1454d14abf15SRobert Mustacchi 
1455d14abf15SRobert Mustacchi     BnxeIntrBlockDisable(pUM, &pUM->rssIntr);
1456d14abf15SRobert Mustacchi     BnxeIntrBlockRemoveHandler(pUM, &pUM->rssIntr);
1457d14abf15SRobert Mustacchi     BnxeIntrBlockFree(pUM, &pUM->rssIntr);
1458d14abf15SRobert Mustacchi }
1459d14abf15SRobert Mustacchi 
1460