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