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 #ifndef STRINGIFY
42*d14abf15SRobert Mustacchi #define XSTRINGIFY(x) #x
43*d14abf15SRobert Mustacchi #define STRINGIFY(x) XSTRINGIFY(x)
44*d14abf15SRobert Mustacchi #endif
45*d14abf15SRobert Mustacchi
46*d14abf15SRobert Mustacchi #define BNXE_PRODUCT_BANNER "QLogic NetXtreme II 10 Gigabit Ethernet Driver v" STRINGIFY(MAJVERSION) "." STRINGIFY(MINVERSION) "." STRINGIFY(REVVERSION)
47*d14abf15SRobert Mustacchi #define BNXE_PRODUCT_INFO "QLogic NXII 10 GbE v" STRINGIFY(MAJVERSION) "." STRINGIFY(MINVERSION) "." STRINGIFY(REVVERSION)
48*d14abf15SRobert Mustacchi
49*d14abf15SRobert Mustacchi #define BNXE_REGISTER_BAR_NUM 1
50*d14abf15SRobert Mustacchi #define BNXE_REGS_MAP_OFFSET 0
51*d14abf15SRobert Mustacchi #define BNXE_L2_MEMORY_WINDOW_SIZE 0x40000 /* 256K for PCI Config Registers */
52*d14abf15SRobert Mustacchi
53*d14abf15SRobert Mustacchi u32_t dbg_code_path = CP_ALL;
54*d14abf15SRobert Mustacchi u8_t dbg_trace_level = LV_VERBOSE;
55*d14abf15SRobert Mustacchi u32_t g_dbg_flags = 0;
56*d14abf15SRobert Mustacchi
57*d14abf15SRobert Mustacchi kmutex_t bnxeLoaderMutex;
58*d14abf15SRobert Mustacchi u32_t bnxeNumPlumbed;
59*d14abf15SRobert Mustacchi
60*d14abf15SRobert Mustacchi extern ddi_dma_attr_t bnxeDmaPageAttrib;
61*d14abf15SRobert Mustacchi extern ddi_dma_attr_t bnxeRxDmaAttrib;
62*d14abf15SRobert Mustacchi extern ddi_dma_attr_t bnxeTxDmaAttrib;
63*d14abf15SRobert Mustacchi extern ddi_dma_attr_t bnxeTxCbDmaAttrib;
64*d14abf15SRobert Mustacchi
65*d14abf15SRobert Mustacchi
BnxeInstance(void * pDev)66*d14abf15SRobert Mustacchi u8_t BnxeInstance(void * pDev)
67*d14abf15SRobert Mustacchi {
68*d14abf15SRobert Mustacchi um_device_t * pUM = (um_device_t *)pDev;
69*d14abf15SRobert Mustacchi return (pUM == NULL) ? 0xf : pUM->instance;
70*d14abf15SRobert Mustacchi }
71*d14abf15SRobert Mustacchi
72*d14abf15SRobert Mustacchi
73*d14abf15SRobert Mustacchi /* pass in pointer to either lm_device_t or um_device_t */
BnxeDevName(void * pDev)74*d14abf15SRobert Mustacchi char * BnxeDevName(void * pDev)
75*d14abf15SRobert Mustacchi {
76*d14abf15SRobert Mustacchi um_device_t * pUM = (um_device_t *)pDev;
77*d14abf15SRobert Mustacchi return ((pUM == NULL) || (*pUM->devName == 0)) ? "(bnxe)" : pUM->devName;
78*d14abf15SRobert Mustacchi }
79*d14abf15SRobert Mustacchi
80*d14abf15SRobert Mustacchi
BnxeChipName(um_device_t * pUM)81*d14abf15SRobert Mustacchi char * BnxeChipName(um_device_t * pUM)
82*d14abf15SRobert Mustacchi {
83*d14abf15SRobert Mustacchi switch (CHIP_NUM(&pUM->lm_dev) >> 16)
84*d14abf15SRobert Mustacchi {
85*d14abf15SRobert Mustacchi case 0x164e: return "BCM57710";
86*d14abf15SRobert Mustacchi case 0x164f: return "BCM57711";
87*d14abf15SRobert Mustacchi case 0x1650: return "BCM57711E";
88*d14abf15SRobert Mustacchi case 0x1662: return "BCM57712";
89*d14abf15SRobert Mustacchi case 0x1663: return "BCM57712NP";
90*d14abf15SRobert Mustacchi case 0x16a1: return "BCM57840";
91*d14abf15SRobert Mustacchi case 0x168d: return "BCM57840";
92*d14abf15SRobert Mustacchi case 0x16a4: return "BCM57840NP";
93*d14abf15SRobert Mustacchi case 0x16ab: return "BCM57840NP";
94*d14abf15SRobert Mustacchi case 0x168e: return "BCM57810";
95*d14abf15SRobert Mustacchi case 0x16ae: return "BCM57810NP";
96*d14abf15SRobert Mustacchi case 0x168a: return "BCM57800";
97*d14abf15SRobert Mustacchi case 0x16a5: return "BCM57800NP";
98*d14abf15SRobert Mustacchi default: return "UNKNOWN";
99*d14abf15SRobert Mustacchi }
100*d14abf15SRobert Mustacchi }
101*d14abf15SRobert Mustacchi
102*d14abf15SRobert Mustacchi
BnxeProtoSupport(um_device_t * pUM,int proto)103*d14abf15SRobert Mustacchi boolean_t BnxeProtoSupport(um_device_t * pUM, int proto)
104*d14abf15SRobert Mustacchi {
105*d14abf15SRobert Mustacchi boolean_t do_eth;
106*d14abf15SRobert Mustacchi boolean_t do_fcoe;
107*d14abf15SRobert Mustacchi uint32_t port_feature_config_sf;
108*d14abf15SRobert Mustacchi
109*d14abf15SRobert Mustacchi if (IS_MULTI_VNIC(&pUM->lm_dev))
110*d14abf15SRobert Mustacchi {
111*d14abf15SRobert Mustacchi do_eth = B_FALSE;
112*d14abf15SRobert Mustacchi do_fcoe = B_FALSE;
113*d14abf15SRobert Mustacchi
114*d14abf15SRobert Mustacchi if (pUM->lm_dev.hw_info.mcp_detected == 1)
115*d14abf15SRobert Mustacchi {
116*d14abf15SRobert Mustacchi if (pUM->lm_dev.params.mf_proto_support_flags &
117*d14abf15SRobert Mustacchi LM_PROTO_SUPPORT_ETHERNET)
118*d14abf15SRobert Mustacchi {
119*d14abf15SRobert Mustacchi do_eth = B_TRUE;
120*d14abf15SRobert Mustacchi }
121*d14abf15SRobert Mustacchi
122*d14abf15SRobert Mustacchi if (pUM->lm_dev.params.mf_proto_support_flags &
123*d14abf15SRobert Mustacchi LM_PROTO_SUPPORT_FCOE)
124*d14abf15SRobert Mustacchi {
125*d14abf15SRobert Mustacchi do_fcoe = B_TRUE;
126*d14abf15SRobert Mustacchi }
127*d14abf15SRobert Mustacchi }
128*d14abf15SRobert Mustacchi else
129*d14abf15SRobert Mustacchi {
130*d14abf15SRobert Mustacchi /* mcp is not present so allow enumeration */
131*d14abf15SRobert Mustacchi do_eth = B_TRUE;
132*d14abf15SRobert Mustacchi do_fcoe = B_TRUE;
133*d14abf15SRobert Mustacchi }
134*d14abf15SRobert Mustacchi }
135*d14abf15SRobert Mustacchi else /* SF */
136*d14abf15SRobert Mustacchi {
137*d14abf15SRobert Mustacchi do_eth = B_TRUE;
138*d14abf15SRobert Mustacchi do_fcoe = B_FALSE;
139*d14abf15SRobert Mustacchi
140*d14abf15SRobert Mustacchi /* check per port storage personality config from NVRAM */
141*d14abf15SRobert Mustacchi port_feature_config_sf = (pUM->lm_dev.hw_info.port_feature_config &
142*d14abf15SRobert Mustacchi PORT_FEAT_CFG_STORAGE_PERSONALITY_MASK);
143*d14abf15SRobert Mustacchi
144*d14abf15SRobert Mustacchi switch (port_feature_config_sf)
145*d14abf15SRobert Mustacchi {
146*d14abf15SRobert Mustacchi case PORT_FEAT_CFG_STORAGE_PERSONALITY_ISCSI:
147*d14abf15SRobert Mustacchi break;
148*d14abf15SRobert Mustacchi
149*d14abf15SRobert Mustacchi case PORT_FEAT_CFG_STORAGE_PERSONALITY_FCOE:
150*d14abf15SRobert Mustacchi case PORT_FEAT_CFG_STORAGE_PERSONALITY_BOTH:
151*d14abf15SRobert Mustacchi case PORT_FEAT_CFG_STORAGE_PERSONALITY_DEFAULT:
152*d14abf15SRobert Mustacchi default:
153*d14abf15SRobert Mustacchi do_fcoe = B_TRUE;
154*d14abf15SRobert Mustacchi break;
155*d14abf15SRobert Mustacchi }
156*d14abf15SRobert Mustacchi }
157*d14abf15SRobert Mustacchi
158*d14abf15SRobert Mustacchi if (pUM->lm_dev.params.max_func_fcoe_cons == 0)
159*d14abf15SRobert Mustacchi {
160*d14abf15SRobert Mustacchi do_fcoe = B_FALSE;
161*d14abf15SRobert Mustacchi }
162*d14abf15SRobert Mustacchi
163*d14abf15SRobert Mustacchi return (((proto == LM_PROTO_SUPPORT_ETHERNET) && do_eth) ||
164*d14abf15SRobert Mustacchi ((proto == LM_PROTO_SUPPORT_FCOE) && do_fcoe));
165*d14abf15SRobert Mustacchi }
166*d14abf15SRobert Mustacchi
167*d14abf15SRobert Mustacchi
BnxeProtoFcoeAfex(um_device_t * pUM)168*d14abf15SRobert Mustacchi boolean_t BnxeProtoFcoeAfex(um_device_t * pUM)
169*d14abf15SRobert Mustacchi {
170*d14abf15SRobert Mustacchi return ((pUM->lm_dev.params.mf_mode == MULTI_FUNCTION_AFEX) &&
171*d14abf15SRobert Mustacchi BnxeProtoSupport(pUM, LM_PROTO_SUPPORT_FCOE)) ? B_TRUE : B_FALSE;
172*d14abf15SRobert Mustacchi }
173*d14abf15SRobert Mustacchi
174*d14abf15SRobert Mustacchi
BnxePciInit(um_device_t * pUM)175*d14abf15SRobert Mustacchi static boolean_t BnxePciInit(um_device_t * pUM)
176*d14abf15SRobert Mustacchi {
177*d14abf15SRobert Mustacchi /* setup resources needed for accessing the PCI configuration space */
178*d14abf15SRobert Mustacchi if (pci_config_setup(pUM->pDev, &pUM->pPciCfg) != DDI_SUCCESS)
179*d14abf15SRobert Mustacchi {
180*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to setup PCI config");
181*d14abf15SRobert Mustacchi return B_FALSE;
182*d14abf15SRobert Mustacchi }
183*d14abf15SRobert Mustacchi
184*d14abf15SRobert Mustacchi return B_TRUE;
185*d14abf15SRobert Mustacchi }
186*d14abf15SRobert Mustacchi
187*d14abf15SRobert Mustacchi
BnxePciDestroy(um_device_t * pUM)188*d14abf15SRobert Mustacchi static void BnxePciDestroy(um_device_t * pUM)
189*d14abf15SRobert Mustacchi {
190*d14abf15SRobert Mustacchi if (pUM->pPciCfg)
191*d14abf15SRobert Mustacchi {
192*d14abf15SRobert Mustacchi pci_config_teardown(&pUM->pPciCfg);
193*d14abf15SRobert Mustacchi pUM->pPciCfg = NULL;
194*d14abf15SRobert Mustacchi }
195*d14abf15SRobert Mustacchi }
196*d14abf15SRobert Mustacchi
197*d14abf15SRobert Mustacchi
BnxeBarMemDestroy(um_device_t * pUM)198*d14abf15SRobert Mustacchi static void BnxeBarMemDestroy(um_device_t * pUM)
199*d14abf15SRobert Mustacchi {
200*d14abf15SRobert Mustacchi BnxeMemRegion * pMemRegion;
201*d14abf15SRobert Mustacchi
202*d14abf15SRobert Mustacchi /* free the BAR mappings */
203*d14abf15SRobert Mustacchi while (!d_list_is_empty(&pUM->memRegionList))
204*d14abf15SRobert Mustacchi {
205*d14abf15SRobert Mustacchi pMemRegion = (BnxeMemRegion *)d_list_peek_head(&pUM->memRegionList);
206*d14abf15SRobert Mustacchi mm_unmap_io_space(&pUM->lm_dev,
207*d14abf15SRobert Mustacchi pMemRegion->pRegAddr,
208*d14abf15SRobert Mustacchi pMemRegion->size);
209*d14abf15SRobert Mustacchi }
210*d14abf15SRobert Mustacchi }
211*d14abf15SRobert Mustacchi
212*d14abf15SRobert Mustacchi
BnxeMutexInit(um_device_t * pUM)213*d14abf15SRobert Mustacchi static void BnxeMutexInit(um_device_t * pUM)
214*d14abf15SRobert Mustacchi {
215*d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
216*d14abf15SRobert Mustacchi int idx;
217*d14abf15SRobert Mustacchi
218*d14abf15SRobert Mustacchi for (idx = 0; idx < (MAX_RSS_CHAINS + 1); idx++)
219*d14abf15SRobert Mustacchi {
220*d14abf15SRobert Mustacchi mutex_init(&pUM->intrMutex[idx], NULL,
221*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
222*d14abf15SRobert Mustacchi mutex_init(&pUM->intrFlipMutex[idx], NULL,
223*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
224*d14abf15SRobert Mustacchi mutex_init(&pUM->sbMutex[idx], NULL,
225*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
226*d14abf15SRobert Mustacchi }
227*d14abf15SRobert Mustacchi
228*d14abf15SRobert Mustacchi for (idx = 0; idx < MAX_ETH_CONS; idx++)
229*d14abf15SRobert Mustacchi {
230*d14abf15SRobert Mustacchi mutex_init(&pUM->txq[idx].txMutex, NULL,
231*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
232*d14abf15SRobert Mustacchi mutex_init(&pUM->txq[idx].freeTxDescMutex, NULL,
233*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
234*d14abf15SRobert Mustacchi pUM->txq[idx].pUM = pUM;
235*d14abf15SRobert Mustacchi pUM->txq[idx].idx = idx;
236*d14abf15SRobert Mustacchi }
237*d14abf15SRobert Mustacchi
238*d14abf15SRobert Mustacchi for (idx = 0; idx < MAX_ETH_CONS; idx++)
239*d14abf15SRobert Mustacchi {
240*d14abf15SRobert Mustacchi mutex_init(&pUM->rxq[idx].rxMutex, NULL,
241*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
242*d14abf15SRobert Mustacchi mutex_init(&pUM->rxq[idx].doneRxMutex, NULL,
243*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
244*d14abf15SRobert Mustacchi pUM->rxq[idx].pUM = pUM;
245*d14abf15SRobert Mustacchi pUM->rxq[idx].idx = idx;
246*d14abf15SRobert Mustacchi }
247*d14abf15SRobert Mustacchi
248*d14abf15SRobert Mustacchi for (idx = 0; idx < USER_OPTION_RX_RING_GROUPS_MAX; idx++)
249*d14abf15SRobert Mustacchi {
250*d14abf15SRobert Mustacchi pUM->rxqGroup[idx].pUM = pUM;
251*d14abf15SRobert Mustacchi pUM->rxqGroup[idx].idx = idx;
252*d14abf15SRobert Mustacchi }
253*d14abf15SRobert Mustacchi
254*d14abf15SRobert Mustacchi mutex_init(&pUM->ethConMutex, NULL,
255*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
256*d14abf15SRobert Mustacchi mutex_init(&pUM->mcpMutex, NULL,
257*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
258*d14abf15SRobert Mustacchi mutex_init(&pUM->phyMutex, NULL,
259*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
260*d14abf15SRobert Mustacchi mutex_init(&pUM->indMutex, NULL,
261*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
262*d14abf15SRobert Mustacchi mutex_init(&pUM->cidMutex, NULL,
263*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
264*d14abf15SRobert Mustacchi mutex_init(&pUM->spqMutex, NULL,
265*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
266*d14abf15SRobert Mustacchi mutex_init(&pUM->spReqMutex, NULL,
267*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
268*d14abf15SRobert Mustacchi mutex_init(&pUM->rrReqMutex, NULL,
269*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
270*d14abf15SRobert Mustacchi mutex_init(&pUM->islesCtrlMutex, NULL,
271*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
272*d14abf15SRobert Mustacchi mutex_init(&pUM->toeMutex, NULL,
273*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
274*d14abf15SRobert Mustacchi mutex_init(&pUM->memMutex, NULL,
275*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
276*d14abf15SRobert Mustacchi mutex_init(&pUM->offloadMutex, NULL,
277*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
278*d14abf15SRobert Mustacchi mutex_init(&pUM->hwInitMutex, NULL,
279*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
280*d14abf15SRobert Mustacchi mutex_init(&pUM->gldMutex, NULL,
281*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
282*d14abf15SRobert Mustacchi rw_init(&pUM->gldTxMutex, NULL, RW_DRIVER, NULL);
283*d14abf15SRobert Mustacchi mutex_init(&pUM->timerMutex, NULL,
284*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
285*d14abf15SRobert Mustacchi mutex_init(&pUM->kstatMutex, NULL,
286*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
287*d14abf15SRobert Mustacchi }
288*d14abf15SRobert Mustacchi
289*d14abf15SRobert Mustacchi
BnxeMutexDestroy(um_device_t * pUM)290*d14abf15SRobert Mustacchi static void BnxeMutexDestroy(um_device_t * pUM)
291*d14abf15SRobert Mustacchi {
292*d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
293*d14abf15SRobert Mustacchi int idx;
294*d14abf15SRobert Mustacchi
295*d14abf15SRobert Mustacchi for (idx = 0; idx < (MAX_RSS_CHAINS + 1); idx++)
296*d14abf15SRobert Mustacchi {
297*d14abf15SRobert Mustacchi mutex_destroy(&pUM->intrMutex[idx]);
298*d14abf15SRobert Mustacchi mutex_destroy(&pUM->intrFlipMutex[idx]);
299*d14abf15SRobert Mustacchi mutex_destroy(&pUM->sbMutex[idx]);
300*d14abf15SRobert Mustacchi }
301*d14abf15SRobert Mustacchi
302*d14abf15SRobert Mustacchi for (idx = 0; idx < MAX_ETH_CONS; idx++)
303*d14abf15SRobert Mustacchi {
304*d14abf15SRobert Mustacchi mutex_destroy(&pUM->txq[idx].txMutex);
305*d14abf15SRobert Mustacchi mutex_destroy(&pUM->txq[idx].freeTxDescMutex);
306*d14abf15SRobert Mustacchi }
307*d14abf15SRobert Mustacchi
308*d14abf15SRobert Mustacchi for (idx = 0; idx < MAX_ETH_CONS; idx++)
309*d14abf15SRobert Mustacchi {
310*d14abf15SRobert Mustacchi mutex_destroy(&pUM->rxq[idx].rxMutex);
311*d14abf15SRobert Mustacchi mutex_destroy(&pUM->rxq[idx].doneRxMutex);
312*d14abf15SRobert Mustacchi }
313*d14abf15SRobert Mustacchi
314*d14abf15SRobert Mustacchi mutex_destroy(&pUM->ethConMutex);
315*d14abf15SRobert Mustacchi mutex_destroy(&pUM->mcpMutex);
316*d14abf15SRobert Mustacchi mutex_destroy(&pUM->phyMutex);
317*d14abf15SRobert Mustacchi mutex_destroy(&pUM->indMutex);
318*d14abf15SRobert Mustacchi mutex_destroy(&pUM->cidMutex);
319*d14abf15SRobert Mustacchi mutex_destroy(&pUM->spqMutex);
320*d14abf15SRobert Mustacchi mutex_destroy(&pUM->spReqMutex);
321*d14abf15SRobert Mustacchi mutex_destroy(&pUM->rrReqMutex);
322*d14abf15SRobert Mustacchi mutex_destroy(&pUM->islesCtrlMutex);
323*d14abf15SRobert Mustacchi mutex_destroy(&pUM->toeMutex);
324*d14abf15SRobert Mustacchi mutex_destroy(&pUM->memMutex); /* not until all mem deleted */
325*d14abf15SRobert Mustacchi mutex_destroy(&pUM->offloadMutex);
326*d14abf15SRobert Mustacchi mutex_destroy(&pUM->hwInitMutex);
327*d14abf15SRobert Mustacchi mutex_destroy(&pUM->gldMutex);
328*d14abf15SRobert Mustacchi rw_destroy(&pUM->gldTxMutex);
329*d14abf15SRobert Mustacchi mutex_destroy(&pUM->timerMutex);
330*d14abf15SRobert Mustacchi mutex_destroy(&pUM->kstatMutex);
331*d14abf15SRobert Mustacchi }
332*d14abf15SRobert Mustacchi
333*d14abf15SRobert Mustacchi
334*d14abf15SRobert Mustacchi /* FMA support */
335*d14abf15SRobert Mustacchi
BnxeCheckAccHandle(ddi_acc_handle_t handle)336*d14abf15SRobert Mustacchi int BnxeCheckAccHandle(ddi_acc_handle_t handle)
337*d14abf15SRobert Mustacchi {
338*d14abf15SRobert Mustacchi ddi_fm_error_t de;
339*d14abf15SRobert Mustacchi
340*d14abf15SRobert Mustacchi ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
341*d14abf15SRobert Mustacchi ddi_fm_acc_err_clear(handle, DDI_FME_VERSION);
342*d14abf15SRobert Mustacchi
343*d14abf15SRobert Mustacchi return (de.fme_status);
344*d14abf15SRobert Mustacchi }
345*d14abf15SRobert Mustacchi
346*d14abf15SRobert Mustacchi
BnxeCheckDmaHandle(ddi_dma_handle_t handle)347*d14abf15SRobert Mustacchi int BnxeCheckDmaHandle(ddi_dma_handle_t handle)
348*d14abf15SRobert Mustacchi {
349*d14abf15SRobert Mustacchi ddi_fm_error_t de;
350*d14abf15SRobert Mustacchi
351*d14abf15SRobert Mustacchi ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
352*d14abf15SRobert Mustacchi
353*d14abf15SRobert Mustacchi return (de.fme_status);
354*d14abf15SRobert Mustacchi }
355*d14abf15SRobert Mustacchi
356*d14abf15SRobert Mustacchi
357*d14abf15SRobert Mustacchi /* The IO fault service error handling callback function */
BnxeFmErrorCb(dev_info_t * pDev,ddi_fm_error_t * err,const void * impl_data)358*d14abf15SRobert Mustacchi static int BnxeFmErrorCb(dev_info_t * pDev,
359*d14abf15SRobert Mustacchi ddi_fm_error_t * err,
360*d14abf15SRobert Mustacchi const void * impl_data)
361*d14abf15SRobert Mustacchi {
362*d14abf15SRobert Mustacchi /*
363*d14abf15SRobert Mustacchi * As the driver can always deal with an error in any dma or
364*d14abf15SRobert Mustacchi * access handle, we can just return the fme_status value.
365*d14abf15SRobert Mustacchi */
366*d14abf15SRobert Mustacchi pci_ereport_post(pDev, err, NULL);
367*d14abf15SRobert Mustacchi
368*d14abf15SRobert Mustacchi return (err->fme_status);
369*d14abf15SRobert Mustacchi }
370*d14abf15SRobert Mustacchi
371*d14abf15SRobert Mustacchi
BnxeFmInit(um_device_t * pUM)372*d14abf15SRobert Mustacchi static void BnxeFmInit(um_device_t * pUM)
373*d14abf15SRobert Mustacchi {
374*d14abf15SRobert Mustacchi ddi_iblock_cookie_t iblk;
375*d14abf15SRobert Mustacchi int fma_acc_flag;
376*d14abf15SRobert Mustacchi int fma_dma_flag;
377*d14abf15SRobert Mustacchi
378*d14abf15SRobert Mustacchi /* Only register with IO Fault Services if we have some capability */
379*d14abf15SRobert Mustacchi if (pUM->fmCapabilities & DDI_FM_ACCCHK_CAPABLE)
380*d14abf15SRobert Mustacchi {
381*d14abf15SRobert Mustacchi bnxeAccessAttribBAR.devacc_attr_version = DDI_DEVICE_ATTR_V1;
382*d14abf15SRobert Mustacchi bnxeAccessAttribBAR.devacc_attr_access = DDI_FLAGERR_ACC;
383*d14abf15SRobert Mustacchi }
384*d14abf15SRobert Mustacchi
385*d14abf15SRobert Mustacchi if (pUM->fmCapabilities & DDI_FM_DMACHK_CAPABLE)
386*d14abf15SRobert Mustacchi {
387*d14abf15SRobert Mustacchi bnxeDmaPageAttrib.dma_attr_flags = DDI_DMA_FLAGERR;
388*d14abf15SRobert Mustacchi bnxeRxDmaAttrib.dma_attr_flags = DDI_DMA_FLAGERR;
389*d14abf15SRobert Mustacchi bnxeTxDmaAttrib.dma_attr_flags = DDI_DMA_FLAGERR;
390*d14abf15SRobert Mustacchi bnxeTxCbDmaAttrib.dma_attr_flags = DDI_DMA_FLAGERR;
391*d14abf15SRobert Mustacchi }
392*d14abf15SRobert Mustacchi
393*d14abf15SRobert Mustacchi if (pUM->fmCapabilities)
394*d14abf15SRobert Mustacchi {
395*d14abf15SRobert Mustacchi /* Register capabilities with IO Fault Services */
396*d14abf15SRobert Mustacchi ddi_fm_init(pUM->pDev, &pUM->fmCapabilities, &iblk);
397*d14abf15SRobert Mustacchi
398*d14abf15SRobert Mustacchi /* Initialize pci ereport capabilities if ereport capable */
399*d14abf15SRobert Mustacchi if (DDI_FM_EREPORT_CAP(pUM->fmCapabilities) ||
400*d14abf15SRobert Mustacchi DDI_FM_ERRCB_CAP(pUM->fmCapabilities))
401*d14abf15SRobert Mustacchi {
402*d14abf15SRobert Mustacchi pci_ereport_setup(pUM->pDev);
403*d14abf15SRobert Mustacchi }
404*d14abf15SRobert Mustacchi
405*d14abf15SRobert Mustacchi /* Register error callback if error callback capable */
406*d14abf15SRobert Mustacchi if (DDI_FM_ERRCB_CAP(pUM->fmCapabilities))
407*d14abf15SRobert Mustacchi {
408*d14abf15SRobert Mustacchi ddi_fm_handler_register(pUM->pDev, BnxeFmErrorCb, (void *)pUM);
409*d14abf15SRobert Mustacchi }
410*d14abf15SRobert Mustacchi }
411*d14abf15SRobert Mustacchi }
412*d14abf15SRobert Mustacchi
413*d14abf15SRobert Mustacchi
BnxeFmFini(um_device_t * pUM)414*d14abf15SRobert Mustacchi static void BnxeFmFini(um_device_t * pUM)
415*d14abf15SRobert Mustacchi {
416*d14abf15SRobert Mustacchi /* Only unregister FMA capabilities if we registered some */
417*d14abf15SRobert Mustacchi if (pUM->fmCapabilities)
418*d14abf15SRobert Mustacchi {
419*d14abf15SRobert Mustacchi /* Release any resources allocated by pci_ereport_setup() */
420*d14abf15SRobert Mustacchi if (DDI_FM_EREPORT_CAP(pUM->fmCapabilities) ||
421*d14abf15SRobert Mustacchi DDI_FM_ERRCB_CAP(pUM->fmCapabilities))
422*d14abf15SRobert Mustacchi {
423*d14abf15SRobert Mustacchi pci_ereport_teardown(pUM->pDev);
424*d14abf15SRobert Mustacchi }
425*d14abf15SRobert Mustacchi
426*d14abf15SRobert Mustacchi /* Un-register error callback if error callback capable */
427*d14abf15SRobert Mustacchi if (DDI_FM_ERRCB_CAP(pUM->fmCapabilities))
428*d14abf15SRobert Mustacchi {
429*d14abf15SRobert Mustacchi ddi_fm_handler_unregister(pUM->pDev);
430*d14abf15SRobert Mustacchi }
431*d14abf15SRobert Mustacchi
432*d14abf15SRobert Mustacchi /* Unregister from IO Fault Services */
433*d14abf15SRobert Mustacchi ddi_fm_fini(pUM->pDev);
434*d14abf15SRobert Mustacchi }
435*d14abf15SRobert Mustacchi }
436*d14abf15SRobert Mustacchi
437*d14abf15SRobert Mustacchi
BnxeFmErrorReport(um_device_t * pUM,char * detail)438*d14abf15SRobert Mustacchi void BnxeFmErrorReport(um_device_t * pUM,
439*d14abf15SRobert Mustacchi char * detail)
440*d14abf15SRobert Mustacchi {
441*d14abf15SRobert Mustacchi uint64_t ena;
442*d14abf15SRobert Mustacchi char buf[FM_MAX_CLASS];
443*d14abf15SRobert Mustacchi
444*d14abf15SRobert Mustacchi (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
445*d14abf15SRobert Mustacchi
446*d14abf15SRobert Mustacchi ena = fm_ena_generate(0, FM_ENA_FMT1);
447*d14abf15SRobert Mustacchi
448*d14abf15SRobert Mustacchi if (DDI_FM_EREPORT_CAP(pUM->fmCapabilities))
449*d14abf15SRobert Mustacchi {
450*d14abf15SRobert Mustacchi ddi_fm_ereport_post(pUM->pDev, buf, ena, DDI_NOSLEEP,
451*d14abf15SRobert Mustacchi FM_VERSION, DATA_TYPE_UINT8,
452*d14abf15SRobert Mustacchi FM_EREPORT_VERS0, NULL);
453*d14abf15SRobert Mustacchi }
454*d14abf15SRobert Mustacchi }
455*d14abf15SRobert Mustacchi
456*d14abf15SRobert Mustacchi
BnxeAttachDevice(um_device_t * pUM)457*d14abf15SRobert Mustacchi static boolean_t BnxeAttachDevice(um_device_t * pUM)
458*d14abf15SRobert Mustacchi {
459*d14abf15SRobert Mustacchi int rc;
460*d14abf15SRobert Mustacchi int * props = NULL;
461*d14abf15SRobert Mustacchi uint_t numProps;
462*d14abf15SRobert Mustacchi u32_t vendor_id;
463*d14abf15SRobert Mustacchi u32_t device_id;
464*d14abf15SRobert Mustacchi
465*d14abf15SRobert Mustacchi /* fm-capable in bnxe.conf can be used to set fmCapabilities. */
466*d14abf15SRobert Mustacchi pUM->fmCapabilities = ddi_prop_get_int(DDI_DEV_T_ANY,
467*d14abf15SRobert Mustacchi pUM->pDev,
468*d14abf15SRobert Mustacchi DDI_PROP_DONTPASS,
469*d14abf15SRobert Mustacchi "fm-capable",
470*d14abf15SRobert Mustacchi (DDI_FM_EREPORT_CAPABLE |
471*d14abf15SRobert Mustacchi DDI_FM_ACCCHK_CAPABLE |
472*d14abf15SRobert Mustacchi DDI_FM_DMACHK_CAPABLE |
473*d14abf15SRobert Mustacchi DDI_FM_ERRCB_CAPABLE));
474*d14abf15SRobert Mustacchi
475*d14abf15SRobert Mustacchi /* Register capabilities with IO Fault Services. */
476*d14abf15SRobert Mustacchi BnxeFmInit(pUM);
477*d14abf15SRobert Mustacchi
478*d14abf15SRobert Mustacchi if (!BnxePciInit(pUM))
479*d14abf15SRobert Mustacchi {
480*d14abf15SRobert Mustacchi BnxeFmFini(pUM);
481*d14abf15SRobert Mustacchi
482*d14abf15SRobert Mustacchi return B_FALSE;
483*d14abf15SRobert Mustacchi }
484*d14abf15SRobert Mustacchi
485*d14abf15SRobert Mustacchi BnxeMutexInit(pUM);
486*d14abf15SRobert Mustacchi
487*d14abf15SRobert Mustacchi if (!BnxeWorkQueueInit(pUM))
488*d14abf15SRobert Mustacchi {
489*d14abf15SRobert Mustacchi return B_FALSE;
490*d14abf15SRobert Mustacchi }
491*d14abf15SRobert Mustacchi
492*d14abf15SRobert Mustacchi rc = lm_get_dev_info(&pUM->lm_dev);
493*d14abf15SRobert Mustacchi
494*d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
495*d14abf15SRobert Mustacchi BnxeCheckAccHandle(pUM->pPciCfg) != DDI_FM_OK)
496*d14abf15SRobert Mustacchi {
497*d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_LOST);
498*d14abf15SRobert Mustacchi BnxeWorkQueueWaitAndDestroy(pUM);
499*d14abf15SRobert Mustacchi BnxeMutexDestroy(pUM);
500*d14abf15SRobert Mustacchi BnxePciDestroy(pUM);
501*d14abf15SRobert Mustacchi BnxeFmFini(pUM);
502*d14abf15SRobert Mustacchi
503*d14abf15SRobert Mustacchi return B_FALSE;
504*d14abf15SRobert Mustacchi }
505*d14abf15SRobert Mustacchi
506*d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
507*d14abf15SRobert Mustacchi BnxeCheckAccHandle(pUM->lm_dev.vars.reg_handle[BAR_0]) != DDI_FM_OK)
508*d14abf15SRobert Mustacchi {
509*d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_LOST);
510*d14abf15SRobert Mustacchi BnxeWorkQueueWaitAndDestroy(pUM);
511*d14abf15SRobert Mustacchi BnxeMutexDestroy(pUM);
512*d14abf15SRobert Mustacchi BnxePciDestroy(pUM);
513*d14abf15SRobert Mustacchi BnxeFmFini(pUM);
514*d14abf15SRobert Mustacchi
515*d14abf15SRobert Mustacchi return B_FALSE;
516*d14abf15SRobert Mustacchi }
517*d14abf15SRobert Mustacchi
518*d14abf15SRobert Mustacchi if (rc != LM_STATUS_SUCCESS)
519*d14abf15SRobert Mustacchi {
520*d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
521*d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_LOST);
522*d14abf15SRobert Mustacchi BnxeWorkQueueWaitAndDestroy(pUM);
523*d14abf15SRobert Mustacchi BnxeMutexDestroy(pUM);
524*d14abf15SRobert Mustacchi BnxePciDestroy(pUM);
525*d14abf15SRobert Mustacchi BnxeFmFini(pUM);
526*d14abf15SRobert Mustacchi
527*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to get device information");
528*d14abf15SRobert Mustacchi return B_FALSE;
529*d14abf15SRobert Mustacchi }
530*d14abf15SRobert Mustacchi
531*d14abf15SRobert Mustacchi #if 0
532*d14abf15SRobert Mustacchi if (IS_PFDEV(&pUM->lm_dev) && lm_check_if_pf_assigned_to_vm(&pUM->lm_dev))
533*d14abf15SRobert Mustacchi {
534*d14abf15SRobert Mustacchi lm_set_virt_mode(&pUM->lm_dev, DEVICE_TYPE_PF, VT_ASSIGNED_TO_VM_PF);
535*d14abf15SRobert Mustacchi }
536*d14abf15SRobert Mustacchi #endif
537*d14abf15SRobert Mustacchi
538*d14abf15SRobert Mustacchi /* check if FCoE is enabled on this function */
539*d14abf15SRobert Mustacchi #if 0
540*d14abf15SRobert Mustacchi pUM->do_fcoe =
541*d14abf15SRobert Mustacchi ((CHIP_IS_E2(&pUM->lm_dev) || CHIP_IS_E3(&pUM->lm_dev)) &&
542*d14abf15SRobert Mustacchi BnxeProtoSupport(pUM, LM_PROTO_SUPPORT_FCOE)) ? B_TRUE :
543*d14abf15SRobert Mustacchi B_FALSE;
544*d14abf15SRobert Mustacchi #else
545*d14abf15SRobert Mustacchi pUM->do_fcoe = B_FALSE;
546*d14abf15SRobert Mustacchi #endif
547*d14abf15SRobert Mustacchi
548*d14abf15SRobert Mustacchi lm_get_iscsi_boot_info_block(&pUM->lm_dev, &pUM->iscsiInfo);
549*d14abf15SRobert Mustacchi if (pUM->iscsiInfo.signature != 0)
550*d14abf15SRobert Mustacchi {
551*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "MBA FCoE boot occurred on this interface.");
552*d14abf15SRobert Mustacchi }
553*d14abf15SRobert Mustacchi
554*d14abf15SRobert Mustacchi if (!BnxeIntrInit(pUM))
555*d14abf15SRobert Mustacchi {
556*d14abf15SRobert Mustacchi BnxeBarMemDestroy(pUM);
557*d14abf15SRobert Mustacchi BnxeWorkQueueWaitAndDestroy(pUM);
558*d14abf15SRobert Mustacchi BnxeMutexDestroy(pUM);
559*d14abf15SRobert Mustacchi BnxePciDestroy(pUM);
560*d14abf15SRobert Mustacchi BnxeFmFini(pUM);
561*d14abf15SRobert Mustacchi
562*d14abf15SRobert Mustacchi return B_FALSE;
563*d14abf15SRobert Mustacchi }
564*d14abf15SRobert Mustacchi
565*d14abf15SRobert Mustacchi if (!BnxeKstatInit(pUM))
566*d14abf15SRobert Mustacchi {
567*d14abf15SRobert Mustacchi BnxeIntrFini(pUM);
568*d14abf15SRobert Mustacchi BnxeBarMemDestroy(pUM);
569*d14abf15SRobert Mustacchi BnxeWorkQueueWaitAndDestroy(pUM);
570*d14abf15SRobert Mustacchi BnxeMutexDestroy(pUM);
571*d14abf15SRobert Mustacchi BnxePciDestroy(pUM);
572*d14abf15SRobert Mustacchi BnxeFmFini(pUM);
573*d14abf15SRobert Mustacchi
574*d14abf15SRobert Mustacchi return B_FALSE;
575*d14abf15SRobert Mustacchi }
576*d14abf15SRobert Mustacchi
577*d14abf15SRobert Mustacchi if (BnxeProtoFcoeAfex(pUM))
578*d14abf15SRobert Mustacchi {
579*d14abf15SRobert Mustacchi /* No support for L2 on FCoE enabled AFEX function! */
580*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "FCoE AFEX function, not registering with GLD.");
581*d14abf15SRobert Mustacchi #if 0
582*d14abf15SRobert Mustacchi /*
583*d14abf15SRobert Mustacchi * The following is wonky. Doing a CLONE_DEV makes it visible to
584*d14abf15SRobert Mustacchi * various L2 networking commands even though the instance was
585*d14abf15SRobert Mustacchi * not registered with GLDv3 via mac_register().
586*d14abf15SRobert Mustacchi */
587*d14abf15SRobert Mustacchi
588*d14abf15SRobert Mustacchi /* Create a style-2 DLPI device */
589*d14abf15SRobert Mustacchi if (ddi_create_minor_node(pUM->pDev,
590*d14abf15SRobert Mustacchi (char *)ddi_driver_name(pUM->pDev),
591*d14abf15SRobert Mustacchi S_IFCHR,
592*d14abf15SRobert Mustacchi 0,
593*d14abf15SRobert Mustacchi DDI_PSEUDO, //DDI_NT_NET,
594*d14abf15SRobert Mustacchi CLONE_DEV) != DDI_SUCCESS)
595*d14abf15SRobert Mustacchi {
596*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to create device minor node.");
597*d14abf15SRobert Mustacchi BnxeKstatFini(pUM);
598*d14abf15SRobert Mustacchi BnxeIntrFini(pUM);
599*d14abf15SRobert Mustacchi BnxeBarMemDestroy(pUM);
600*d14abf15SRobert Mustacchi BnxeWorkQueueWaitAndDestroy(pUM);
601*d14abf15SRobert Mustacchi BnxeMutexDestroy(pUM);
602*d14abf15SRobert Mustacchi BnxePciDestroy(pUM);
603*d14abf15SRobert Mustacchi BnxeFmFini(pUM);
604*d14abf15SRobert Mustacchi
605*d14abf15SRobert Mustacchi return B_FALSE;
606*d14abf15SRobert Mustacchi }
607*d14abf15SRobert Mustacchi
608*d14abf15SRobert Mustacchi /* Create a style-1 DLPI device */
609*d14abf15SRobert Mustacchi if (ddi_create_minor_node(pUM->pDev,
610*d14abf15SRobert Mustacchi pUM->devName,
611*d14abf15SRobert Mustacchi S_IFCHR,
612*d14abf15SRobert Mustacchi pUM->instance,
613*d14abf15SRobert Mustacchi DDI_PSEUDO, //DDI_NT_NET,
614*d14abf15SRobert Mustacchi 0) != DDI_SUCCESS)
615*d14abf15SRobert Mustacchi {
616*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to create device instance minor node.");
617*d14abf15SRobert Mustacchi ddi_remove_minor_node(pUM->pDev, (char *)ddi_driver_name(pUM->pDev));
618*d14abf15SRobert Mustacchi BnxeKstatFini(pUM);
619*d14abf15SRobert Mustacchi BnxeIntrFini(pUM);
620*d14abf15SRobert Mustacchi BnxeBarMemDestroy(pUM);
621*d14abf15SRobert Mustacchi BnxeWorkQueueWaitAndDestroy(pUM);
622*d14abf15SRobert Mustacchi BnxeMutexDestroy(pUM);
623*d14abf15SRobert Mustacchi BnxePciDestroy(pUM);
624*d14abf15SRobert Mustacchi BnxeFmFini(pUM);
625*d14abf15SRobert Mustacchi
626*d14abf15SRobert Mustacchi return B_FALSE;
627*d14abf15SRobert Mustacchi }
628*d14abf15SRobert Mustacchi #endif
629*d14abf15SRobert Mustacchi }
630*d14abf15SRobert Mustacchi else
631*d14abf15SRobert Mustacchi {
632*d14abf15SRobert Mustacchi /* register with the GLDv3 MAC layer */
633*d14abf15SRobert Mustacchi if (!BnxeGldInit(pUM))
634*d14abf15SRobert Mustacchi {
635*d14abf15SRobert Mustacchi BnxeKstatFini(pUM);
636*d14abf15SRobert Mustacchi BnxeIntrFini(pUM);
637*d14abf15SRobert Mustacchi BnxeBarMemDestroy(pUM);
638*d14abf15SRobert Mustacchi BnxeWorkQueueWaitAndDestroy(pUM);
639*d14abf15SRobert Mustacchi BnxeMutexDestroy(pUM);
640*d14abf15SRobert Mustacchi BnxePciDestroy(pUM);
641*d14abf15SRobert Mustacchi BnxeFmFini(pUM);
642*d14abf15SRobert Mustacchi
643*d14abf15SRobert Mustacchi return B_FALSE;
644*d14abf15SRobert Mustacchi }
645*d14abf15SRobert Mustacchi }
646*d14abf15SRobert Mustacchi
647*d14abf15SRobert Mustacchi snprintf(pUM->version,
648*d14abf15SRobert Mustacchi sizeof(pUM->version),
649*d14abf15SRobert Mustacchi "%d.%d.%d",
650*d14abf15SRobert Mustacchi MAJVERSION,
651*d14abf15SRobert Mustacchi MINVERSION,
652*d14abf15SRobert Mustacchi REVVERSION);
653*d14abf15SRobert Mustacchi
654*d14abf15SRobert Mustacchi snprintf(pUM->versionLM,
655*d14abf15SRobert Mustacchi sizeof(pUM->versionLM),
656*d14abf15SRobert Mustacchi "%d.%d.%d",
657*d14abf15SRobert Mustacchi LM_DRIVER_MAJOR_VER,
658*d14abf15SRobert Mustacchi LM_DRIVER_MINOR_VER,
659*d14abf15SRobert Mustacchi LM_DRIVER_FIX_NUM);
660*d14abf15SRobert Mustacchi
661*d14abf15SRobert Mustacchi snprintf(pUM->versionFW,
662*d14abf15SRobert Mustacchi sizeof(pUM->versionFW),
663*d14abf15SRobert Mustacchi "%d.%d.%d.%d",
664*d14abf15SRobert Mustacchi BCM_5710_FW_MAJOR_VERSION,
665*d14abf15SRobert Mustacchi BCM_5710_FW_MINOR_VERSION,
666*d14abf15SRobert Mustacchi BCM_5710_FW_REVISION_VERSION,
667*d14abf15SRobert Mustacchi BCM_5710_FW_ENGINEERING_VERSION);
668*d14abf15SRobert Mustacchi
669*d14abf15SRobert Mustacchi snprintf(pUM->versionBC,
670*d14abf15SRobert Mustacchi sizeof(pUM->versionBC),
671*d14abf15SRobert Mustacchi "%d.%d.%d",
672*d14abf15SRobert Mustacchi ((pUM->lm_dev.hw_info.bc_rev >> 24) & 0xff),
673*d14abf15SRobert Mustacchi ((pUM->lm_dev.hw_info.bc_rev >> 16) & 0xff),
674*d14abf15SRobert Mustacchi ((pUM->lm_dev.hw_info.bc_rev >> 8) & 0xff));
675*d14abf15SRobert Mustacchi
676*d14abf15SRobert Mustacchi snprintf(pUM->chipName,
677*d14abf15SRobert Mustacchi sizeof(pUM->chipName),
678*d14abf15SRobert Mustacchi "%s",
679*d14abf15SRobert Mustacchi BnxeChipName(pUM));
680*d14abf15SRobert Mustacchi
681*d14abf15SRobert Mustacchi snprintf(pUM->chipID,
682*d14abf15SRobert Mustacchi sizeof(pUM->chipID),
683*d14abf15SRobert Mustacchi "0x%x",
684*d14abf15SRobert Mustacchi pUM->lm_dev.hw_info.chip_id);
685*d14abf15SRobert Mustacchi
686*d14abf15SRobert Mustacchi *pUM->bus_dev_func = 0;
687*d14abf15SRobert Mustacchi rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, pUM->pDev,
688*d14abf15SRobert Mustacchi 0, "reg", &props, &numProps);
689*d14abf15SRobert Mustacchi if ((rc == DDI_PROP_SUCCESS) && (numProps > 0))
690*d14abf15SRobert Mustacchi {
691*d14abf15SRobert Mustacchi snprintf(pUM->bus_dev_func,
692*d14abf15SRobert Mustacchi sizeof(pUM->bus_dev_func),
693*d14abf15SRobert Mustacchi "%04x:%02x:%02x",
694*d14abf15SRobert Mustacchi PCI_REG_BUS_G(props[0]),
695*d14abf15SRobert Mustacchi PCI_REG_DEV_G(props[0]),
696*d14abf15SRobert Mustacchi PCI_REG_FUNC_G(props[0]));
697*d14abf15SRobert Mustacchi ddi_prop_free(props);
698*d14abf15SRobert Mustacchi }
699*d14abf15SRobert Mustacchi
700*d14abf15SRobert Mustacchi vendor_id = 0;
701*d14abf15SRobert Mustacchi rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, pUM->pDev,
702*d14abf15SRobert Mustacchi 0, "vendor-id", &props, &numProps);
703*d14abf15SRobert Mustacchi if ((rc == DDI_PROP_SUCCESS) && (numProps > 0))
704*d14abf15SRobert Mustacchi {
705*d14abf15SRobert Mustacchi vendor_id = props[0];
706*d14abf15SRobert Mustacchi ddi_prop_free(props);
707*d14abf15SRobert Mustacchi }
708*d14abf15SRobert Mustacchi
709*d14abf15SRobert Mustacchi device_id = 0;
710*d14abf15SRobert Mustacchi rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, pUM->pDev,
711*d14abf15SRobert Mustacchi 0, "device-id", &props, &numProps);
712*d14abf15SRobert Mustacchi if ((rc == DDI_PROP_SUCCESS) && (numProps > 0))
713*d14abf15SRobert Mustacchi {
714*d14abf15SRobert Mustacchi device_id = props[0];
715*d14abf15SRobert Mustacchi ddi_prop_free(props);
716*d14abf15SRobert Mustacchi }
717*d14abf15SRobert Mustacchi
718*d14abf15SRobert Mustacchi snprintf(pUM->vendor_device,
719*d14abf15SRobert Mustacchi sizeof(pUM->vendor_device),
720*d14abf15SRobert Mustacchi "%04x:%04x",
721*d14abf15SRobert Mustacchi vendor_id,
722*d14abf15SRobert Mustacchi device_id);
723*d14abf15SRobert Mustacchi
724*d14abf15SRobert Mustacchi snprintf(pUM->intrAlloc,
725*d14abf15SRobert Mustacchi sizeof(pUM->intrAlloc),
726*d14abf15SRobert Mustacchi "%d %s",
727*d14abf15SRobert Mustacchi (pUM->intrType == DDI_INTR_TYPE_FIXED) ? 1 : (pUM->defIntr.intrCount +
728*d14abf15SRobert Mustacchi pUM->fcoeIntr.intrCount +
729*d14abf15SRobert Mustacchi pUM->rssIntr.intrCount),
730*d14abf15SRobert Mustacchi (pUM->intrType == DDI_INTR_TYPE_MSIX) ? "MSIX" :
731*d14abf15SRobert Mustacchi (pUM->intrType == DDI_INTR_TYPE_MSI) ? "MSI" :
732*d14abf15SRobert Mustacchi "Fixed");
733*d14abf15SRobert Mustacchi
734*d14abf15SRobert Mustacchi BnxeLogInfo(pUM,
735*d14abf15SRobert Mustacchi "(0x%p) %s %s - v%s - FW v%s - BC v%s - %s (%s)",
736*d14abf15SRobert Mustacchi pUM,
737*d14abf15SRobert Mustacchi pUM->chipName,
738*d14abf15SRobert Mustacchi pUM->chipID,
739*d14abf15SRobert Mustacchi pUM->version,
740*d14abf15SRobert Mustacchi pUM->versionFW,
741*d14abf15SRobert Mustacchi pUM->versionBC,
742*d14abf15SRobert Mustacchi IS_MULTI_VNIC(&pUM->lm_dev) ? "MF" : "SF",
743*d14abf15SRobert Mustacchi pUM->intrAlloc);
744*d14abf15SRobert Mustacchi
745*d14abf15SRobert Mustacchi return B_TRUE;
746*d14abf15SRobert Mustacchi }
747*d14abf15SRobert Mustacchi
748*d14abf15SRobert Mustacchi
BnxeDetachDevice(um_device_t * pUM)749*d14abf15SRobert Mustacchi static boolean_t BnxeDetachDevice(um_device_t * pUM)
750*d14abf15SRobert Mustacchi {
751*d14abf15SRobert Mustacchi int rc;
752*d14abf15SRobert Mustacchi
753*d14abf15SRobert Mustacchi rc = BnxeFcoeFini(pUM);
754*d14abf15SRobert Mustacchi
755*d14abf15SRobert Mustacchi if ((rc != 0) && (rc != ENOTSUP) && (rc != ENODEV))
756*d14abf15SRobert Mustacchi {
757*d14abf15SRobert Mustacchi return B_FALSE;
758*d14abf15SRobert Mustacchi }
759*d14abf15SRobert Mustacchi
760*d14abf15SRobert Mustacchi if (BnxeProtoFcoeAfex(pUM))
761*d14abf15SRobert Mustacchi {
762*d14abf15SRobert Mustacchi /* No support for L2 on FCoE enabled AFEX function! */
763*d14abf15SRobert Mustacchi ;
764*d14abf15SRobert Mustacchi #if 0
765*d14abf15SRobert Mustacchi ddi_remove_minor_node(pUM->pDev, pUM->devName);
766*d14abf15SRobert Mustacchi ddi_remove_minor_node(pUM->pDev, (char *)ddi_driver_name(pUM->pDev));
767*d14abf15SRobert Mustacchi #endif
768*d14abf15SRobert Mustacchi }
769*d14abf15SRobert Mustacchi else
770*d14abf15SRobert Mustacchi {
771*d14abf15SRobert Mustacchi if (!BnxeGldFini(pUM))
772*d14abf15SRobert Mustacchi {
773*d14abf15SRobert Mustacchi return B_FALSE;
774*d14abf15SRobert Mustacchi }
775*d14abf15SRobert Mustacchi }
776*d14abf15SRobert Mustacchi
777*d14abf15SRobert Mustacchi BnxeKstatFini(pUM);
778*d14abf15SRobert Mustacchi BnxeIntrFini(pUM);
779*d14abf15SRobert Mustacchi BnxeBarMemDestroy(pUM);
780*d14abf15SRobert Mustacchi BnxeWorkQueueWaitAndDestroy(pUM);
781*d14abf15SRobert Mustacchi BnxeMutexDestroy(pUM);
782*d14abf15SRobert Mustacchi BnxePciDestroy(pUM);
783*d14abf15SRobert Mustacchi BnxeFmFini(pUM);
784*d14abf15SRobert Mustacchi
785*d14abf15SRobert Mustacchi return B_TRUE;
786*d14abf15SRobert Mustacchi }
787*d14abf15SRobert Mustacchi
788*d14abf15SRobert Mustacchi
BnxeAttach(dev_info_t * pDev,ddi_attach_cmd_t cmd)789*d14abf15SRobert Mustacchi static int BnxeAttach(dev_info_t * pDev, ddi_attach_cmd_t cmd)
790*d14abf15SRobert Mustacchi {
791*d14abf15SRobert Mustacchi um_device_t * pUM;
792*d14abf15SRobert Mustacchi
793*d14abf15SRobert Mustacchi switch (cmd)
794*d14abf15SRobert Mustacchi {
795*d14abf15SRobert Mustacchi case DDI_ATTACH:
796*d14abf15SRobert Mustacchi
797*d14abf15SRobert Mustacchi if ((pUM = kmem_zalloc(sizeof(um_device_t), KM_SLEEP)) == NULL)
798*d14abf15SRobert Mustacchi {
799*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "failed to allocate device structure");
800*d14abf15SRobert Mustacchi return DDI_FAILURE;
801*d14abf15SRobert Mustacchi }
802*d14abf15SRobert Mustacchi
803*d14abf15SRobert Mustacchi ddi_set_driver_private(pDev, pUM);
804*d14abf15SRobert Mustacchi
805*d14abf15SRobert Mustacchi /* set magic number for identification */
806*d14abf15SRobert Mustacchi pUM->magic = BNXE_MAGIC;
807*d14abf15SRobert Mustacchi
808*d14abf15SRobert Mustacchi /* default for debug logging is dump everything */
809*d14abf15SRobert Mustacchi pUM->devParams.debug_level = (CP_ALL | LV_MASK);
810*d14abf15SRobert Mustacchi
811*d14abf15SRobert Mustacchi /* save dev_info_t in the driver structure */
812*d14abf15SRobert Mustacchi pUM->pDev = pDev;
813*d14abf15SRobert Mustacchi
814*d14abf15SRobert Mustacchi d_list_clear(&pUM->memBlockList);
815*d14abf15SRobert Mustacchi d_list_clear(&pUM->memDmaList);
816*d14abf15SRobert Mustacchi d_list_clear(&pUM->memRegionList);
817*d14abf15SRobert Mustacchi #ifdef BNXE_DEBUG_DMA_LIST
818*d14abf15SRobert Mustacchi d_list_clear(&pUM->memDmaListSaved);
819*d14abf15SRobert Mustacchi #endif
820*d14abf15SRobert Mustacchi
821*d14abf15SRobert Mustacchi /* obtain a human-readable device name log messages with */
822*d14abf15SRobert Mustacchi pUM->instance = ddi_get_instance(pDev);
823*d14abf15SRobert Mustacchi snprintf(pUM->devName, sizeof(pUM->devName),
824*d14abf15SRobert Mustacchi "bnxe%d", pUM->instance);
825*d14abf15SRobert Mustacchi
826*d14abf15SRobert Mustacchi if (!BnxeAttachDevice(pUM))
827*d14abf15SRobert Mustacchi {
828*d14abf15SRobert Mustacchi kmem_free(pUM, sizeof(um_device_t));
829*d14abf15SRobert Mustacchi return DDI_FAILURE;
830*d14abf15SRobert Mustacchi }
831*d14abf15SRobert Mustacchi
832*d14abf15SRobert Mustacchi if (BNXE_FCOE(pUM) && pUM->devParams.fcoeEnable)
833*d14abf15SRobert Mustacchi {
834*d14abf15SRobert Mustacchi BnxeFcoeStartStop(pUM);
835*d14abf15SRobert Mustacchi }
836*d14abf15SRobert Mustacchi
837*d14abf15SRobert Mustacchi return DDI_SUCCESS;
838*d14abf15SRobert Mustacchi
839*d14abf15SRobert Mustacchi case DDI_RESUME:
840*d14abf15SRobert Mustacchi #if !(defined(__S11) || defined(__S12))
841*d14abf15SRobert Mustacchi case DDI_PM_RESUME:
842*d14abf15SRobert Mustacchi #endif
843*d14abf15SRobert Mustacchi
844*d14abf15SRobert Mustacchi pUM = (um_device_t *)ddi_get_driver_private(pDev);
845*d14abf15SRobert Mustacchi
846*d14abf15SRobert Mustacchi /* sanity check */
847*d14abf15SRobert Mustacchi if (pUM == NULL || pUM->pDev != pDev)
848*d14abf15SRobert Mustacchi {
849*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__);
850*d14abf15SRobert Mustacchi return DDI_FAILURE;
851*d14abf15SRobert Mustacchi }
852*d14abf15SRobert Mustacchi
853*d14abf15SRobert Mustacchi if (BnxeHwResume(pUM) != 0)
854*d14abf15SRobert Mustacchi {
855*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Fail to resume this device!");
856*d14abf15SRobert Mustacchi return DDI_FAILURE;
857*d14abf15SRobert Mustacchi }
858*d14abf15SRobert Mustacchi
859*d14abf15SRobert Mustacchi return DDI_SUCCESS;
860*d14abf15SRobert Mustacchi
861*d14abf15SRobert Mustacchi default:
862*d14abf15SRobert Mustacchi
863*d14abf15SRobert Mustacchi return DDI_FAILURE;
864*d14abf15SRobert Mustacchi }
865*d14abf15SRobert Mustacchi }
866*d14abf15SRobert Mustacchi
867*d14abf15SRobert Mustacchi
BnxeDetach(dev_info_t * pDev,ddi_detach_cmd_t cmd)868*d14abf15SRobert Mustacchi static int BnxeDetach(dev_info_t * pDev, ddi_detach_cmd_t cmd)
869*d14abf15SRobert Mustacchi {
870*d14abf15SRobert Mustacchi um_device_t * pUM;
871*d14abf15SRobert Mustacchi
872*d14abf15SRobert Mustacchi switch (cmd)
873*d14abf15SRobert Mustacchi {
874*d14abf15SRobert Mustacchi case DDI_DETACH:
875*d14abf15SRobert Mustacchi
876*d14abf15SRobert Mustacchi pUM = (um_device_t *)ddi_get_driver_private(pDev);
877*d14abf15SRobert Mustacchi
878*d14abf15SRobert Mustacchi /* sanity check */
879*d14abf15SRobert Mustacchi if (pUM == NULL || pUM->pDev != pDev)
880*d14abf15SRobert Mustacchi {
881*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__);
882*d14abf15SRobert Mustacchi return DDI_FAILURE;
883*d14abf15SRobert Mustacchi }
884*d14abf15SRobert Mustacchi
885*d14abf15SRobert Mustacchi if (pUM->intrEnabled != B_FALSE)
886*d14abf15SRobert Mustacchi {
887*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Detaching a device that is currently running!");
888*d14abf15SRobert Mustacchi return DDI_FAILURE;
889*d14abf15SRobert Mustacchi }
890*d14abf15SRobert Mustacchi
891*d14abf15SRobert Mustacchi if (!BnxeDetachDevice(pUM))
892*d14abf15SRobert Mustacchi {
893*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Can't detach it now, please try again later!");
894*d14abf15SRobert Mustacchi return DDI_FAILURE;
895*d14abf15SRobert Mustacchi }
896*d14abf15SRobert Mustacchi
897*d14abf15SRobert Mustacchi kmem_free(pUM, sizeof(um_device_t));
898*d14abf15SRobert Mustacchi
899*d14abf15SRobert Mustacchi return DDI_SUCCESS;
900*d14abf15SRobert Mustacchi
901*d14abf15SRobert Mustacchi case DDI_SUSPEND:
902*d14abf15SRobert Mustacchi #if !(defined(__S11) || defined(__S12))
903*d14abf15SRobert Mustacchi case DDI_PM_SUSPEND:
904*d14abf15SRobert Mustacchi #endif
905*d14abf15SRobert Mustacchi
906*d14abf15SRobert Mustacchi pUM = (um_device_t *)ddi_get_driver_private(pDev);
907*d14abf15SRobert Mustacchi
908*d14abf15SRobert Mustacchi /* sanity check */
909*d14abf15SRobert Mustacchi if (pUM == NULL || pUM->pDev != pDev)
910*d14abf15SRobert Mustacchi {
911*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__);
912*d14abf15SRobert Mustacchi return DDI_FAILURE;
913*d14abf15SRobert Mustacchi }
914*d14abf15SRobert Mustacchi
915*d14abf15SRobert Mustacchi if (BnxeHwSuspend(pUM) != 0)
916*d14abf15SRobert Mustacchi {
917*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Fail to suspend this device!");
918*d14abf15SRobert Mustacchi return DDI_FAILURE;
919*d14abf15SRobert Mustacchi }
920*d14abf15SRobert Mustacchi
921*d14abf15SRobert Mustacchi return DDI_SUCCESS;
922*d14abf15SRobert Mustacchi
923*d14abf15SRobert Mustacchi default:
924*d14abf15SRobert Mustacchi
925*d14abf15SRobert Mustacchi return DDI_FAILURE;
926*d14abf15SRobert Mustacchi }
927*d14abf15SRobert Mustacchi }
928*d14abf15SRobert Mustacchi
929*d14abf15SRobert Mustacchi
930*d14abf15SRobert Mustacchi #if (DEVO_REV > 3)
931*d14abf15SRobert Mustacchi
BnxeQuiesce(dev_info_t * pDev)932*d14abf15SRobert Mustacchi static int BnxeQuiesce(dev_info_t * pDev)
933*d14abf15SRobert Mustacchi {
934*d14abf15SRobert Mustacchi um_device_t * pUM;
935*d14abf15SRobert Mustacchi
936*d14abf15SRobert Mustacchi pUM = (um_device_t *)ddi_get_driver_private(pDev);
937*d14abf15SRobert Mustacchi
938*d14abf15SRobert Mustacchi /* sanity check */
939*d14abf15SRobert Mustacchi if (pUM == NULL || pUM->pDev != pDev)
940*d14abf15SRobert Mustacchi {
941*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__);
942*d14abf15SRobert Mustacchi return DDI_FAILURE;
943*d14abf15SRobert Mustacchi }
944*d14abf15SRobert Mustacchi
945*d14abf15SRobert Mustacchi if (!pUM->plumbed)
946*d14abf15SRobert Mustacchi {
947*d14abf15SRobert Mustacchi return DDI_SUCCESS;
948*d14abf15SRobert Mustacchi }
949*d14abf15SRobert Mustacchi
950*d14abf15SRobert Mustacchi if (BnxeHwQuiesce(pUM) != 0)
951*d14abf15SRobert Mustacchi {
952*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to quiesce the device!");
953*d14abf15SRobert Mustacchi return DDI_FAILURE;
954*d14abf15SRobert Mustacchi }
955*d14abf15SRobert Mustacchi
956*d14abf15SRobert Mustacchi return DDI_SUCCESS;
957*d14abf15SRobert Mustacchi }
958*d14abf15SRobert Mustacchi
959*d14abf15SRobert Mustacchi #endif
960*d14abf15SRobert Mustacchi
961*d14abf15SRobert Mustacchi
BnxeFcoeInitChild(dev_info_t * pDev,dev_info_t * cDip)962*d14abf15SRobert Mustacchi void BnxeFcoeInitChild(dev_info_t * pDev,
963*d14abf15SRobert Mustacchi dev_info_t * cDip)
964*d14abf15SRobert Mustacchi {
965*d14abf15SRobert Mustacchi um_device_t *pUM = (um_device_t *) ddi_get_driver_private(pDev);
966*d14abf15SRobert Mustacchi
967*d14abf15SRobert Mustacchi if ((pUM == NULL) || (pUM->pDev != pDev))
968*d14abf15SRobert Mustacchi {
969*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: dev_info_t match failed ", __func__);
970*d14abf15SRobert Mustacchi return;
971*d14abf15SRobert Mustacchi }
972*d14abf15SRobert Mustacchi
973*d14abf15SRobert Mustacchi ddi_set_name_addr(cDip, ddi_get_name_addr(pUM->pDev));
974*d14abf15SRobert Mustacchi }
975*d14abf15SRobert Mustacchi
976*d14abf15SRobert Mustacchi
BnxeFcoeUninitChild(dev_info_t * pDev,dev_info_t * cDip)977*d14abf15SRobert Mustacchi void BnxeFcoeUninitChild(dev_info_t * pDev,
978*d14abf15SRobert Mustacchi dev_info_t * cDip)
979*d14abf15SRobert Mustacchi {
980*d14abf15SRobert Mustacchi ddi_set_name_addr(cDip, NULL);
981*d14abf15SRobert Mustacchi }
982*d14abf15SRobert Mustacchi
983*d14abf15SRobert Mustacchi
BnxeBusCtl(dev_info_t * pDev,dev_info_t * pRDev,ddi_ctl_enum_t op,void * pArg,void * pResult)984*d14abf15SRobert Mustacchi static int BnxeBusCtl(dev_info_t * pDev,
985*d14abf15SRobert Mustacchi dev_info_t * pRDev,
986*d14abf15SRobert Mustacchi ddi_ctl_enum_t op,
987*d14abf15SRobert Mustacchi void * pArg,
988*d14abf15SRobert Mustacchi void * pResult)
989*d14abf15SRobert Mustacchi {
990*d14abf15SRobert Mustacchi um_device_t * pUM = (um_device_t *)ddi_get_driver_private(pDev);
991*d14abf15SRobert Mustacchi
992*d14abf15SRobert Mustacchi /* sanity check */
993*d14abf15SRobert Mustacchi if (pUM == NULL || pUM->pDev != pDev)
994*d14abf15SRobert Mustacchi {
995*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__);
996*d14abf15SRobert Mustacchi return DDI_FAILURE;
997*d14abf15SRobert Mustacchi }
998*d14abf15SRobert Mustacchi
999*d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "BnxeBusCtl (%d)", op);
1000*d14abf15SRobert Mustacchi
1001*d14abf15SRobert Mustacchi switch (op)
1002*d14abf15SRobert Mustacchi {
1003*d14abf15SRobert Mustacchi case DDI_CTLOPS_REPORTDEV:
1004*d14abf15SRobert Mustacchi case DDI_CTLOPS_IOMIN:
1005*d14abf15SRobert Mustacchi break;
1006*d14abf15SRobert Mustacchi case DDI_CTLOPS_INITCHILD:
1007*d14abf15SRobert Mustacchi BnxeFcoeInitChild(pDev, (dev_info_t *) pArg);
1008*d14abf15SRobert Mustacchi break;
1009*d14abf15SRobert Mustacchi case DDI_CTLOPS_UNINITCHILD:
1010*d14abf15SRobert Mustacchi BnxeFcoeUninitChild(pDev, (dev_info_t *) pArg);
1011*d14abf15SRobert Mustacchi break;
1012*d14abf15SRobert Mustacchi
1013*d14abf15SRobert Mustacchi default:
1014*d14abf15SRobert Mustacchi
1015*d14abf15SRobert Mustacchi return (ddi_ctlops(pDev, pRDev, op, pArg, pResult));
1016*d14abf15SRobert Mustacchi }
1017*d14abf15SRobert Mustacchi
1018*d14abf15SRobert Mustacchi return DDI_SUCCESS;
1019*d14abf15SRobert Mustacchi }
1020*d14abf15SRobert Mustacchi
1021*d14abf15SRobert Mustacchi
BnxeCbIoctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)1022*d14abf15SRobert Mustacchi static int BnxeCbIoctl(dev_t dev,
1023*d14abf15SRobert Mustacchi int cmd,
1024*d14abf15SRobert Mustacchi intptr_t arg,
1025*d14abf15SRobert Mustacchi int mode,
1026*d14abf15SRobert Mustacchi cred_t * credp,
1027*d14abf15SRobert Mustacchi int * rvalp)
1028*d14abf15SRobert Mustacchi {
1029*d14abf15SRobert Mustacchi BnxeBinding * pBinding = (BnxeBinding *)arg;
1030*d14abf15SRobert Mustacchi um_device_t * pUM;
1031*d14abf15SRobert Mustacchi
1032*d14abf15SRobert Mustacchi (void)dev;
1033*d14abf15SRobert Mustacchi (void)mode;
1034*d14abf15SRobert Mustacchi (void)credp;
1035*d14abf15SRobert Mustacchi (void)rvalp;
1036*d14abf15SRobert Mustacchi
1037*d14abf15SRobert Mustacchi if ((pBinding == NULL) ||
1038*d14abf15SRobert Mustacchi (pBinding->pCliDev == NULL) ||
1039*d14abf15SRobert Mustacchi (pBinding->pPrvDev == NULL))
1040*d14abf15SRobert Mustacchi {
1041*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "Invalid binding arg to ioctl %d", cmd);
1042*d14abf15SRobert Mustacchi return DDI_FAILURE;
1043*d14abf15SRobert Mustacchi }
1044*d14abf15SRobert Mustacchi
1045*d14abf15SRobert Mustacchi pUM = (um_device_t *)ddi_get_driver_private(pBinding->pPrvDev);
1046*d14abf15SRobert Mustacchi
1047*d14abf15SRobert Mustacchi /* sanity checks */
1048*d14abf15SRobert Mustacchi
1049*d14abf15SRobert Mustacchi if (pBinding->version != BNXE_BINDING_VERSION)
1050*d14abf15SRobert Mustacchi {
1051*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: Invalid binding version (0x%08x)",
1052*d14abf15SRobert Mustacchi __func__, pBinding->version);
1053*d14abf15SRobert Mustacchi return DDI_FAILURE;
1054*d14abf15SRobert Mustacchi }
1055*d14abf15SRobert Mustacchi
1056*d14abf15SRobert Mustacchi if ((pUM == NULL) ||
1057*d14abf15SRobert Mustacchi (pUM->fcoe.pDev != pBinding->pCliDev) ||
1058*d14abf15SRobert Mustacchi (pUM->pDev != pBinding->pPrvDev))
1059*d14abf15SRobert Mustacchi {
1060*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__);
1061*d14abf15SRobert Mustacchi return DDI_FAILURE;
1062*d14abf15SRobert Mustacchi }
1063*d14abf15SRobert Mustacchi
1064*d14abf15SRobert Mustacchi switch (cmd)
1065*d14abf15SRobert Mustacchi {
1066*d14abf15SRobert Mustacchi case BNXE_BIND_FCOE:
1067*d14abf15SRobert Mustacchi
1068*d14abf15SRobert Mustacchi /* copy the binding struct and fill in the provider callback */
1069*d14abf15SRobert Mustacchi
1070*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "FCoE BIND start");
1071*d14abf15SRobert Mustacchi
1072*d14abf15SRobert Mustacchi if (!CLIENT_DEVI(pUM, LM_CLI_IDX_FCOE))
1073*d14abf15SRobert Mustacchi {
1074*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "FCoE BIND when DEVI is offline!");
1075*d14abf15SRobert Mustacchi return DDI_FAILURE;
1076*d14abf15SRobert Mustacchi }
1077*d14abf15SRobert Mustacchi
1078*d14abf15SRobert Mustacchi if (CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE))
1079*d14abf15SRobert Mustacchi {
1080*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "FCoE BIND when alread bound!");
1081*d14abf15SRobert Mustacchi return DDI_FAILURE;
1082*d14abf15SRobert Mustacchi }
1083*d14abf15SRobert Mustacchi
1084*d14abf15SRobert Mustacchi pUM->fcoe.bind = *pBinding;
1085*d14abf15SRobert Mustacchi
1086*d14abf15SRobert Mustacchi pUM->fcoe.bind.prvCtl = pBinding->prvCtl = BnxeFcoePrvCtl;
1087*d14abf15SRobert Mustacchi pUM->fcoe.bind.prvTx = pBinding->prvTx = BnxeFcoePrvTx;
1088*d14abf15SRobert Mustacchi pUM->fcoe.bind.prvPoll = pBinding->prvPoll = BnxeFcoePrvPoll;
1089*d14abf15SRobert Mustacchi pUM->fcoe.bind.prvSendWqes = pBinding->prvSendWqes = BnxeFcoePrvSendWqes;
1090*d14abf15SRobert Mustacchi pUM->fcoe.bind.prvMapMailboxq = pBinding->prvMapMailboxq = BnxeFcoePrvMapMailboxq;
1091*d14abf15SRobert Mustacchi pUM->fcoe.bind.prvUnmapMailboxq = pBinding->prvUnmapMailboxq = BnxeFcoePrvUnmapMailboxq;
1092*d14abf15SRobert Mustacchi
1093*d14abf15SRobert Mustacchi pUM->devParams.numRxDesc[LM_CLI_IDX_FCOE] = pBinding->numRxDescs;
1094*d14abf15SRobert Mustacchi pUM->devParams.numTxDesc[LM_CLI_IDX_FCOE] = pBinding->numTxDescs;
1095*d14abf15SRobert Mustacchi
1096*d14abf15SRobert Mustacchi pUM->lm_dev.params.l2_rx_desc_cnt[LM_CLI_IDX_FCOE] = pBinding->numRxDescs;
1097*d14abf15SRobert Mustacchi BnxeInitBdCnts(pUM, LM_CLI_IDX_FCOE);
1098*d14abf15SRobert Mustacchi
1099*d14abf15SRobert Mustacchi if (BnxeHwStartFCOE(pUM))
1100*d14abf15SRobert Mustacchi {
1101*d14abf15SRobert Mustacchi return DDI_FAILURE;
1102*d14abf15SRobert Mustacchi }
1103*d14abf15SRobert Mustacchi
1104*d14abf15SRobert Mustacchi CLIENT_BIND_SET(pUM, LM_CLI_IDX_FCOE);
1105*d14abf15SRobert Mustacchi lm_mcp_indicate_client_bind(&pUM->lm_dev, LM_CLI_IDX_FCOE);
1106*d14abf15SRobert Mustacchi
1107*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "FCoE BIND done");
1108*d14abf15SRobert Mustacchi return DDI_SUCCESS;
1109*d14abf15SRobert Mustacchi
1110*d14abf15SRobert Mustacchi case BNXE_UNBIND_FCOE:
1111*d14abf15SRobert Mustacchi
1112*d14abf15SRobert Mustacchi /* clear the binding struct and stats */
1113*d14abf15SRobert Mustacchi
1114*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "FCoE UNBIND start");
1115*d14abf15SRobert Mustacchi
1116*d14abf15SRobert Mustacchi if (CLIENT_DEVI(pUM, LM_CLI_IDX_FCOE))
1117*d14abf15SRobert Mustacchi {
1118*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "FCoE UNBIND when DEVI is online!");
1119*d14abf15SRobert Mustacchi return DDI_FAILURE;
1120*d14abf15SRobert Mustacchi }
1121*d14abf15SRobert Mustacchi
1122*d14abf15SRobert Mustacchi if (!CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE))
1123*d14abf15SRobert Mustacchi {
1124*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "FCoE UNBIND when not bound!");
1125*d14abf15SRobert Mustacchi return DDI_FAILURE;
1126*d14abf15SRobert Mustacchi }
1127*d14abf15SRobert Mustacchi
1128*d14abf15SRobert Mustacchi /* We must not detach until all packets held by fcoe are retrieved. */
1129*d14abf15SRobert Mustacchi if (!BnxeWaitForPacketsFromClient(pUM, LM_CLI_IDX_FCOE))
1130*d14abf15SRobert Mustacchi {
1131*d14abf15SRobert Mustacchi return DDI_FAILURE;
1132*d14abf15SRobert Mustacchi }
1133*d14abf15SRobert Mustacchi
1134*d14abf15SRobert Mustacchi lm_mcp_indicate_client_unbind(&pUM->lm_dev, LM_CLI_IDX_FCOE);
1135*d14abf15SRobert Mustacchi CLIENT_BIND_RESET(pUM, LM_CLI_IDX_FCOE);
1136*d14abf15SRobert Mustacchi
1137*d14abf15SRobert Mustacchi BnxeHwStopFCOE(pUM);
1138*d14abf15SRobert Mustacchi
1139*d14abf15SRobert Mustacchi memset(&pUM->fcoe.bind, 0, sizeof(pUM->fcoe.bind));
1140*d14abf15SRobert Mustacchi memset(&pUM->fcoe.stats, 0, sizeof(pUM->fcoe.stats));
1141*d14abf15SRobert Mustacchi
1142*d14abf15SRobert Mustacchi pBinding->prvCtl = NULL;
1143*d14abf15SRobert Mustacchi pBinding->prvTx = NULL;
1144*d14abf15SRobert Mustacchi pBinding->prvPoll = NULL;
1145*d14abf15SRobert Mustacchi pBinding->prvSendWqes = NULL;
1146*d14abf15SRobert Mustacchi pBinding->prvMapMailboxq = NULL;
1147*d14abf15SRobert Mustacchi pBinding->prvUnmapMailboxq = NULL;
1148*d14abf15SRobert Mustacchi
1149*d14abf15SRobert Mustacchi pUM->fcoe.pDev = NULL; /* sketchy? */
1150*d14abf15SRobert Mustacchi
1151*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "FCoE UNBIND done");
1152*d14abf15SRobert Mustacchi return DDI_SUCCESS;
1153*d14abf15SRobert Mustacchi
1154*d14abf15SRobert Mustacchi default:
1155*d14abf15SRobert Mustacchi
1156*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Unknown ioctl %d", cmd);
1157*d14abf15SRobert Mustacchi return DDI_FAILURE;
1158*d14abf15SRobert Mustacchi }
1159*d14abf15SRobert Mustacchi }
1160*d14abf15SRobert Mustacchi
1161*d14abf15SRobert Mustacchi #ifndef ILLUMOS
1162*d14abf15SRobert Mustacchi static struct bus_ops bnxe_bus_ops =
1163*d14abf15SRobert Mustacchi {
1164*d14abf15SRobert Mustacchi BUSO_REV,
1165*d14abf15SRobert Mustacchi nullbusmap, /* bus_map */
1166*d14abf15SRobert Mustacchi NULL, /* bus_get_intrspec */
1167*d14abf15SRobert Mustacchi NULL, /* bus_add_intrspec */
1168*d14abf15SRobert Mustacchi NULL, /* bus_remove_intrspec */
1169*d14abf15SRobert Mustacchi i_ddi_map_fault, /* bus_map_fault */
1170*d14abf15SRobert Mustacchi ddi_dma_map, /* bus_dma_map */
1171*d14abf15SRobert Mustacchi ddi_dma_allochdl, /* bus_dma_allochdl */
1172*d14abf15SRobert Mustacchi ddi_dma_freehdl, /* bus_dma_freehdl */
1173*d14abf15SRobert Mustacchi ddi_dma_bindhdl, /* bus_dma_bindhdl */
1174*d14abf15SRobert Mustacchi ddi_dma_unbindhdl, /* bus_unbindhdl */
1175*d14abf15SRobert Mustacchi ddi_dma_flush, /* bus_dma_flush */
1176*d14abf15SRobert Mustacchi ddi_dma_win, /* bus_dma_win */
1177*d14abf15SRobert Mustacchi ddi_dma_mctl, /* bus_dma_ctl */
1178*d14abf15SRobert Mustacchi BnxeBusCtl, /* bus_ctl */
1179*d14abf15SRobert Mustacchi ddi_bus_prop_op, /* bus_prop_op */
1180*d14abf15SRobert Mustacchi NULL, /* bus_get_eventcookie */
1181*d14abf15SRobert Mustacchi NULL, /* bus_add_eventcall */
1182*d14abf15SRobert Mustacchi NULL, /* bus_remove_event */
1183*d14abf15SRobert Mustacchi NULL, /* bus_post_event */
1184*d14abf15SRobert Mustacchi NULL, /* bus_intr_ctl */
1185*d14abf15SRobert Mustacchi NULL, /* bus_config */
1186*d14abf15SRobert Mustacchi NULL, /* bus_unconfig */
1187*d14abf15SRobert Mustacchi NULL, /* bus_fm_init */
1188*d14abf15SRobert Mustacchi NULL, /* bus_fm_fini */
1189*d14abf15SRobert Mustacchi NULL, /* bus_fm_access_enter */
1190*d14abf15SRobert Mustacchi NULL, /* bus_fm_access_exit */
1191*d14abf15SRobert Mustacchi NULL, /* bus_power */
1192*d14abf15SRobert Mustacchi NULL
1193*d14abf15SRobert Mustacchi };
1194*d14abf15SRobert Mustacchi #endif /* ILLUMOS */
1195*d14abf15SRobert Mustacchi
1196*d14abf15SRobert Mustacchi
1197*d14abf15SRobert Mustacchi static struct cb_ops bnxe_cb_ops =
1198*d14abf15SRobert Mustacchi {
1199*d14abf15SRobert Mustacchi nulldev, /* cb_open */
1200*d14abf15SRobert Mustacchi nulldev, /* cb_close */
1201*d14abf15SRobert Mustacchi nodev, /* cb_strategy */
1202*d14abf15SRobert Mustacchi nodev, /* cb_print */
1203*d14abf15SRobert Mustacchi nodev, /* cb_dump */
1204*d14abf15SRobert Mustacchi nodev, /* cb_read */
1205*d14abf15SRobert Mustacchi nodev, /* cb_write */
1206*d14abf15SRobert Mustacchi BnxeCbIoctl, /* cb_ioctl */
1207*d14abf15SRobert Mustacchi nodev, /* cb_devmap */
1208*d14abf15SRobert Mustacchi nodev, /* cb_mmap */
1209*d14abf15SRobert Mustacchi nodev, /* cb_segmap */
1210*d14abf15SRobert Mustacchi nochpoll, /* cb_chpoll */
1211*d14abf15SRobert Mustacchi ddi_prop_op, /* cb_prop_op */
1212*d14abf15SRobert Mustacchi NULL, /* cb_stream */
1213*d14abf15SRobert Mustacchi (int)(D_MP | D_64BIT), /* cb_flag */
1214*d14abf15SRobert Mustacchi CB_REV, /* cb_rev */
1215*d14abf15SRobert Mustacchi nodev, /* cb_aread */
1216*d14abf15SRobert Mustacchi nodev, /* cb_awrite */
1217*d14abf15SRobert Mustacchi };
1218*d14abf15SRobert Mustacchi
1219*d14abf15SRobert Mustacchi
1220*d14abf15SRobert Mustacchi #if (DEVO_REV > 3)
1221*d14abf15SRobert Mustacchi
1222*d14abf15SRobert Mustacchi static struct dev_ops bnxe_dev_ops =
1223*d14abf15SRobert Mustacchi {
1224*d14abf15SRobert Mustacchi DEVO_REV, /* devo_rev */
1225*d14abf15SRobert Mustacchi 0, /* devo_refcnt */
1226*d14abf15SRobert Mustacchi NULL, /* devo_getinfo */
1227*d14abf15SRobert Mustacchi nulldev, /* devo_identify */
1228*d14abf15SRobert Mustacchi nulldev, /* devo_probe */
1229*d14abf15SRobert Mustacchi BnxeAttach, /* devo_attach */
1230*d14abf15SRobert Mustacchi BnxeDetach, /* devo_detach */
1231*d14abf15SRobert Mustacchi nodev, /* devo_reset */
1232*d14abf15SRobert Mustacchi &bnxe_cb_ops, /* devo_cb_ops */
1233*d14abf15SRobert Mustacchi #ifndef ILLUMOS
1234*d14abf15SRobert Mustacchi &bnxe_bus_ops, /* devo_bus_ops */
1235*d14abf15SRobert Mustacchi #else
1236*d14abf15SRobert Mustacchi NULL, /* devo_bus_ops */
1237*d14abf15SRobert Mustacchi #endif
1238*d14abf15SRobert Mustacchi NULL, /* devo_power */
1239*d14abf15SRobert Mustacchi BnxeQuiesce /* devo_quiesce */
1240*d14abf15SRobert Mustacchi };
1241*d14abf15SRobert Mustacchi
1242*d14abf15SRobert Mustacchi #else
1243*d14abf15SRobert Mustacchi
1244*d14abf15SRobert Mustacchi static struct dev_ops bnxe_dev_ops =
1245*d14abf15SRobert Mustacchi {
1246*d14abf15SRobert Mustacchi DEVO_REV, /* devo_rev */
1247*d14abf15SRobert Mustacchi 0, /* devo_refcnt */
1248*d14abf15SRobert Mustacchi NULL, /* devo_getinfo */
1249*d14abf15SRobert Mustacchi nulldev, /* devo_identify */
1250*d14abf15SRobert Mustacchi nulldev, /* devo_probe */
1251*d14abf15SRobert Mustacchi BnxeAttach, /* devo_attach */
1252*d14abf15SRobert Mustacchi BnxeDetach, /* devo_detach */
1253*d14abf15SRobert Mustacchi nodev, /* devo_reset */
1254*d14abf15SRobert Mustacchi &bnxe_cb_ops, /* devo_cb_ops */
1255*d14abf15SRobert Mustacchi &bnxe_bus_ops, /* devo_bus_ops */
1256*d14abf15SRobert Mustacchi NULL /* devo_power */
1257*d14abf15SRobert Mustacchi };
1258*d14abf15SRobert Mustacchi
1259*d14abf15SRobert Mustacchi #endif
1260*d14abf15SRobert Mustacchi
1261*d14abf15SRobert Mustacchi
1262*d14abf15SRobert Mustacchi static struct modldrv bnxe_modldrv =
1263*d14abf15SRobert Mustacchi {
1264*d14abf15SRobert Mustacchi &mod_driverops, /* drv_modops (must be mod_driverops for drivers) */
1265*d14abf15SRobert Mustacchi BNXE_PRODUCT_INFO, /* drv_linkinfo (string displayed by modinfo) */
1266*d14abf15SRobert Mustacchi &bnxe_dev_ops /* drv_dev_ops */
1267*d14abf15SRobert Mustacchi };
1268*d14abf15SRobert Mustacchi
1269*d14abf15SRobert Mustacchi
1270*d14abf15SRobert Mustacchi static struct modlinkage bnxe_modlinkage =
1271*d14abf15SRobert Mustacchi {
1272*d14abf15SRobert Mustacchi MODREV_1, /* ml_rev */
1273*d14abf15SRobert Mustacchi {
1274*d14abf15SRobert Mustacchi &bnxe_modldrv, /* ml_linkage */
1275*d14abf15SRobert Mustacchi NULL /* NULL termination */
1276*d14abf15SRobert Mustacchi }
1277*d14abf15SRobert Mustacchi };
1278*d14abf15SRobert Mustacchi
1279*d14abf15SRobert Mustacchi
_init(void)1280*d14abf15SRobert Mustacchi int _init(void)
1281*d14abf15SRobert Mustacchi {
1282*d14abf15SRobert Mustacchi int rc;
1283*d14abf15SRobert Mustacchi
1284*d14abf15SRobert Mustacchi mac_init_ops(&bnxe_dev_ops, "bnxe");
1285*d14abf15SRobert Mustacchi
1286*d14abf15SRobert Mustacchi /* Install module information with O/S */
1287*d14abf15SRobert Mustacchi if ((rc = mod_install(&bnxe_modlinkage)) != DDI_SUCCESS)
1288*d14abf15SRobert Mustacchi {
1289*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "mod_install returned 0x%x", rc);
1290*d14abf15SRobert Mustacchi mac_fini_ops(&bnxe_dev_ops);
1291*d14abf15SRobert Mustacchi return rc;
1292*d14abf15SRobert Mustacchi }
1293*d14abf15SRobert Mustacchi
1294*d14abf15SRobert Mustacchi mutex_init(&bnxeLoaderMutex, NULL, MUTEX_DRIVER, NULL);
1295*d14abf15SRobert Mustacchi bnxeNumPlumbed = 0;
1296*d14abf15SRobert Mustacchi
1297*d14abf15SRobert Mustacchi BnxeLogInfo(NULL, "%s", BNXE_PRODUCT_BANNER);
1298*d14abf15SRobert Mustacchi
1299*d14abf15SRobert Mustacchi return rc;
1300*d14abf15SRobert Mustacchi }
1301*d14abf15SRobert Mustacchi
1302*d14abf15SRobert Mustacchi
_fini(void)1303*d14abf15SRobert Mustacchi int _fini(void)
1304*d14abf15SRobert Mustacchi {
1305*d14abf15SRobert Mustacchi int rc;
1306*d14abf15SRobert Mustacchi
1307*d14abf15SRobert Mustacchi if ((rc = mod_remove(&bnxe_modlinkage)) == DDI_SUCCESS)
1308*d14abf15SRobert Mustacchi {
1309*d14abf15SRobert Mustacchi mac_fini_ops(&bnxe_dev_ops);
1310*d14abf15SRobert Mustacchi mutex_destroy(&bnxeLoaderMutex);
1311*d14abf15SRobert Mustacchi
1312*d14abf15SRobert Mustacchi if (bnxeNumPlumbed > 0)
1313*d14abf15SRobert Mustacchi {
1314*d14abf15SRobert Mustacchi /*
1315*d14abf15SRobert Mustacchi * This shouldn't be possible since modunload must only call _fini
1316*d14abf15SRobert Mustacchi * when no instances are currently plumbed.
1317*d14abf15SRobert Mustacchi */
1318*d14abf15SRobert Mustacchi BnxeLogWarn(NULL, "%d instances have not been unplumbed", bnxeNumPlumbed);
1319*d14abf15SRobert Mustacchi }
1320*d14abf15SRobert Mustacchi }
1321*d14abf15SRobert Mustacchi
1322*d14abf15SRobert Mustacchi return rc;
1323*d14abf15SRobert Mustacchi }
1324*d14abf15SRobert Mustacchi
1325*d14abf15SRobert Mustacchi
_info(struct modinfo * pModinfo)1326*d14abf15SRobert Mustacchi int _info(struct modinfo * pModinfo)
1327*d14abf15SRobert Mustacchi {
1328*d14abf15SRobert Mustacchi return mod_info(&bnxe_modlinkage, pModinfo);
1329*d14abf15SRobert Mustacchi }
1330*d14abf15SRobert Mustacchi
1331