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