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