1d14abf15SRobert Mustacchi /*
2d14abf15SRobert Mustacchi * CDDL HEADER START
3d14abf15SRobert Mustacchi *
4d14abf15SRobert Mustacchi * The contents of this file are subject to the terms of the
5d14abf15SRobert Mustacchi * Common Development and Distribution License (the "License").
6d14abf15SRobert Mustacchi * You may not use this file except in compliance with the License.
7d14abf15SRobert Mustacchi *
8d14abf15SRobert Mustacchi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d14abf15SRobert Mustacchi * or http://www.opensolaris.org/os/licensing.
10d14abf15SRobert Mustacchi * See the License for the specific language governing permissions
11d14abf15SRobert Mustacchi * and limitations under the License.
12d14abf15SRobert Mustacchi *
13d14abf15SRobert Mustacchi * When distributing Covered Code, include this CDDL HEADER in each
14d14abf15SRobert Mustacchi * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d14abf15SRobert Mustacchi * If applicable, add the following below this CDDL HEADER, with the
16d14abf15SRobert Mustacchi * fields enclosed by brackets "[]" replaced with your own identifying
17d14abf15SRobert Mustacchi * information: Portions Copyright [yyyy] [name of copyright owner]
18d14abf15SRobert Mustacchi *
19d14abf15SRobert Mustacchi * CDDL HEADER END
20d14abf15SRobert Mustacchi */
21d14abf15SRobert Mustacchi
22d14abf15SRobert Mustacchi /*
23d14abf15SRobert Mustacchi * Copyright 2014 QLogic Corporation
24d14abf15SRobert Mustacchi * The contents of this file are subject to the terms of the
25d14abf15SRobert Mustacchi * QLogic End User License (the "License").
26d14abf15SRobert Mustacchi * You may not use this file except in compliance with the License.
27d14abf15SRobert Mustacchi *
28d14abf15SRobert Mustacchi * You can obtain a copy of the License at
29d14abf15SRobert Mustacchi * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/
30d14abf15SRobert Mustacchi * QLogic_End_User_Software_License.txt
31d14abf15SRobert Mustacchi * See the License for the specific language governing permissions
32d14abf15SRobert Mustacchi * and limitations under the License.
33d14abf15SRobert Mustacchi */
34d14abf15SRobert Mustacchi
35d14abf15SRobert Mustacchi /*
36d14abf15SRobert Mustacchi * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
37d14abf15SRobert Mustacchi */
38d14abf15SRobert Mustacchi
39d14abf15SRobert Mustacchi #include "bnxe.h"
40d14abf15SRobert Mustacchi
41d14abf15SRobert Mustacchi
42d14abf15SRobert Mustacchi #ifdef BNXE_DEBUG_DMA_LIST
43d14abf15SRobert Mustacchi
BnxeVerifySavedDmaList(um_device_t * pUM)44d14abf15SRobert Mustacchi static void BnxeVerifySavedDmaList(um_device_t * pUM)
45d14abf15SRobert Mustacchi {
46d14abf15SRobert Mustacchi BnxeMemDma * pTmp;
47d14abf15SRobert Mustacchi int i;
48d14abf15SRobert Mustacchi
49d14abf15SRobert Mustacchi BNXE_LOCK_ENTER_MEM(pUM);
50d14abf15SRobert Mustacchi
51d14abf15SRobert Mustacchi pTmp = (BnxeMemDma *)d_list_peek_head(&pUM->memDmaListSaved);
52d14abf15SRobert Mustacchi while (pTmp)
53d14abf15SRobert Mustacchi {
54d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "testing dma block %p / %p %d",
55d14abf15SRobert Mustacchi pTmp, pTmp->pDmaVirt, pTmp->size);
56d14abf15SRobert Mustacchi for (i = 0; i < pTmp->size; i++)
57d14abf15SRobert Mustacchi {
58d14abf15SRobert Mustacchi if (((u8_t *)pTmp->pDmaVirt)[i] != 0x0)
59d14abf15SRobert Mustacchi {
60d14abf15SRobert Mustacchi BnxeDbgBreakMsg(pUM, "old dma block wacked %p (byte %i)",
61d14abf15SRobert Mustacchi pTmp, i);
62d14abf15SRobert Mustacchi }
63d14abf15SRobert Mustacchi }
64d14abf15SRobert Mustacchi
65d14abf15SRobert Mustacchi pTmp = (BnxeMemDma *)d_list_next_entry(&pTmp->link);
66d14abf15SRobert Mustacchi }
67d14abf15SRobert Mustacchi
68d14abf15SRobert Mustacchi BNXE_LOCK_EXIT_MEM(pUM);
69d14abf15SRobert Mustacchi }
70d14abf15SRobert Mustacchi
71d14abf15SRobert Mustacchi #endif /* BNXE_DEBUG_DMA_LIST */
72d14abf15SRobert Mustacchi
73d14abf15SRobert Mustacchi
BnxeRssEnable(um_device_t * pUM)74d14abf15SRobert Mustacchi static boolean_t BnxeRssEnable(um_device_t * pUM)
75d14abf15SRobert Mustacchi {
76d14abf15SRobert Mustacchi #define BNXE_RSS_HASH_KEY_SIZE 40
77d14abf15SRobert Mustacchi u8_t hashKey[BNXE_RSS_HASH_KEY_SIZE];
78d14abf15SRobert Mustacchi #define BNXE_RSS_INDIRECTION_TABLE_SIZE 128 /* must be a power of 2 */
79d14abf15SRobert Mustacchi u8_t indirectionTable[BNXE_RSS_INDIRECTION_TABLE_SIZE];
80d14abf15SRobert Mustacchi lm_rss_hash_t hashType;
81d14abf15SRobert Mustacchi int i, rc;
82d14abf15SRobert Mustacchi
83d14abf15SRobert Mustacchi if (!pUM->devParams.numRings)
84d14abf15SRobert Mustacchi {
85d14abf15SRobert Mustacchi return B_TRUE;
86d14abf15SRobert Mustacchi }
87d14abf15SRobert Mustacchi
88d14abf15SRobert Mustacchi /* fill out the indirection table */
89d14abf15SRobert Mustacchi for (i = 0; i < BNXE_RSS_INDIRECTION_TABLE_SIZE; i++)
90d14abf15SRobert Mustacchi {
91d14abf15SRobert Mustacchi indirectionTable[i] = (i % pUM->devParams.numRings);
92d14abf15SRobert Mustacchi }
93d14abf15SRobert Mustacchi
94d14abf15SRobert Mustacchi /* seed the hash function with random data */
95d14abf15SRobert Mustacchi random_get_pseudo_bytes(hashKey, BNXE_RSS_HASH_KEY_SIZE);
96d14abf15SRobert Mustacchi
97d14abf15SRobert Mustacchi hashType = (LM_RSS_HASH_IPV4 |
98d14abf15SRobert Mustacchi LM_RSS_HASH_TCP_IPV4 |
99d14abf15SRobert Mustacchi LM_RSS_HASH_IPV6 |
100d14abf15SRobert Mustacchi LM_RSS_HASH_TCP_IPV6);
101d14abf15SRobert Mustacchi
102d14abf15SRobert Mustacchi rc = lm_enable_rss((lm_device_t *)pUM,
103d14abf15SRobert Mustacchi indirectionTable,
104d14abf15SRobert Mustacchi BNXE_RSS_INDIRECTION_TABLE_SIZE,
105d14abf15SRobert Mustacchi hashKey,
106d14abf15SRobert Mustacchi BNXE_RSS_HASH_KEY_SIZE,
107d14abf15SRobert Mustacchi hashType,
108d14abf15SRobert Mustacchi FALSE,
109d14abf15SRobert Mustacchi NULL);
110d14abf15SRobert Mustacchi
111d14abf15SRobert Mustacchi if (rc == LM_STATUS_PENDING)
112d14abf15SRobert Mustacchi {
113d14abf15SRobert Mustacchi if ((rc = lm_wait_config_rss_done(&pUM->lm_dev)) != LM_STATUS_SUCCESS)
114d14abf15SRobert Mustacchi {
115d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to enable RSS from pending operation (%d)", rc);
116d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_NO_RESPONSE);
117d14abf15SRobert Mustacchi }
118d14abf15SRobert Mustacchi }
119d14abf15SRobert Mustacchi else if (rc != LM_STATUS_SUCCESS)
120d14abf15SRobert Mustacchi {
121d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to enable RSS (%d)", rc);
122d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
123d14abf15SRobert Mustacchi }
124d14abf15SRobert Mustacchi
125d14abf15SRobert Mustacchi return (rc == LM_STATUS_SUCCESS) ? B_TRUE : B_FALSE;
126d14abf15SRobert Mustacchi }
127d14abf15SRobert Mustacchi
128d14abf15SRobert Mustacchi
BnxeRssDisable(um_device_t * pUM)129d14abf15SRobert Mustacchi static lm_status_t BnxeRssDisable(um_device_t * pUM)
130d14abf15SRobert Mustacchi {
131*8993acd7SToomas Soome lm_status_t rc;
132d14abf15SRobert Mustacchi
133d14abf15SRobert Mustacchi rc = lm_disable_rss((lm_device_t *)pUM, FALSE, NULL);
134d14abf15SRobert Mustacchi
135d14abf15SRobert Mustacchi if (rc == LM_STATUS_PENDING)
136d14abf15SRobert Mustacchi {
137d14abf15SRobert Mustacchi if ((rc = lm_wait_config_rss_done(&pUM->lm_dev)) != LM_STATUS_SUCCESS)
138d14abf15SRobert Mustacchi {
139d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to disable RSS from pending operation (%d)", rc);
140d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_NO_RESPONSE);
141d14abf15SRobert Mustacchi }
142d14abf15SRobert Mustacchi }
143d14abf15SRobert Mustacchi else if (rc != LM_STATUS_SUCCESS)
144d14abf15SRobert Mustacchi {
145d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to disable RSS (%d)", rc);
146d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
147d14abf15SRobert Mustacchi }
148d14abf15SRobert Mustacchi
149*8993acd7SToomas Soome return (rc);
150d14abf15SRobert Mustacchi }
151d14abf15SRobert Mustacchi
152d14abf15SRobert Mustacchi
BnxeHwReqPhyMediumSettings(um_device_t * pUM)153d14abf15SRobert Mustacchi lm_medium_t BnxeHwReqPhyMediumSettings(um_device_t * pUM)
154d14abf15SRobert Mustacchi {
155d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
156d14abf15SRobert Mustacchi lm_medium_t medium = 0;
157d14abf15SRobert Mustacchi char buf[128];
158d14abf15SRobert Mustacchi int i;
159d14abf15SRobert Mustacchi
160d14abf15SRobert Mustacchi memset(pUM->hwinit.supported, 0, sizeof(pUM->hwinit.supported));
161d14abf15SRobert Mustacchi
162d14abf15SRobert Mustacchi switch (pLM->params.link.num_phys)
163d14abf15SRobert Mustacchi {
164d14abf15SRobert Mustacchi case 1:
165d14abf15SRobert Mustacchi
166d14abf15SRobert Mustacchi pUM->hwinit.supported[0] =
167d14abf15SRobert Mustacchi pLM->params.link.phy[ELINK_INT_PHY].supported;
168d14abf15SRobert Mustacchi pUM->hwinit.phy_cfg_size = 1;
169d14abf15SRobert Mustacchi break;
170d14abf15SRobert Mustacchi
171d14abf15SRobert Mustacchi case 2:
172d14abf15SRobert Mustacchi
173d14abf15SRobert Mustacchi pUM->hwinit.supported[0] =
174d14abf15SRobert Mustacchi pLM->params.link.phy[ELINK_EXT_PHY1].supported;
175d14abf15SRobert Mustacchi pUM->hwinit.phy_cfg_size = 1;
176d14abf15SRobert Mustacchi break;
177d14abf15SRobert Mustacchi
178d14abf15SRobert Mustacchi case 3:
179d14abf15SRobert Mustacchi
180d14abf15SRobert Mustacchi if (pLM->params.link.multi_phy_config &
181d14abf15SRobert Mustacchi PORT_HW_CFG_PHY_SWAPPED_ENABLED)
182d14abf15SRobert Mustacchi {
183d14abf15SRobert Mustacchi pUM->hwinit.supported[1] =
184d14abf15SRobert Mustacchi pLM->params.link.phy[ELINK_EXT_PHY1].supported;
185d14abf15SRobert Mustacchi pUM->hwinit.supported[0] =
186d14abf15SRobert Mustacchi pLM->params.link.phy[ELINK_EXT_PHY2].supported;
187d14abf15SRobert Mustacchi }
188d14abf15SRobert Mustacchi else
189d14abf15SRobert Mustacchi {
190d14abf15SRobert Mustacchi pUM->hwinit.supported[0] =
191d14abf15SRobert Mustacchi pLM->params.link.phy[ELINK_EXT_PHY1].supported;
192d14abf15SRobert Mustacchi pUM->hwinit.supported[1] =
193d14abf15SRobert Mustacchi pLM->params.link.phy[ELINK_EXT_PHY2].supported;
194d14abf15SRobert Mustacchi }
195d14abf15SRobert Mustacchi
196d14abf15SRobert Mustacchi pUM->hwinit.phy_cfg_size = 2;
197d14abf15SRobert Mustacchi break;
198d14abf15SRobert Mustacchi
199d14abf15SRobert Mustacchi default:
200d14abf15SRobert Mustacchi
201d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Unexpected number of phys, check nvram config! (%d)",
202d14abf15SRobert Mustacchi pLM->params.link.num_phys);
203d14abf15SRobert Mustacchi return 0;
204d14abf15SRobert Mustacchi }
205d14abf15SRobert Mustacchi
206d14abf15SRobert Mustacchi for (i = 0; i < pUM->hwinit.phy_cfg_size; i++)
207d14abf15SRobert Mustacchi {
208d14abf15SRobert Mustacchi *buf = 0;
209d14abf15SRobert Mustacchi snprintf(buf, sizeof(buf), "Phy %d supported:", i);
210d14abf15SRobert Mustacchi
211d14abf15SRobert Mustacchi if (!(pLM->params.link.speed_cap_mask[i] &
212d14abf15SRobert Mustacchi PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF))
213d14abf15SRobert Mustacchi {
214d14abf15SRobert Mustacchi pUM->hwinit.supported[i] &= ~ELINK_SUPPORTED_10baseT_Half;
215d14abf15SRobert Mustacchi }
216d14abf15SRobert Mustacchi else
217d14abf15SRobert Mustacchi {
218d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
219d14abf15SRobert Mustacchi " 10M/half");
220d14abf15SRobert Mustacchi }
221d14abf15SRobert Mustacchi
222d14abf15SRobert Mustacchi if (!(pLM->params.link.speed_cap_mask[i] &
223d14abf15SRobert Mustacchi PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL))
224d14abf15SRobert Mustacchi {
225d14abf15SRobert Mustacchi pUM->hwinit.supported[i] &= ~ELINK_SUPPORTED_10baseT_Full;
226d14abf15SRobert Mustacchi }
227d14abf15SRobert Mustacchi else
228d14abf15SRobert Mustacchi {
229d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
230d14abf15SRobert Mustacchi " 10M/full");
231d14abf15SRobert Mustacchi }
232d14abf15SRobert Mustacchi
233d14abf15SRobert Mustacchi if (!(pLM->params.link.speed_cap_mask[i] &
234d14abf15SRobert Mustacchi PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF))
235d14abf15SRobert Mustacchi {
236d14abf15SRobert Mustacchi pUM->hwinit.supported[i] &= ~ELINK_SUPPORTED_100baseT_Half;
237d14abf15SRobert Mustacchi }
238d14abf15SRobert Mustacchi else
239d14abf15SRobert Mustacchi {
240d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
241d14abf15SRobert Mustacchi " 100M/half");
242d14abf15SRobert Mustacchi }
243d14abf15SRobert Mustacchi
244d14abf15SRobert Mustacchi if (!(pLM->params.link.speed_cap_mask[i] &
245d14abf15SRobert Mustacchi PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL))
246d14abf15SRobert Mustacchi {
247d14abf15SRobert Mustacchi pUM->hwinit.supported[i] &= ~ELINK_SUPPORTED_100baseT_Full;
248d14abf15SRobert Mustacchi }
249d14abf15SRobert Mustacchi else
250d14abf15SRobert Mustacchi {
251d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
252d14abf15SRobert Mustacchi " 100M/full");
253d14abf15SRobert Mustacchi }
254d14abf15SRobert Mustacchi
255d14abf15SRobert Mustacchi if (!(pLM->params.link.speed_cap_mask[i] &
256d14abf15SRobert Mustacchi PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))
257d14abf15SRobert Mustacchi {
258d14abf15SRobert Mustacchi pUM->hwinit.supported[i] &= ~ELINK_SUPPORTED_1000baseT_Full;
259d14abf15SRobert Mustacchi }
260d14abf15SRobert Mustacchi else
261d14abf15SRobert Mustacchi {
262d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
263d14abf15SRobert Mustacchi " 1G");
264d14abf15SRobert Mustacchi }
265d14abf15SRobert Mustacchi
266d14abf15SRobert Mustacchi if (!(pLM->params.link.speed_cap_mask[i] &
267d14abf15SRobert Mustacchi PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
268d14abf15SRobert Mustacchi {
269d14abf15SRobert Mustacchi pUM->hwinit.supported[i] &= ~ELINK_SUPPORTED_2500baseX_Full;
270d14abf15SRobert Mustacchi }
271d14abf15SRobert Mustacchi else
272d14abf15SRobert Mustacchi {
273d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
274d14abf15SRobert Mustacchi " 2.5G");
275d14abf15SRobert Mustacchi }
276d14abf15SRobert Mustacchi
277d14abf15SRobert Mustacchi if (!(pLM->params.link.speed_cap_mask[i] &
278d14abf15SRobert Mustacchi PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
279d14abf15SRobert Mustacchi {
280d14abf15SRobert Mustacchi pUM->hwinit.supported[i] &= ~ELINK_SUPPORTED_10000baseT_Full;
281d14abf15SRobert Mustacchi }
282d14abf15SRobert Mustacchi else
283d14abf15SRobert Mustacchi {
284d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
285d14abf15SRobert Mustacchi " 10G");
286d14abf15SRobert Mustacchi }
287d14abf15SRobert Mustacchi
288d14abf15SRobert Mustacchi if (!(pLM->params.link.speed_cap_mask[i] &
289d14abf15SRobert Mustacchi PORT_HW_CFG_SPEED_CAPABILITY_D0_20G))
290d14abf15SRobert Mustacchi {
291d14abf15SRobert Mustacchi pUM->hwinit.supported[i] &= ~(ELINK_SUPPORTED_20000baseMLD2_Full |
292d14abf15SRobert Mustacchi ELINK_SUPPORTED_20000baseKR2_Full);
293d14abf15SRobert Mustacchi }
294d14abf15SRobert Mustacchi else
295d14abf15SRobert Mustacchi {
296d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
297d14abf15SRobert Mustacchi " 20G");
298d14abf15SRobert Mustacchi }
299d14abf15SRobert Mustacchi
300d14abf15SRobert Mustacchi BnxeLogInfo(pUM, buf);
301d14abf15SRobert Mustacchi
302d14abf15SRobert Mustacchi *buf = 0;
303d14abf15SRobert Mustacchi snprintf(buf, sizeof(buf), "Phy %d link config:", i);
304d14abf15SRobert Mustacchi
305d14abf15SRobert Mustacchi switch ((uint32_t)pLM->hw_info.link_config[i] &
306d14abf15SRobert Mustacchi PORT_FEATURE_CONNECTED_SWITCH_MASK)
307d14abf15SRobert Mustacchi {
308d14abf15SRobert Mustacchi case PORT_FEATURE_CON_SWITCH_1G_SWITCH:
309d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
310d14abf15SRobert Mustacchi " switch/1G");
311d14abf15SRobert Mustacchi break;
312d14abf15SRobert Mustacchi case PORT_FEATURE_CON_SWITCH_10G_SWITCH:
313d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
314d14abf15SRobert Mustacchi " switch/10G");
315d14abf15SRobert Mustacchi break;
316d14abf15SRobert Mustacchi case PORT_FEATURE_CON_SWITCH_AUTO_DETECT:
317d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
318d14abf15SRobert Mustacchi " switch/auto");
319d14abf15SRobert Mustacchi break;
320d14abf15SRobert Mustacchi case PORT_FEATURE_CON_SWITCH_ONE_TIME_DETECT:
321d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
322d14abf15SRobert Mustacchi " switch/once");
323d14abf15SRobert Mustacchi break;
324d14abf15SRobert Mustacchi default:
325d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
326d14abf15SRobert Mustacchi " switch/unknown");
327d14abf15SRobert Mustacchi break;
328d14abf15SRobert Mustacchi }
329d14abf15SRobert Mustacchi
330d14abf15SRobert Mustacchi switch ((uint32_t)pLM->hw_info.link_config[i] &
331d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK)
332d14abf15SRobert Mustacchi {
333d14abf15SRobert Mustacchi case PORT_FEATURE_LINK_SPEED_AUTO:
334d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
335d14abf15SRobert Mustacchi " speed/auto");
336d14abf15SRobert Mustacchi break;
337d14abf15SRobert Mustacchi case PORT_FEATURE_LINK_SPEED_10M_FULL:
338d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
339d14abf15SRobert Mustacchi " speed/10M/full");
340d14abf15SRobert Mustacchi break;
341d14abf15SRobert Mustacchi case PORT_FEATURE_LINK_SPEED_10M_HALF:
342d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
343d14abf15SRobert Mustacchi " speed/10M/half");
344d14abf15SRobert Mustacchi break;
345d14abf15SRobert Mustacchi case PORT_FEATURE_LINK_SPEED_100M_HALF:
346d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
347d14abf15SRobert Mustacchi " speed/100M/half");
348d14abf15SRobert Mustacchi break;
349d14abf15SRobert Mustacchi case PORT_FEATURE_LINK_SPEED_100M_FULL:
350d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
351d14abf15SRobert Mustacchi " speed/100M/full");
352d14abf15SRobert Mustacchi break;
353d14abf15SRobert Mustacchi case PORT_FEATURE_LINK_SPEED_1G:
354d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
355d14abf15SRobert Mustacchi " speed/1G");
356d14abf15SRobert Mustacchi break;
357d14abf15SRobert Mustacchi case PORT_FEATURE_LINK_SPEED_2_5G:
358d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
359d14abf15SRobert Mustacchi " speed/2.5G");
360d14abf15SRobert Mustacchi break;
361d14abf15SRobert Mustacchi case PORT_FEATURE_LINK_SPEED_10G_CX4:
362d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
363d14abf15SRobert Mustacchi " speed/10G");
364d14abf15SRobert Mustacchi break;
365d14abf15SRobert Mustacchi case PORT_FEATURE_LINK_SPEED_20G:
366d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
367d14abf15SRobert Mustacchi " speed/20G");
368d14abf15SRobert Mustacchi break;
369d14abf15SRobert Mustacchi default:
370d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
371d14abf15SRobert Mustacchi " speed/unknown");
372d14abf15SRobert Mustacchi break;
373d14abf15SRobert Mustacchi }
374d14abf15SRobert Mustacchi
375d14abf15SRobert Mustacchi switch ((uint32_t)pLM->hw_info.link_config[i] &
376d14abf15SRobert Mustacchi PORT_FEATURE_FLOW_CONTROL_MASK)
377d14abf15SRobert Mustacchi {
378d14abf15SRobert Mustacchi case PORT_FEATURE_FLOW_CONTROL_AUTO:
379d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
380d14abf15SRobert Mustacchi " flow/auto");
381d14abf15SRobert Mustacchi break;
382d14abf15SRobert Mustacchi case PORT_FEATURE_FLOW_CONTROL_TX:
383d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
384d14abf15SRobert Mustacchi " flow/tx");
385d14abf15SRobert Mustacchi break;
386d14abf15SRobert Mustacchi case PORT_FEATURE_FLOW_CONTROL_RX:
387d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
388d14abf15SRobert Mustacchi " flow/rx");
389d14abf15SRobert Mustacchi break;
390d14abf15SRobert Mustacchi case PORT_FEATURE_FLOW_CONTROL_BOTH:
391d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
392d14abf15SRobert Mustacchi " flow/both");
393d14abf15SRobert Mustacchi break;
394d14abf15SRobert Mustacchi case PORT_FEATURE_FLOW_CONTROL_NONE:
395d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
396d14abf15SRobert Mustacchi " flow/none");
397d14abf15SRobert Mustacchi break;
398d14abf15SRobert Mustacchi default:
399d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
400d14abf15SRobert Mustacchi " flow/unknown");
401d14abf15SRobert Mustacchi break;
402d14abf15SRobert Mustacchi }
403d14abf15SRobert Mustacchi
404d14abf15SRobert Mustacchi BnxeLogInfo(pUM, buf);
405d14abf15SRobert Mustacchi }
406d14abf15SRobert Mustacchi
407d14abf15SRobert Mustacchi for (i = 0; i < pUM->hwinit.phy_cfg_size; i++)
408d14abf15SRobert Mustacchi {
409d14abf15SRobert Mustacchi *buf = 0;
410d14abf15SRobert Mustacchi snprintf(buf, sizeof(buf), "Requesting Phy %d speed:", i);
411d14abf15SRobert Mustacchi
412d14abf15SRobert Mustacchi if (pUM->curcfg.lnkcfg.param_10hdx)
413d14abf15SRobert Mustacchi {
414d14abf15SRobert Mustacchi if (((pLM->hw_info.link_config[i] &
415d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
416d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_AUTO) ||
417d14abf15SRobert Mustacchi ((pLM->hw_info.link_config[i] &
418d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
419d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_10M_HALF))
420d14abf15SRobert Mustacchi {
421d14abf15SRobert Mustacchi medium |= (LM_MEDIUM_SPEED_10MBPS | LM_MEDIUM_HALF_DUPLEX);
422d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
423d14abf15SRobert Mustacchi " 10M/half");
424d14abf15SRobert Mustacchi }
425d14abf15SRobert Mustacchi else
426d14abf15SRobert Mustacchi {
427d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Phy 10hdx requested but not supported");
428d14abf15SRobert Mustacchi }
429d14abf15SRobert Mustacchi }
430d14abf15SRobert Mustacchi
431d14abf15SRobert Mustacchi if (pUM->curcfg.lnkcfg.param_10fdx)
432d14abf15SRobert Mustacchi {
433d14abf15SRobert Mustacchi if (((pLM->hw_info.link_config[i] &
434d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
435d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_AUTO) ||
436d14abf15SRobert Mustacchi ((pLM->hw_info.link_config[i] &
437d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
438d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_10M_FULL))
439d14abf15SRobert Mustacchi {
440d14abf15SRobert Mustacchi medium |= (LM_MEDIUM_SPEED_10MBPS | LM_MEDIUM_FULL_DUPLEX);
441d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
442d14abf15SRobert Mustacchi " 10M/full");
443d14abf15SRobert Mustacchi }
444d14abf15SRobert Mustacchi else
445d14abf15SRobert Mustacchi {
446d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Phy 10fdx requested but not supported");
447d14abf15SRobert Mustacchi }
448d14abf15SRobert Mustacchi }
449d14abf15SRobert Mustacchi
450d14abf15SRobert Mustacchi if (pUM->curcfg.lnkcfg.param_100hdx)
451d14abf15SRobert Mustacchi {
452d14abf15SRobert Mustacchi if (((pLM->hw_info.link_config[i] &
453d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
454d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_AUTO) ||
455d14abf15SRobert Mustacchi ((pLM->hw_info.link_config[i] &
456d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
457d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_100M_HALF))
458d14abf15SRobert Mustacchi {
459d14abf15SRobert Mustacchi medium |= (LM_MEDIUM_SPEED_100MBPS | LM_MEDIUM_HALF_DUPLEX);
460d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
461d14abf15SRobert Mustacchi " 100M/half");
462d14abf15SRobert Mustacchi }
463d14abf15SRobert Mustacchi else
464d14abf15SRobert Mustacchi {
465d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Phy 100hdx requested but not supported");
466d14abf15SRobert Mustacchi }
467d14abf15SRobert Mustacchi }
468d14abf15SRobert Mustacchi
469d14abf15SRobert Mustacchi if (pUM->curcfg.lnkcfg.param_100fdx)
470d14abf15SRobert Mustacchi {
471d14abf15SRobert Mustacchi if (((pLM->hw_info.link_config[i] &
472d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
473d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_AUTO) ||
474d14abf15SRobert Mustacchi ((pLM->hw_info.link_config[i] &
475d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
476d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_100M_FULL))
477d14abf15SRobert Mustacchi {
478d14abf15SRobert Mustacchi medium |= (LM_MEDIUM_SPEED_100MBPS | LM_MEDIUM_FULL_DUPLEX);
479d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
480d14abf15SRobert Mustacchi " 100M/full");
481d14abf15SRobert Mustacchi }
482d14abf15SRobert Mustacchi else
483d14abf15SRobert Mustacchi {
484d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Phy 100fdx requested but not supported");
485d14abf15SRobert Mustacchi }
486d14abf15SRobert Mustacchi }
487d14abf15SRobert Mustacchi
488d14abf15SRobert Mustacchi if (pUM->curcfg.lnkcfg.param_1000fdx)
489d14abf15SRobert Mustacchi {
490d14abf15SRobert Mustacchi if (((pLM->hw_info.link_config[i] &
491d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
492d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_AUTO) ||
493d14abf15SRobert Mustacchi ((pLM->hw_info.link_config[i] &
494d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
495d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_1G))
496d14abf15SRobert Mustacchi {
497d14abf15SRobert Mustacchi medium |= (LM_MEDIUM_SPEED_1000MBPS | LM_MEDIUM_FULL_DUPLEX);
498d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
499d14abf15SRobert Mustacchi " 1G");
500d14abf15SRobert Mustacchi }
501d14abf15SRobert Mustacchi else
502d14abf15SRobert Mustacchi {
503d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Phy 1000fdx requested but not supported");
504d14abf15SRobert Mustacchi }
505d14abf15SRobert Mustacchi }
506d14abf15SRobert Mustacchi
507d14abf15SRobert Mustacchi if (pUM->curcfg.lnkcfg.param_10000fdx)
508d14abf15SRobert Mustacchi {
509d14abf15SRobert Mustacchi if (((pLM->hw_info.link_config[i] &
510d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
511d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_AUTO) ||
512d14abf15SRobert Mustacchi ((pLM->hw_info.link_config[i] &
513d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
514d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_10G_CX4))
515d14abf15SRobert Mustacchi {
516d14abf15SRobert Mustacchi medium |= (LM_MEDIUM_SPEED_10GBPS | LM_MEDIUM_FULL_DUPLEX);
517d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
518d14abf15SRobert Mustacchi " 10G");
519d14abf15SRobert Mustacchi }
520d14abf15SRobert Mustacchi else
521d14abf15SRobert Mustacchi {
522d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Phy 10000fdx requested but not supported");
523d14abf15SRobert Mustacchi }
524d14abf15SRobert Mustacchi }
525d14abf15SRobert Mustacchi
526d14abf15SRobert Mustacchi if (pUM->curcfg.lnkcfg.param_20000fdx)
527d14abf15SRobert Mustacchi {
528d14abf15SRobert Mustacchi if (((pLM->hw_info.link_config[i] &
529d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
530d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_AUTO) ||
531d14abf15SRobert Mustacchi ((pLM->hw_info.link_config[i] &
532d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
533d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_20G))
534d14abf15SRobert Mustacchi {
535d14abf15SRobert Mustacchi medium |= (LM_MEDIUM_SPEED_20GBPS | LM_MEDIUM_FULL_DUPLEX);
536d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
537d14abf15SRobert Mustacchi " 20G");
538d14abf15SRobert Mustacchi }
539d14abf15SRobert Mustacchi else
540d14abf15SRobert Mustacchi {
541d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Phy 20000fdx requested but not supported");
542d14abf15SRobert Mustacchi }
543d14abf15SRobert Mustacchi }
544d14abf15SRobert Mustacchi
545d14abf15SRobert Mustacchi if (pUM->curcfg.lnkcfg.link_autoneg)
546d14abf15SRobert Mustacchi {
547d14abf15SRobert Mustacchi if ((pLM->hw_info.link_config[i] &
548d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_MASK) ==
549d14abf15SRobert Mustacchi PORT_FEATURE_LINK_SPEED_AUTO)
550d14abf15SRobert Mustacchi {
551d14abf15SRobert Mustacchi if (medium)
552d14abf15SRobert Mustacchi {
553d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Phy autoneg requested along with other speeds, ignoring others and forcing autoneg");
554d14abf15SRobert Mustacchi }
555d14abf15SRobert Mustacchi
556d14abf15SRobert Mustacchi medium = LM_MEDIUM_SPEED_AUTONEG; /* 0x0000 */
557d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
558d14abf15SRobert Mustacchi " auto");
559d14abf15SRobert Mustacchi }
560d14abf15SRobert Mustacchi else
561d14abf15SRobert Mustacchi {
562d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Phy autoneg requested but not supported");
563d14abf15SRobert Mustacchi }
564d14abf15SRobert Mustacchi }
565d14abf15SRobert Mustacchi
566d14abf15SRobert Mustacchi BnxeLogInfo(pUM, buf);
567d14abf15SRobert Mustacchi }
568d14abf15SRobert Mustacchi
569d14abf15SRobert Mustacchi medium |= LM_MEDIUM_TYPE_XGXS;
570d14abf15SRobert Mustacchi
571d14abf15SRobert Mustacchi return medium;
572d14abf15SRobert Mustacchi }
573d14abf15SRobert Mustacchi
574d14abf15SRobert Mustacchi
BnxeHwReqPhyFlowSettings(um_device_t * pUM)575d14abf15SRobert Mustacchi lm_flow_control_t BnxeHwReqPhyFlowSettings(um_device_t * pUM)
576d14abf15SRobert Mustacchi {
577d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
578d14abf15SRobert Mustacchi lm_flow_control_t flowctrl;
579d14abf15SRobert Mustacchi char buf[128];
580d14abf15SRobert Mustacchi int i;
581d14abf15SRobert Mustacchi
582d14abf15SRobert Mustacchi flowctrl = LM_FLOW_CONTROL_NONE;
583d14abf15SRobert Mustacchi
584d14abf15SRobert Mustacchi for (i = 0; i < pUM->hwinit.phy_cfg_size; i++)
585d14abf15SRobert Mustacchi {
586d14abf15SRobert Mustacchi *buf = 0;
587d14abf15SRobert Mustacchi snprintf(buf, sizeof(buf), "Requesting Phy %d flow:", i);
588d14abf15SRobert Mustacchi
589d14abf15SRobert Mustacchi if (pUM->curcfg.lnkcfg.param_txpause)
590d14abf15SRobert Mustacchi {
591d14abf15SRobert Mustacchi if ((pLM->hw_info.link_config[i] &
592d14abf15SRobert Mustacchi PORT_FEATURE_FLOW_CONTROL_MASK) &
593d14abf15SRobert Mustacchi PORT_FEATURE_FLOW_CONTROL_TX)
594d14abf15SRobert Mustacchi {
595d14abf15SRobert Mustacchi flowctrl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
596d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
597d14abf15SRobert Mustacchi " tx");
598d14abf15SRobert Mustacchi }
599d14abf15SRobert Mustacchi else
600d14abf15SRobert Mustacchi {
601d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Phy TX flow requested but not supported");
602d14abf15SRobert Mustacchi }
603d14abf15SRobert Mustacchi }
604d14abf15SRobert Mustacchi
605d14abf15SRobert Mustacchi if (pUM->curcfg.lnkcfg.param_rxpause)
606d14abf15SRobert Mustacchi {
607d14abf15SRobert Mustacchi if ((pLM->hw_info.link_config[i] &
608d14abf15SRobert Mustacchi PORT_FEATURE_FLOW_CONTROL_MASK) &
609d14abf15SRobert Mustacchi PORT_FEATURE_FLOW_CONTROL_RX)
610d14abf15SRobert Mustacchi {
611d14abf15SRobert Mustacchi flowctrl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
612d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
613d14abf15SRobert Mustacchi " rx");
614d14abf15SRobert Mustacchi }
615d14abf15SRobert Mustacchi else
616d14abf15SRobert Mustacchi {
617d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Phy RX flow requested but not supported");
618d14abf15SRobert Mustacchi }
619d14abf15SRobert Mustacchi }
620d14abf15SRobert Mustacchi
621d14abf15SRobert Mustacchi if (pUM->curcfg.flow_autoneg)
622d14abf15SRobert Mustacchi {
623d14abf15SRobert Mustacchi /*
624d14abf15SRobert Mustacchi * This value can be or'ed with receive pause and transmit
625d14abf15SRobert Mustacchi * pause. If the auto-negotiation is disabled and the receive
626d14abf15SRobert Mustacchi * pause and transmit pause bits are set, then flow control is
627d14abf15SRobert Mustacchi * enabled regardless of link partner's flow control capability.
628d14abf15SRobert Mustacchi * Otherwise, if this bit is set, then flow is negotiated with
629d14abf15SRobert Mustacchi * the link partner. Values 0x80000000 and 0x80000003 are
630d14abf15SRobert Mustacchi * equivalent.
631d14abf15SRobert Mustacchi */
632d14abf15SRobert Mustacchi if ((pLM->hw_info.link_config[i] &
633d14abf15SRobert Mustacchi PORT_FEATURE_FLOW_CONTROL_MASK) ==
634d14abf15SRobert Mustacchi PORT_FEATURE_FLOW_CONTROL_AUTO)
635d14abf15SRobert Mustacchi {
636d14abf15SRobert Mustacchi flowctrl |= LM_FLOW_CONTROL_AUTO_PAUSE;
637d14abf15SRobert Mustacchi snprintf(buf + strlen(buf), (sizeof(buf) - strlen(buf)),
638d14abf15SRobert Mustacchi " auto");
639d14abf15SRobert Mustacchi }
640d14abf15SRobert Mustacchi else
641d14abf15SRobert Mustacchi {
642d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Phy Auto flow requested but not supported");
643d14abf15SRobert Mustacchi }
644d14abf15SRobert Mustacchi }
645d14abf15SRobert Mustacchi
646d14abf15SRobert Mustacchi BnxeLogInfo(pUM, buf);
647d14abf15SRobert Mustacchi }
648d14abf15SRobert Mustacchi
649d14abf15SRobert Mustacchi return flowctrl;
650d14abf15SRobert Mustacchi }
651d14abf15SRobert Mustacchi
652d14abf15SRobert Mustacchi
BnxeUpdatePhy(um_device_t * pUM)653d14abf15SRobert Mustacchi void BnxeUpdatePhy(um_device_t * pUM)
654d14abf15SRobert Mustacchi {
655d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
656d14abf15SRobert Mustacchi int rc;
657d14abf15SRobert Mustacchi
658d14abf15SRobert Mustacchi BNXE_LOCK_ENTER_PHY(pUM);
659d14abf15SRobert Mustacchi
660d14abf15SRobert Mustacchi pLM->params.req_medium = BnxeHwReqPhyMediumSettings(pUM);
661d14abf15SRobert Mustacchi pLM->params.flow_ctrl_cap = BnxeHwReqPhyFlowSettings(pUM);
662d14abf15SRobert Mustacchi
663d14abf15SRobert Mustacchi if (IS_PMF(&pUM->lm_dev))
664d14abf15SRobert Mustacchi {
665d14abf15SRobert Mustacchi lm_reset_link(pLM);
666d14abf15SRobert Mustacchi }
667d14abf15SRobert Mustacchi
668d14abf15SRobert Mustacchi rc = lm_init_phy(pLM,
669d14abf15SRobert Mustacchi pLM->params.req_medium,
670d14abf15SRobert Mustacchi pLM->params.flow_ctrl_cap,
671d14abf15SRobert Mustacchi 0 /* pLM->params.selective_autoneg */,
672d14abf15SRobert Mustacchi 0 /* pLM->params.wire_speed */,
673d14abf15SRobert Mustacchi 0);
674d14abf15SRobert Mustacchi
675d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
676d14abf15SRobert Mustacchi BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
677d14abf15SRobert Mustacchi {
678d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
679d14abf15SRobert Mustacchi }
680d14abf15SRobert Mustacchi
681d14abf15SRobert Mustacchi if (rc == LM_STATUS_SUCCESS)
682d14abf15SRobert Mustacchi {
683d14abf15SRobert Mustacchi pUM->phyInitialized = B_TRUE;
684d14abf15SRobert Mustacchi }
685d14abf15SRobert Mustacchi else
686d14abf15SRobert Mustacchi {
687d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to initialize the phy (%d)", rc);
688d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
689d14abf15SRobert Mustacchi }
690d14abf15SRobert Mustacchi
691d14abf15SRobert Mustacchi #if 0
692d14abf15SRobert Mustacchi /*
693d14abf15SRobert Mustacchi * This is problematic. For non-PMF functions the lm_niv_vif_set for
694d14abf15SRobert Mustacchi * a link up will come very early and is queued for processing right
695d14abf15SRobert Mustacchi * after lm_chip_start. Thereafter setting the loopback mode brings
696*8993acd7SToomas Soome * the interface back down. Don't know if setting the loopback mode
697d14abf15SRobert Mustacchi * is even required when forcing it off. XXX
698d14abf15SRobert Mustacchi */
699d14abf15SRobert Mustacchi if (IS_MF_AFEX_MODE(&pUM->lm_dev))
700d14abf15SRobert Mustacchi {
701d14abf15SRobert Mustacchi lm_niv_set_loopback_mode(&pUM->lm_dev, FALSE);
702d14abf15SRobert Mustacchi }
703d14abf15SRobert Mustacchi #endif
704d14abf15SRobert Mustacchi
705d14abf15SRobert Mustacchi BNXE_LOCK_EXIT_PHY(pUM);
706d14abf15SRobert Mustacchi }
707d14abf15SRobert Mustacchi
708d14abf15SRobert Mustacchi
709d14abf15SRobert Mustacchi /*
710d14abf15SRobert Mustacchi * (flag) TRUE = add, FALSE = remove
711d14abf15SRobert Mustacchi *
712d14abf15SRobert Mustacchi * This function must be called with BNXE_LOCK_ENTER_HWINIT held because this
713d14abf15SRobert Mustacchi * is shared between GLDv3 and FCoE entry points.
714d14abf15SRobert Mustacchi */
BnxeMacAddress(um_device_t * pUM,int cliIdx,boolean_t flag,const uint8_t * pMacAddr)715d14abf15SRobert Mustacchi int BnxeMacAddress(um_device_t * pUM,
716d14abf15SRobert Mustacchi int cliIdx,
717d14abf15SRobert Mustacchi boolean_t flag,
718d14abf15SRobert Mustacchi const uint8_t * pMacAddr)
719d14abf15SRobert Mustacchi {
720d14abf15SRobert Mustacchi int i, rc;
721d14abf15SRobert Mustacchi
722d14abf15SRobert Mustacchi if ((cliIdx != LM_CLI_IDX_NDIS) && (cliIdx != LM_CLI_IDX_FCOE))
723d14abf15SRobert Mustacchi {
724d14abf15SRobert Mustacchi return EINVAL;
725d14abf15SRobert Mustacchi }
726d14abf15SRobert Mustacchi
727d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "%s MAC address: %02x:%02x:%02x:%02x:%02x:%02x",
728d14abf15SRobert Mustacchi (flag) ? "Adding" : "Removing",
729d14abf15SRobert Mustacchi pMacAddr[0], pMacAddr[1], pMacAddr[2],
730d14abf15SRobert Mustacchi pMacAddr[3], pMacAddr[4], pMacAddr[5]);
731d14abf15SRobert Mustacchi
732d14abf15SRobert Mustacchi rc = lm_set_mac_addr(&pUM->lm_dev,
733d14abf15SRobert Mustacchi (u8_t *)pMacAddr,
734d14abf15SRobert Mustacchi /* XXX */ LM_SET_CAM_NO_VLAN_FILTER,
735d14abf15SRobert Mustacchi LM_CLI_CID(&pUM->lm_dev, cliIdx),
736d14abf15SRobert Mustacchi NULL, flag, 0);
737d14abf15SRobert Mustacchi
738d14abf15SRobert Mustacchi if (rc == LM_STATUS_PENDING)
739d14abf15SRobert Mustacchi {
740d14abf15SRobert Mustacchi if ((rc = lm_wait_set_mac_done(&pUM->lm_dev,
741d14abf15SRobert Mustacchi LM_CLI_CID(&pUM->lm_dev, cliIdx))) !=
742d14abf15SRobert Mustacchi LM_STATUS_SUCCESS)
743d14abf15SRobert Mustacchi {
744d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to %s MAC Address from pending operation (%d)",
745d14abf15SRobert Mustacchi (flag) ? "set" : "remove", rc);
746d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_NO_RESPONSE);
747d14abf15SRobert Mustacchi return ENOMEM;
748d14abf15SRobert Mustacchi }
749d14abf15SRobert Mustacchi }
750d14abf15SRobert Mustacchi else if ((rc != LM_STATUS_PENDING) && (rc != LM_STATUS_EXISTING_OBJECT))
751d14abf15SRobert Mustacchi {
752d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to %s MAC Address (%d)",
753d14abf15SRobert Mustacchi (flag) ? "set" : "remove", rc);
754d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
755d14abf15SRobert Mustacchi return ENOMEM;
756d14abf15SRobert Mustacchi }
757d14abf15SRobert Mustacchi
758d14abf15SRobert Mustacchi return 0;
759d14abf15SRobert Mustacchi }
760d14abf15SRobert Mustacchi
761d14abf15SRobert Mustacchi
762d14abf15SRobert Mustacchi /*
763d14abf15SRobert Mustacchi * This function is used to enable or disable multicast packet reception for
764d14abf15SRobert Mustacchi * particular multicast addresses. (flag) TRUE = add, FALSE = remove.
765d14abf15SRobert Mustacchi *
766d14abf15SRobert Mustacchi * This function must be called with BNXE_LOCK_ENTER_HWINIT held because this
767d14abf15SRobert Mustacchi * is shared between GLDv3 and FCoE entry points.
768d14abf15SRobert Mustacchi */
769d14abf15SRobert Mustacchi
BnxeMulticastE1(um_device_t * pUM,int cliIdx)770d14abf15SRobert Mustacchi void BnxeMulticastE1(um_device_t * pUM,
771d14abf15SRobert Mustacchi int cliIdx)
772d14abf15SRobert Mustacchi {
773d14abf15SRobert Mustacchi if ((cliIdx != LM_CLI_IDX_NDIS) || !CHIP_IS_E1(&pUM->lm_dev))
774d14abf15SRobert Mustacchi {
775d14abf15SRobert Mustacchi return;
776d14abf15SRobert Mustacchi }
777d14abf15SRobert Mustacchi
778d14abf15SRobert Mustacchi /* already holding BNXE_LOCK_ENTER_HWINIT */
779d14abf15SRobert Mustacchi
780d14abf15SRobert Mustacchi if (d_list_entry_cnt(&pUM->mcast_l2) > 64)
781d14abf15SRobert Mustacchi {
782d14abf15SRobert Mustacchi if (!(pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS] &
783d14abf15SRobert Mustacchi LM_RX_MASK_ACCEPT_ALL_MULTICAST))
784d14abf15SRobert Mustacchi {
785d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "Turning ON the ALL_MCAST rx mask, number of multicast addressess is >64");
786d14abf15SRobert Mustacchi
787d14abf15SRobert Mustacchi pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS] |=
788d14abf15SRobert Mustacchi LM_RX_MASK_ACCEPT_ALL_MULTICAST;
789d14abf15SRobert Mustacchi
790d14abf15SRobert Mustacchi BnxeRxMask(pUM, LM_CLI_IDX_NDIS,
791d14abf15SRobert Mustacchi pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS]);
792d14abf15SRobert Mustacchi }
793d14abf15SRobert Mustacchi }
794d14abf15SRobert Mustacchi else
795d14abf15SRobert Mustacchi {
796d14abf15SRobert Mustacchi if (pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS] &
797d14abf15SRobert Mustacchi LM_RX_MASK_ACCEPT_ALL_MULTICAST)
798d14abf15SRobert Mustacchi {
799d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "Turning OFF the ALL_MCAST rx mask, number of multicast addressess is <=64");
800d14abf15SRobert Mustacchi
801d14abf15SRobert Mustacchi pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS] &=
802d14abf15SRobert Mustacchi ~LM_RX_MASK_ACCEPT_ALL_MULTICAST;
803d14abf15SRobert Mustacchi
804d14abf15SRobert Mustacchi BnxeRxMask(pUM, LM_CLI_IDX_NDIS,
805d14abf15SRobert Mustacchi pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS]);
806d14abf15SRobert Mustacchi }
807d14abf15SRobert Mustacchi }
808d14abf15SRobert Mustacchi }
809d14abf15SRobert Mustacchi
BnxeMulticast(um_device_t * pUM,int cliIdx,boolean_t flag,const uint8_t * pMcastAddr,boolean_t hwSet)810d14abf15SRobert Mustacchi int BnxeMulticast(um_device_t * pUM,
811d14abf15SRobert Mustacchi int cliIdx,
812d14abf15SRobert Mustacchi boolean_t flag,
813d14abf15SRobert Mustacchi const uint8_t * pMcastAddr,
814d14abf15SRobert Mustacchi boolean_t hwSet)
815d14abf15SRobert Mustacchi {
816d14abf15SRobert Mustacchi struct ecore_mcast_list_elem * pTmp;
817d14abf15SRobert Mustacchi d_list_t * mcastList;
818d14abf15SRobert Mustacchi int i, rc;
819d14abf15SRobert Mustacchi
820d14abf15SRobert Mustacchi if ((cliIdx != LM_CLI_IDX_NDIS) && (cliIdx != LM_CLI_IDX_FCOE))
821d14abf15SRobert Mustacchi {
822d14abf15SRobert Mustacchi return EINVAL;
823d14abf15SRobert Mustacchi }
824d14abf15SRobert Mustacchi
825d14abf15SRobert Mustacchi if (!pMcastAddr)
826d14abf15SRobert Mustacchi {
827d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "Removing all multicast");
828d14abf15SRobert Mustacchi }
829d14abf15SRobert Mustacchi else
830d14abf15SRobert Mustacchi {
831d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "%s multicast: %02x:%02x:%02x:%02x:%02x:%02x",
832d14abf15SRobert Mustacchi (flag) ? "Adding" : "Removing",
833d14abf15SRobert Mustacchi pMcastAddr[0], pMcastAddr[1], pMcastAddr[2],
834d14abf15SRobert Mustacchi pMcastAddr[3], pMcastAddr[4], pMcastAddr[5]);
835d14abf15SRobert Mustacchi }
836d14abf15SRobert Mustacchi
837d14abf15SRobert Mustacchi mcastList = (cliIdx == LM_CLI_IDX_NDIS) ? &pUM->mcast_l2 :
838d14abf15SRobert Mustacchi &pUM->mcast_fcoe;
839d14abf15SRobert Mustacchi
840d14abf15SRobert Mustacchi if (flag && (pMcastAddr == NULL))
841d14abf15SRobert Mustacchi {
842d14abf15SRobert Mustacchi /* adding a new address that isn't specified...? */
843d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "ERROR: Multicast address not specified");
844d14abf15SRobert Mustacchi return EINVAL;
845d14abf15SRobert Mustacchi }
846d14abf15SRobert Mustacchi else if (!flag && (pMcastAddr == NULL))
847d14abf15SRobert Mustacchi {
848d14abf15SRobert Mustacchi /* clear all multicast addresses */
849d14abf15SRobert Mustacchi
850d14abf15SRobert Mustacchi while (d_list_entry_cnt(mcastList))
851d14abf15SRobert Mustacchi {
852d14abf15SRobert Mustacchi pTmp = (struct ecore_mcast_list_elem *)d_list_pop_head(mcastList);
853d14abf15SRobert Mustacchi kmem_free(pTmp, (sizeof(struct ecore_mcast_list_elem) +
854d14abf15SRobert Mustacchi ETHERNET_ADDRESS_SIZE));
855d14abf15SRobert Mustacchi }
856d14abf15SRobert Mustacchi
857d14abf15SRobert Mustacchi if (!hwSet)
858d14abf15SRobert Mustacchi {
859d14abf15SRobert Mustacchi return 0;
860d14abf15SRobert Mustacchi }
861d14abf15SRobert Mustacchi
862d14abf15SRobert Mustacchi rc = lm_set_mc_list(&pUM->lm_dev, mcastList, NULL, cliIdx);
863d14abf15SRobert Mustacchi
864d14abf15SRobert Mustacchi if (rc == LM_STATUS_PENDING)
865d14abf15SRobert Mustacchi {
866d14abf15SRobert Mustacchi if ((rc = lm_wait_set_mc_done(&pUM->lm_dev, cliIdx)) !=
867d14abf15SRobert Mustacchi LM_STATUS_SUCCESS)
868d14abf15SRobert Mustacchi {
869d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to clear Multicast Address table from pending operation (%d)", rc);
870d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_NO_RESPONSE);
871d14abf15SRobert Mustacchi return ENOMEM;
872d14abf15SRobert Mustacchi }
873d14abf15SRobert Mustacchi }
874d14abf15SRobert Mustacchi else if (rc != LM_STATUS_SUCCESS)
875d14abf15SRobert Mustacchi {
876d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to clear Multicast Address table (%d)", rc);
877d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
878d14abf15SRobert Mustacchi return ENOMEM;
879d14abf15SRobert Mustacchi }
880d14abf15SRobert Mustacchi
881d14abf15SRobert Mustacchi BnxeMulticastE1(pUM, cliIdx);
882d14abf15SRobert Mustacchi
883d14abf15SRobert Mustacchi return 0;
884d14abf15SRobert Mustacchi }
885d14abf15SRobert Mustacchi
886d14abf15SRobert Mustacchi /* check if this address already exists in the table */
887d14abf15SRobert Mustacchi pTmp = (struct ecore_mcast_list_elem *)d_list_peek_head(mcastList);
888d14abf15SRobert Mustacchi while (pTmp)
889d14abf15SRobert Mustacchi {
890d14abf15SRobert Mustacchi if (IS_ETH_ADDRESS_EQUAL(pMcastAddr, pTmp->mac))
891d14abf15SRobert Mustacchi {
892d14abf15SRobert Mustacchi break;
893d14abf15SRobert Mustacchi }
894d14abf15SRobert Mustacchi
895d14abf15SRobert Mustacchi pTmp = (struct ecore_mcast_list_elem *)d_list_next_entry(D_LINK_CAST(pTmp));
896d14abf15SRobert Mustacchi }
897d14abf15SRobert Mustacchi
898d14abf15SRobert Mustacchi if (flag)
899d14abf15SRobert Mustacchi {
900d14abf15SRobert Mustacchi /* only add the address if the table is empty or address not found */
901d14abf15SRobert Mustacchi if (pTmp == NULL)
902d14abf15SRobert Mustacchi {
903d14abf15SRobert Mustacchi if ((pTmp = kmem_zalloc((sizeof(struct ecore_mcast_list_elem) +
904d14abf15SRobert Mustacchi ETHERNET_ADDRESS_SIZE),
905d14abf15SRobert Mustacchi KM_NOSLEEP)) == NULL)
906d14abf15SRobert Mustacchi {
907d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to alloc Multicast Address node");
908d14abf15SRobert Mustacchi return ENOMEM;
909d14abf15SRobert Mustacchi }
910d14abf15SRobert Mustacchi
911d14abf15SRobert Mustacchi pTmp->mac = (u8_t *)pTmp + sizeof(struct ecore_mcast_list_elem);
912d14abf15SRobert Mustacchi
913d14abf15SRobert Mustacchi COPY_ETH_ADDRESS(pMcastAddr, pTmp->mac);
914d14abf15SRobert Mustacchi
915d14abf15SRobert Mustacchi d_list_push_head(mcastList, D_LINK_CAST(pTmp));
916d14abf15SRobert Mustacchi }
917d14abf15SRobert Mustacchi }
918d14abf15SRobert Mustacchi else /* (!flag) */
919d14abf15SRobert Mustacchi {
920d14abf15SRobert Mustacchi if (pTmp == NULL)
921d14abf15SRobert Mustacchi {
922d14abf15SRobert Mustacchi /* the address isn't in the table */
923d14abf15SRobert Mustacchi return ENXIO;
924d14abf15SRobert Mustacchi }
925d14abf15SRobert Mustacchi
926d14abf15SRobert Mustacchi d_list_remove_entry(mcastList, D_LINK_CAST(pTmp));
927d14abf15SRobert Mustacchi
928d14abf15SRobert Mustacchi kmem_free(pTmp, (sizeof(struct ecore_mcast_list_elem) +
929d14abf15SRobert Mustacchi ETHERNET_ADDRESS_SIZE));
930d14abf15SRobert Mustacchi }
931d14abf15SRobert Mustacchi
932d14abf15SRobert Mustacchi if (!hwSet)
933d14abf15SRobert Mustacchi {
934d14abf15SRobert Mustacchi return 0;
935d14abf15SRobert Mustacchi }
936d14abf15SRobert Mustacchi
937d14abf15SRobert Mustacchi rc = lm_set_mc_list(&pUM->lm_dev, mcastList, NULL, cliIdx);
938d14abf15SRobert Mustacchi
939d14abf15SRobert Mustacchi if (rc == LM_STATUS_PENDING)
940d14abf15SRobert Mustacchi {
941d14abf15SRobert Mustacchi if ((rc = lm_wait_set_mc_done(&pUM->lm_dev, cliIdx)) !=
942d14abf15SRobert Mustacchi LM_STATUS_SUCCESS)
943d14abf15SRobert Mustacchi {
944d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to set Multicast Address table from pending operation (%d)", rc);
945d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_NO_RESPONSE);
946d14abf15SRobert Mustacchi return ENOMEM;
947d14abf15SRobert Mustacchi }
948d14abf15SRobert Mustacchi }
949d14abf15SRobert Mustacchi else if (rc != LM_STATUS_SUCCESS)
950d14abf15SRobert Mustacchi {
951d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to set Multicast Address table (%d)", rc);
952d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
953d14abf15SRobert Mustacchi return ENOMEM;
954d14abf15SRobert Mustacchi }
955d14abf15SRobert Mustacchi
956d14abf15SRobert Mustacchi BnxeMulticastE1(pUM, cliIdx);
957d14abf15SRobert Mustacchi
958d14abf15SRobert Mustacchi return 0;
959d14abf15SRobert Mustacchi }
960d14abf15SRobert Mustacchi
961d14abf15SRobert Mustacchi
962d14abf15SRobert Mustacchi /*
963d14abf15SRobert Mustacchi * This function must be called with BNXE_LOCK_ENTER_HWINIT held because this
964d14abf15SRobert Mustacchi * is shared between GLDv3 and FCoE entry points.
965d14abf15SRobert Mustacchi */
BnxeRxMask(um_device_t * pUM,int cliIdx,lm_rx_mask_t mask)966d14abf15SRobert Mustacchi int BnxeRxMask(um_device_t * pUM,
967d14abf15SRobert Mustacchi int cliIdx,
968d14abf15SRobert Mustacchi lm_rx_mask_t mask)
969d14abf15SRobert Mustacchi {
970d14abf15SRobert Mustacchi int rc;
971d14abf15SRobert Mustacchi
972d14abf15SRobert Mustacchi if ((cliIdx != LM_CLI_IDX_NDIS) && (cliIdx != LM_CLI_IDX_FCOE))
973d14abf15SRobert Mustacchi {
974d14abf15SRobert Mustacchi return EINVAL;
975d14abf15SRobert Mustacchi }
976d14abf15SRobert Mustacchi
977d14abf15SRobert Mustacchi pUM->devParams.rx_filter_mask[cliIdx] = mask;
978d14abf15SRobert Mustacchi
979d14abf15SRobert Mustacchi rc = lm_set_rx_mask(&pUM->lm_dev,
980d14abf15SRobert Mustacchi LM_CLI_CID(&pUM->lm_dev, cliIdx), mask, NULL);
981d14abf15SRobert Mustacchi
982d14abf15SRobert Mustacchi if (rc == LM_STATUS_PENDING)
983d14abf15SRobert Mustacchi {
984d14abf15SRobert Mustacchi if ((rc =
985d14abf15SRobert Mustacchi lm_wait_set_rx_mask_done(&pUM->lm_dev,
986d14abf15SRobert Mustacchi LM_CLI_CID(&pUM->lm_dev, cliIdx))) !=
987d14abf15SRobert Mustacchi LM_STATUS_SUCCESS)
988d14abf15SRobert Mustacchi {
989d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to set Rx mask from pending operation (%d)", rc);
990d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_NO_RESPONSE);
991d14abf15SRobert Mustacchi return ENOMEM;
992d14abf15SRobert Mustacchi }
993d14abf15SRobert Mustacchi }
994d14abf15SRobert Mustacchi
995d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
996d14abf15SRobert Mustacchi BnxeCheckAccHandle(pUM->lm_dev.vars.reg_handle[BAR_0]) != DDI_FM_OK)
997d14abf15SRobert Mustacchi {
998d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "DMA fault when setting Rx mask");
999d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_LOST);
1000d14abf15SRobert Mustacchi return ENOMEM;
1001d14abf15SRobert Mustacchi }
1002d14abf15SRobert Mustacchi
1003d14abf15SRobert Mustacchi if (rc != LM_STATUS_SUCCESS)
1004d14abf15SRobert Mustacchi {
1005d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to set Rx mask (%d)", rc);
1006d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
1007d14abf15SRobert Mustacchi return ENOMEM;
1008d14abf15SRobert Mustacchi }
1009d14abf15SRobert Mustacchi
1010d14abf15SRobert Mustacchi return 0;
1011d14abf15SRobert Mustacchi }
1012d14abf15SRobert Mustacchi
1013d14abf15SRobert Mustacchi
BnxeEstablishHwConn(um_device_t * pUM,int cid)1014d14abf15SRobert Mustacchi boolean_t BnxeEstablishHwConn(um_device_t * pUM,
1015d14abf15SRobert Mustacchi int cid)
1016d14abf15SRobert Mustacchi {
1017d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
1018d14abf15SRobert Mustacchi lm_client_con_params_t cliParams;
1019d14abf15SRobert Mustacchi int sb_id;
1020d14abf15SRobert Mustacchi int rc;
1021d14abf15SRobert Mustacchi
1022d14abf15SRobert Mustacchi sb_id = lm_sb_id_from_chain(&pUM->lm_dev, cid);
1023d14abf15SRobert Mustacchi
1024d14abf15SRobert Mustacchi memset(&cliParams, 0, sizeof(cliParams));
1025d14abf15SRobert Mustacchi cliParams.mtu = pUM->devParams.mtu[LM_CHAIN_IDX_CLI(pLM, cid)];
1026d14abf15SRobert Mustacchi //cliParams.lah_size = pUM->devParams.mtu[LM_CHAIN_IDX_CLI(pLM, cid)];
1027d14abf15SRobert Mustacchi cliParams.lah_size = 0;
1028d14abf15SRobert Mustacchi cliParams.num_rx_desc = pUM->devParams.numRxDesc[LM_CHAIN_IDX_CLI(pLM, cid)];
1029d14abf15SRobert Mustacchi cliParams.num_tx_desc = pUM->devParams.numTxDesc[LM_CHAIN_IDX_CLI(pLM, cid)];
1030d14abf15SRobert Mustacchi cliParams.attributes = (LM_CLIENT_ATTRIBUTES_RX |
1031d14abf15SRobert Mustacchi LM_CLIENT_ATTRIBUTES_TX |
1032d14abf15SRobert Mustacchi LM_CLIENT_ATTRIBUTES_REG_CLI);
1033d14abf15SRobert Mustacchi
1034d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Setting up client for cid %d", cid);
1035d14abf15SRobert Mustacchi if (lm_setup_client_con_params(pLM, cid, &cliParams) != LM_STATUS_SUCCESS)
1036d14abf15SRobert Mustacchi {
1037d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to setup client for cid %d", cid);
1038d14abf15SRobert Mustacchi return B_FALSE;
1039d14abf15SRobert Mustacchi }
1040d14abf15SRobert Mustacchi
1041d14abf15SRobert Mustacchi /*********************************************************/
1042d14abf15SRobert Mustacchi
1043d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Initializing client for cid %d", cid);
1044d14abf15SRobert Mustacchi rc = lm_init_chain_con(pLM, cid, TRUE);
1045d14abf15SRobert Mustacchi
1046d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1047d14abf15SRobert Mustacchi BnxeCheckAccHandle(pUM->pPciCfg) != DDI_FM_OK)
1048d14abf15SRobert Mustacchi {
1049d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_LOST);
1050d14abf15SRobert Mustacchi return B_FALSE;
1051d14abf15SRobert Mustacchi }
1052d14abf15SRobert Mustacchi
1053d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1054d14abf15SRobert Mustacchi BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
1055d14abf15SRobert Mustacchi {
1056d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_LOST);
1057d14abf15SRobert Mustacchi return B_FALSE;
1058d14abf15SRobert Mustacchi }
1059d14abf15SRobert Mustacchi
1060d14abf15SRobert Mustacchi if (rc != LM_STATUS_SUCCESS)
1061d14abf15SRobert Mustacchi {
1062d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to initialize client for cid %d", cid);
1063d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
1064d14abf15SRobert Mustacchi return B_FALSE;
1065d14abf15SRobert Mustacchi }
1066d14abf15SRobert Mustacchi
1067d14abf15SRobert Mustacchi /*********************************************************/
1068d14abf15SRobert Mustacchi
1069d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Establishing client for cid %d", cid);
1070d14abf15SRobert Mustacchi rc = lm_establish_eth_con(pLM, cid, sb_id,
1071d14abf15SRobert Mustacchi pLM->params.l2_cli_con_params[cid].attributes);
1072d14abf15SRobert Mustacchi
1073d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1074d14abf15SRobert Mustacchi BnxeCheckAccHandle(pUM->pPciCfg) != DDI_FM_OK)
1075d14abf15SRobert Mustacchi {
1076d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_LOST);
1077d14abf15SRobert Mustacchi return B_FALSE;
1078d14abf15SRobert Mustacchi }
1079d14abf15SRobert Mustacchi
1080d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1081d14abf15SRobert Mustacchi BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
1082d14abf15SRobert Mustacchi {
1083d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_LOST);
1084d14abf15SRobert Mustacchi return B_FALSE;
1085d14abf15SRobert Mustacchi }
1086d14abf15SRobert Mustacchi
1087d14abf15SRobert Mustacchi if (rc != LM_STATUS_SUCCESS)
1088d14abf15SRobert Mustacchi {
1089d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to establish client connection");
1090d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
1091d14abf15SRobert Mustacchi return B_FALSE;
1092d14abf15SRobert Mustacchi }
1093d14abf15SRobert Mustacchi
1094d14abf15SRobert Mustacchi return B_TRUE;
1095d14abf15SRobert Mustacchi }
1096d14abf15SRobert Mustacchi
1097d14abf15SRobert Mustacchi
BnxeHwStartFCOE(um_device_t * pUM)1098d14abf15SRobert Mustacchi int BnxeHwStartFCOE(um_device_t * pUM)
1099d14abf15SRobert Mustacchi {
1100d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
1101d14abf15SRobert Mustacchi int rc;
1102d14abf15SRobert Mustacchi
1103d14abf15SRobert Mustacchi if (!BNXE_FCOE(pUM))
1104d14abf15SRobert Mustacchi {
1105d14abf15SRobert Mustacchi BnxeDbgBreakMsg(pUM, "Inside BnxeHwStartFCOE and FCoE not supported!");
1106d14abf15SRobert Mustacchi return -1;
1107d14abf15SRobert Mustacchi }
1108d14abf15SRobert Mustacchi
1109d14abf15SRobert Mustacchi BNXE_LOCK_ENTER_HWINIT(pUM);
1110d14abf15SRobert Mustacchi
1111d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStartFCOE: Starting FCoE (clients %s)",
1112d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1113d14abf15SRobert Mustacchi
1114d14abf15SRobert Mustacchi if (BnxeHwStartCore(pUM))
1115d14abf15SRobert Mustacchi {
1116d14abf15SRobert Mustacchi goto BnxeHwStartFCOE_error;
1117d14abf15SRobert Mustacchi }
1118d14abf15SRobert Mustacchi
1119d14abf15SRobert Mustacchi if (!pUM->hwInitDone)
1120d14abf15SRobert Mustacchi {
1121d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "BnxeHwStartFCOE: Failed, hardware not initialized (clients %s)",
1122d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1123d14abf15SRobert Mustacchi goto BnxeHwStartFCOE_error;
1124d14abf15SRobert Mustacchi }
1125d14abf15SRobert Mustacchi
1126d14abf15SRobert Mustacchi /*********************************************************/
1127d14abf15SRobert Mustacchi
1128d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Allocating FCoE Resources");
1129d14abf15SRobert Mustacchi
1130d14abf15SRobert Mustacchi if (lm_fc_alloc_resc(&pUM->lm_dev) != LM_STATUS_SUCCESS)
1131d14abf15SRobert Mustacchi {
1132d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate FCoE resources");
1133d14abf15SRobert Mustacchi goto BnxeHwStartFCOE_error;
1134d14abf15SRobert Mustacchi }
1135d14abf15SRobert Mustacchi
1136d14abf15SRobert Mustacchi /*********************************************************/
1137d14abf15SRobert Mustacchi
1138d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Opening FCoE Ethernet Connection");
1139d14abf15SRobert Mustacchi
1140d14abf15SRobert Mustacchi pUM->lm_dev.ofld_info.state_blks[STATE_BLOCK_FCOE] =
1141d14abf15SRobert Mustacchi &pUM->lm_dev.fcoe_info.run_time.state_blk;
1142d14abf15SRobert Mustacchi
1143d14abf15SRobert Mustacchi if (!BnxeEstablishHwConn(pUM, FCOE_CID(pLM)))
1144d14abf15SRobert Mustacchi {
1145d14abf15SRobert Mustacchi goto BnxeHwStartFCOE_error;
1146d14abf15SRobert Mustacchi }
1147d14abf15SRobert Mustacchi
1148d14abf15SRobert Mustacchi /*********************************************************/
1149d14abf15SRobert Mustacchi
1150d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Initializing FCoE Tx Pkts");
1151d14abf15SRobert Mustacchi
1152d14abf15SRobert Mustacchi if (BnxeTxPktsInit(pUM, LM_CLI_IDX_FCOE))
1153d14abf15SRobert Mustacchi {
1154d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate FCoE Tx resources");
1155d14abf15SRobert Mustacchi goto BnxeHwStartFCOE_error;
1156d14abf15SRobert Mustacchi }
1157d14abf15SRobert Mustacchi
1158d14abf15SRobert Mustacchi /*********************************************************/
1159d14abf15SRobert Mustacchi
1160d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Initializing FCoE Rx Pkts");
1161d14abf15SRobert Mustacchi
1162d14abf15SRobert Mustacchi if (BnxeRxPktsInit(pUM, LM_CLI_IDX_FCOE))
1163d14abf15SRobert Mustacchi {
1164d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate FCoE Rx resources");
1165d14abf15SRobert Mustacchi goto BnxeHwStartFCOE_error;
1166d14abf15SRobert Mustacchi }
1167d14abf15SRobert Mustacchi
1168d14abf15SRobert Mustacchi if (BnxeRxPktsInitPostBuffers(pUM, LM_CLI_IDX_FCOE))
1169d14abf15SRobert Mustacchi {
1170d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to post FCoE Rx buffers");
1171d14abf15SRobert Mustacchi goto BnxeHwStartFCOE_error;
1172d14abf15SRobert Mustacchi }
1173d14abf15SRobert Mustacchi
1174d14abf15SRobert Mustacchi /*********************************************************/
1175d14abf15SRobert Mustacchi
1176d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Setting FCoE MAC Address");
1177d14abf15SRobert Mustacchi
1178d14abf15SRobert Mustacchi if (BnxeMacAddress(pUM, LM_CLI_IDX_FCOE, B_TRUE,
1179d14abf15SRobert Mustacchi pLM->hw_info.fcoe_mac_addr) < 0)
1180d14abf15SRobert Mustacchi {
1181d14abf15SRobert Mustacchi goto BnxeHwStartFCOE_error;
1182d14abf15SRobert Mustacchi }
1183d14abf15SRobert Mustacchi
1184d14abf15SRobert Mustacchi /*********************************************************/
1185d14abf15SRobert Mustacchi
1186d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Setting FCoE Multicast Addresses");
1187d14abf15SRobert Mustacchi
1188d14abf15SRobert Mustacchi #define ALL_FCOE_MACS (const uint8_t *)"\x01\x10\x18\x01\x00\x00"
1189d14abf15SRobert Mustacchi #define ALL_ENODE_MACS (const uint8_t *)"\x01\x10\x18\x01\x00\x01"
1190d14abf15SRobert Mustacchi
1191d14abf15SRobert Mustacchi if ((BnxeMulticast(pUM, LM_CLI_IDX_FCOE, B_TRUE, ALL_FCOE_MACS, B_FALSE) < 0) ||
1192d14abf15SRobert Mustacchi (BnxeMulticast(pUM, LM_CLI_IDX_FCOE, B_TRUE, ALL_ENODE_MACS, B_TRUE) < 0))
1193d14abf15SRobert Mustacchi {
1194d14abf15SRobert Mustacchi goto BnxeHwStartFCOE_error;
1195d14abf15SRobert Mustacchi }
1196d14abf15SRobert Mustacchi
1197d14abf15SRobert Mustacchi /*********************************************************/
1198d14abf15SRobert Mustacchi
1199d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Turning on FCoE Rx Mask");
1200d14abf15SRobert Mustacchi
1201d14abf15SRobert Mustacchi if (BnxeRxMask(pUM, LM_CLI_IDX_FCOE, (
1202d14abf15SRobert Mustacchi LM_RX_MASK_ACCEPT_UNICAST
1203d14abf15SRobert Mustacchi //| LM_RX_MASK_ACCEPT_ALL_MULTICAST
1204d14abf15SRobert Mustacchi | LM_RX_MASK_ACCEPT_MULTICAST
1205d14abf15SRobert Mustacchi //| LM_RX_MASK_ACCEPT_BROADCAST
1206d14abf15SRobert Mustacchi //| LM_RX_MASK_PROMISCUOUS_MODE
1207d14abf15SRobert Mustacchi )) < 0)
1208d14abf15SRobert Mustacchi {
1209d14abf15SRobert Mustacchi goto BnxeHwStartFCOE_error;
1210d14abf15SRobert Mustacchi }
1211d14abf15SRobert Mustacchi
1212d14abf15SRobert Mustacchi /*********************************************************/
1213d14abf15SRobert Mustacchi
1214d14abf15SRobert Mustacchi CLIENT_HW_SET(pUM, LM_CLI_IDX_FCOE);
1215d14abf15SRobert Mustacchi
1216d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStartFCOE: FCoE started (clients %s)",
1217d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1218d14abf15SRobert Mustacchi
1219d14abf15SRobert Mustacchi BNXE_LOCK_EXIT_HWINIT(pUM);
1220d14abf15SRobert Mustacchi return 0;
1221d14abf15SRobert Mustacchi
1222d14abf15SRobert Mustacchi BnxeHwStartFCOE_error:
1223d14abf15SRobert Mustacchi
1224d14abf15SRobert Mustacchi BNXE_LOCK_EXIT_HWINIT(pUM);
1225d14abf15SRobert Mustacchi return -1;
1226d14abf15SRobert Mustacchi }
1227d14abf15SRobert Mustacchi
1228d14abf15SRobert Mustacchi
BnxeHwStartL2(um_device_t * pUM)1229d14abf15SRobert Mustacchi int BnxeHwStartL2(um_device_t * pUM)
1230d14abf15SRobert Mustacchi {
1231d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
1232d14abf15SRobert Mustacchi int idx, rc;
1233d14abf15SRobert Mustacchi
1234d14abf15SRobert Mustacchi BNXE_LOCK_ENTER_HWINIT(pUM);
1235d14abf15SRobert Mustacchi
1236d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStartL2: Starting L2 (clients %s)",
1237d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1238d14abf15SRobert Mustacchi
1239d14abf15SRobert Mustacchi if (BnxeHwStartCore(pUM))
1240d14abf15SRobert Mustacchi {
1241d14abf15SRobert Mustacchi goto BnxeHwStartL2_error;
1242d14abf15SRobert Mustacchi }
1243d14abf15SRobert Mustacchi
1244d14abf15SRobert Mustacchi if (!pUM->hwInitDone)
1245d14abf15SRobert Mustacchi {
1246d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "BnxeHwStartL2: Failed, hardware not initialized (clients %s)",
1247d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1248d14abf15SRobert Mustacchi goto BnxeHwStartL2_error;
1249d14abf15SRobert Mustacchi }
1250d14abf15SRobert Mustacchi
1251d14abf15SRobert Mustacchi /*********************************************************/
1252d14abf15SRobert Mustacchi
1253d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Opening L2 Ethernet Connections (%d)",
1254d14abf15SRobert Mustacchi pLM->params.rss_chain_cnt);
1255d14abf15SRobert Mustacchi
1256d14abf15SRobert Mustacchi LM_FOREACH_RSS_IDX(pLM, idx)
1257d14abf15SRobert Mustacchi {
1258d14abf15SRobert Mustacchi if (!BnxeEstablishHwConn(pUM, idx))
1259d14abf15SRobert Mustacchi {
1260d14abf15SRobert Mustacchi goto BnxeHwStartL2_error;
1261d14abf15SRobert Mustacchi }
1262d14abf15SRobert Mustacchi }
1263d14abf15SRobert Mustacchi
1264d14abf15SRobert Mustacchi /*********************************************************/
1265d14abf15SRobert Mustacchi
1266d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Initializing Tx Pkts");
1267d14abf15SRobert Mustacchi
1268d14abf15SRobert Mustacchi if (BnxeTxPktsInit(pUM, LM_CLI_IDX_NDIS))
1269d14abf15SRobert Mustacchi {
1270d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate tx resources");
1271d14abf15SRobert Mustacchi goto BnxeHwStartL2_error;
1272d14abf15SRobert Mustacchi }
1273d14abf15SRobert Mustacchi
1274d14abf15SRobert Mustacchi /*********************************************************/
1275d14abf15SRobert Mustacchi
1276d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Initializing Rx Pkts");
1277d14abf15SRobert Mustacchi
1278d14abf15SRobert Mustacchi if (BnxeRxPktsInit(pUM, LM_CLI_IDX_NDIS))
1279d14abf15SRobert Mustacchi {
1280d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate L2 Rx resources");
1281d14abf15SRobert Mustacchi goto BnxeHwStartL2_error;
1282d14abf15SRobert Mustacchi }
1283d14abf15SRobert Mustacchi
1284d14abf15SRobert Mustacchi if (BnxeRxPktsInitPostBuffers(pUM, LM_CLI_IDX_NDIS))
1285d14abf15SRobert Mustacchi {
1286d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to post L2 Rx buffers");
1287d14abf15SRobert Mustacchi goto BnxeHwStartL2_error;
1288d14abf15SRobert Mustacchi }
1289d14abf15SRobert Mustacchi
1290d14abf15SRobert Mustacchi /*********************************************************/
1291d14abf15SRobert Mustacchi
1292d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Enabling RSS");
1293d14abf15SRobert Mustacchi
1294d14abf15SRobert Mustacchi if (!BnxeRssEnable(pUM))
1295d14abf15SRobert Mustacchi {
1296d14abf15SRobert Mustacchi goto BnxeHwStartL2_error;
1297d14abf15SRobert Mustacchi }
1298d14abf15SRobert Mustacchi
1299d14abf15SRobert Mustacchi /*********************************************************/
1300d14abf15SRobert Mustacchi
1301d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Setting L2 MAC Address");
1302d14abf15SRobert Mustacchi
1303*8993acd7SToomas Soome /* use the hw programmed address (GLDv3 will overwrite if needed) */
1304d14abf15SRobert Mustacchi
1305d14abf15SRobert Mustacchi {
1306d14abf15SRobert Mustacchi u8_t zero_mac_addr[ETHERNET_ADDRESS_SIZE];
1307d14abf15SRobert Mustacchi memset(zero_mac_addr, 0, ETHERNET_ADDRESS_SIZE);
1308d14abf15SRobert Mustacchi
1309d14abf15SRobert Mustacchi if (IS_ETH_ADDRESS_EQUAL(pUM->gldMac, zero_mac_addr))
1310d14abf15SRobert Mustacchi {
1311d14abf15SRobert Mustacchi COPY_ETH_ADDRESS(pUM->lm_dev.hw_info.mac_addr,
1312d14abf15SRobert Mustacchi pUM->lm_dev.params.mac_addr);
1313d14abf15SRobert Mustacchi }
1314d14abf15SRobert Mustacchi else
1315d14abf15SRobert Mustacchi {
1316d14abf15SRobert Mustacchi COPY_ETH_ADDRESS(pUM->gldMac,
1317d14abf15SRobert Mustacchi pUM->lm_dev.params.mac_addr);
1318d14abf15SRobert Mustacchi }
1319d14abf15SRobert Mustacchi }
1320d14abf15SRobert Mustacchi
1321d14abf15SRobert Mustacchi if (BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_TRUE,
1322d14abf15SRobert Mustacchi pUM->lm_dev.params.mac_addr) < 0)
1323d14abf15SRobert Mustacchi {
1324d14abf15SRobert Mustacchi goto BnxeHwStartL2_error;
1325d14abf15SRobert Mustacchi }
1326d14abf15SRobert Mustacchi
1327d14abf15SRobert Mustacchi /*********************************************************/
1328d14abf15SRobert Mustacchi
1329d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Turning on L2 Rx Mask");
1330d14abf15SRobert Mustacchi
1331d14abf15SRobert Mustacchi if (BnxeRxMask(pUM, LM_CLI_IDX_NDIS, (
1332d14abf15SRobert Mustacchi LM_RX_MASK_ACCEPT_UNICAST
1333d14abf15SRobert Mustacchi //| LM_RX_MASK_ACCEPT_ALL_MULTICAST
1334d14abf15SRobert Mustacchi | LM_RX_MASK_ACCEPT_MULTICAST
1335d14abf15SRobert Mustacchi | LM_RX_MASK_ACCEPT_BROADCAST
1336d14abf15SRobert Mustacchi //| LM_RX_MASK_PROMISCUOUS_MODE
1337d14abf15SRobert Mustacchi )) < 0)
1338d14abf15SRobert Mustacchi {
1339d14abf15SRobert Mustacchi goto BnxeHwStartL2_error;
1340d14abf15SRobert Mustacchi }
1341d14abf15SRobert Mustacchi
1342d14abf15SRobert Mustacchi /*********************************************************/
1343d14abf15SRobert Mustacchi
1344d14abf15SRobert Mustacchi CLIENT_HW_SET(pUM, LM_CLI_IDX_NDIS);
1345d14abf15SRobert Mustacchi lm_mcp_indicate_client_bind(&pUM->lm_dev, LM_CLI_IDX_NDIS);
1346d14abf15SRobert Mustacchi
1347d14abf15SRobert Mustacchi BNXE_LOCK_EXIT_HWINIT(pUM);
1348d14abf15SRobert Mustacchi
1349d14abf15SRobert Mustacchi /*********************************************************/
1350d14abf15SRobert Mustacchi
1351d14abf15SRobert Mustacchi /*
1352d14abf15SRobert Mustacchi * Force a link update. Another client might already be up in which case
1353d14abf15SRobert Mustacchi * the link status won't change during this plumb of the L2 client.
1354d14abf15SRobert Mustacchi */
1355d14abf15SRobert Mustacchi BnxeGldLink(pUM, (pUM->devParams.lastIndLink == LM_STATUS_LINK_ACTIVE) ?
1356d14abf15SRobert Mustacchi LINK_STATE_UP : LINK_STATE_DOWN);
1357d14abf15SRobert Mustacchi
1358d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStartL2: L2 started (clients %s)",
1359d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1360d14abf15SRobert Mustacchi
1361d14abf15SRobert Mustacchi return 0;
1362d14abf15SRobert Mustacchi
1363d14abf15SRobert Mustacchi BnxeHwStartL2_error:
1364d14abf15SRobert Mustacchi
1365d14abf15SRobert Mustacchi /* XXX Need cleanup! */
1366d14abf15SRobert Mustacchi
1367d14abf15SRobert Mustacchi BNXE_LOCK_EXIT_HWINIT(pUM);
1368d14abf15SRobert Mustacchi return -1;
1369d14abf15SRobert Mustacchi }
1370d14abf15SRobert Mustacchi
1371d14abf15SRobert Mustacchi
1372d14abf15SRobert Mustacchi /* Must be called with BNXE_LOCK_ENTER_HWINIT taken! */
BnxeHwStartCore(um_device_t * pUM)1373d14abf15SRobert Mustacchi int BnxeHwStartCore(um_device_t * pUM)
1374d14abf15SRobert Mustacchi {
1375d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
1376d14abf15SRobert Mustacchi int rc;
1377d14abf15SRobert Mustacchi
1378d14abf15SRobert Mustacchi if (pUM->hwInitDone)
1379d14abf15SRobert Mustacchi {
1380d14abf15SRobert Mustacchi /* already initialized */
1381d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStartCore: Hardware already initialized (clients %s)",
1382d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1383d14abf15SRobert Mustacchi return 0;
1384d14abf15SRobert Mustacchi }
1385d14abf15SRobert Mustacchi
1386d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStartCore: Starting hardware (clients %s)",
1387d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1388d14abf15SRobert Mustacchi
1389d14abf15SRobert Mustacchi memset(&pLM->debug_info, 0, sizeof(pLM->debug_info));
1390d14abf15SRobert Mustacchi
1391d14abf15SRobert Mustacchi /*********************************************************/
1392d14abf15SRobert Mustacchi
1393d14abf15SRobert Mustacchi /* reset the configuration to the hardware default */
1394d14abf15SRobert Mustacchi BnxeCfgReset(pUM);
1395d14abf15SRobert Mustacchi
1396d14abf15SRobert Mustacchi pUM->phyInitialized = B_FALSE;
1397d14abf15SRobert Mustacchi
1398d14abf15SRobert Mustacchi /*********************************************************/
1399d14abf15SRobert Mustacchi
1400d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Allocating LM Resources");
1401d14abf15SRobert Mustacchi
1402d14abf15SRobert Mustacchi if (lm_alloc_resc(pLM) != LM_STATUS_SUCCESS)
1403d14abf15SRobert Mustacchi {
1404d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate resources");
1405d14abf15SRobert Mustacchi goto BnxeHwStartCore_error;
1406d14abf15SRobert Mustacchi }
1407d14abf15SRobert Mustacchi
1408d14abf15SRobert Mustacchi /*********************************************************/
1409d14abf15SRobert Mustacchi
1410d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Initializing BRCM Chip");
1411d14abf15SRobert Mustacchi
1412d14abf15SRobert Mustacchi rc = lm_chip_init(pLM);
1413d14abf15SRobert Mustacchi
1414d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1415d14abf15SRobert Mustacchi BnxeCheckAccHandle(pUM->pPciCfg) != DDI_FM_OK)
1416d14abf15SRobert Mustacchi {
1417d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_LOST);
1418d14abf15SRobert Mustacchi goto BnxeHwStartCore_error;
1419d14abf15SRobert Mustacchi }
1420d14abf15SRobert Mustacchi
1421d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1422d14abf15SRobert Mustacchi BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
1423d14abf15SRobert Mustacchi {
1424d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_LOST);
1425d14abf15SRobert Mustacchi goto BnxeHwStartCore_error;
1426d14abf15SRobert Mustacchi }
1427d14abf15SRobert Mustacchi
1428d14abf15SRobert Mustacchi if (rc != LM_STATUS_SUCCESS)
1429d14abf15SRobert Mustacchi {
1430d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to initialize chip");
1431d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
1432d14abf15SRobert Mustacchi goto BnxeHwStartCore_error;
1433d14abf15SRobert Mustacchi }
1434d14abf15SRobert Mustacchi
1435d14abf15SRobert Mustacchi /*********************************************************/
1436d14abf15SRobert Mustacchi
1437d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Enabling Interrupts");
1438d14abf15SRobert Mustacchi
1439d14abf15SRobert Mustacchi if (BnxeIntrEnable(pUM))
1440d14abf15SRobert Mustacchi {
1441d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to enable interrupts");
1442d14abf15SRobert Mustacchi goto BnxeHwStartCore_error;
1443d14abf15SRobert Mustacchi }
1444d14abf15SRobert Mustacchi
1445d14abf15SRobert Mustacchi /*********************************************************/
1446d14abf15SRobert Mustacchi
1447d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Starting BRCM Chip");
1448d14abf15SRobert Mustacchi
1449d14abf15SRobert Mustacchi rc = lm_chip_start(pLM);
1450d14abf15SRobert Mustacchi
1451d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1452d14abf15SRobert Mustacchi BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
1453d14abf15SRobert Mustacchi {
1454d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_LOST);
1455d14abf15SRobert Mustacchi goto BnxeHwStartCore_error;
1456d14abf15SRobert Mustacchi }
1457d14abf15SRobert Mustacchi
1458d14abf15SRobert Mustacchi if (rc != LM_STATUS_SUCCESS)
1459d14abf15SRobert Mustacchi {
1460d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to start chip");
1461d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
1462d14abf15SRobert Mustacchi goto BnxeHwStartCore_error;
1463d14abf15SRobert Mustacchi }
1464d14abf15SRobert Mustacchi
1465d14abf15SRobert Mustacchi atomic_swap_32(&pUM->chipStarted, B_TRUE);
1466d14abf15SRobert Mustacchi
1467d14abf15SRobert Mustacchi /*********************************************************/
1468d14abf15SRobert Mustacchi
1469d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Activating pending WorkQ items");
1470d14abf15SRobert Mustacchi
1471d14abf15SRobert Mustacchi BnxeWorkQueueStartPending(pUM);
1472d14abf15SRobert Mustacchi
1473d14abf15SRobert Mustacchi /*********************************************************/
1474d14abf15SRobert Mustacchi
1475d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Initializing DCBX");
1476d14abf15SRobert Mustacchi
1477d14abf15SRobert Mustacchi lm_dcbx_init(pLM, B_FALSE); /* B_TRUE for hibernate */
1478d14abf15SRobert Mustacchi
1479d14abf15SRobert Mustacchi /*********************************************************/
1480d14abf15SRobert Mustacchi
1481d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Initializing Phy");
1482d14abf15SRobert Mustacchi
1483d14abf15SRobert Mustacchi BnxeUpdatePhy(pUM);
1484d14abf15SRobert Mustacchi
1485d14abf15SRobert Mustacchi /*********************************************************/
1486d14abf15SRobert Mustacchi
1487d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Starting Timer");
1488d14abf15SRobert Mustacchi
1489d14abf15SRobert Mustacchi BnxeTimerStart(pUM);
1490d14abf15SRobert Mustacchi
1491d14abf15SRobert Mustacchi /*********************************************************/
1492d14abf15SRobert Mustacchi
1493d14abf15SRobert Mustacchi atomic_swap_32(&pUM->hwInitDone, B_TRUE);
1494d14abf15SRobert Mustacchi
1495d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStartCore: Hardware started (clients %s)",
1496d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1497d14abf15SRobert Mustacchi
1498d14abf15SRobert Mustacchi return 0;
1499d14abf15SRobert Mustacchi
1500d14abf15SRobert Mustacchi BnxeHwStartCore_error:
1501d14abf15SRobert Mustacchi
1502d14abf15SRobert Mustacchi return -1;
1503d14abf15SRobert Mustacchi }
1504d14abf15SRobert Mustacchi
1505d14abf15SRobert Mustacchi
BnxeHwStopFCOE(um_device_t * pUM)1506d14abf15SRobert Mustacchi void BnxeHwStopFCOE(um_device_t * pUM)
1507d14abf15SRobert Mustacchi {
1508d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
1509d14abf15SRobert Mustacchi int rc;
1510d14abf15SRobert Mustacchi
1511d14abf15SRobert Mustacchi if (!BNXE_FCOE(pUM))
1512d14abf15SRobert Mustacchi {
1513d14abf15SRobert Mustacchi BnxeDbgBreakMsg(pUM, "Inside BnxeHwStopFCOE and FCoE not supported!");
1514d14abf15SRobert Mustacchi return;
1515d14abf15SRobert Mustacchi }
1516d14abf15SRobert Mustacchi
1517d14abf15SRobert Mustacchi BNXE_LOCK_ENTER_HWINIT(pUM);
1518d14abf15SRobert Mustacchi
1519d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStopFCOE: Stopping FCoE (clients %s)",
1520d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1521d14abf15SRobert Mustacchi
1522d14abf15SRobert Mustacchi CLIENT_HW_RESET(pUM, LM_CLI_IDX_FCOE);
1523d14abf15SRobert Mustacchi
1524d14abf15SRobert Mustacchi /*********************************************************/
1525d14abf15SRobert Mustacchi
1526d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Turning off FCoE RX Mask");
1527d14abf15SRobert Mustacchi
1528d14abf15SRobert Mustacchi BnxeRxMask(pUM, LM_CLI_IDX_FCOE, LM_RX_MASK_ACCEPT_NONE);
1529d14abf15SRobert Mustacchi
1530d14abf15SRobert Mustacchi /*********************************************************/
1531d14abf15SRobert Mustacchi
1532d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Clearing the FCoE Multicast Table");
1533d14abf15SRobert Mustacchi
1534d14abf15SRobert Mustacchi BnxeMulticast(pUM, LM_CLI_IDX_FCOE, B_FALSE, NULL, B_TRUE);
1535d14abf15SRobert Mustacchi
1536d14abf15SRobert Mustacchi /*********************************************************/
1537d14abf15SRobert Mustacchi
1538d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Closing FCoE Connection");
1539d14abf15SRobert Mustacchi
1540d14abf15SRobert Mustacchi if ((rc = lm_close_eth_con(pLM, FCOE_CID(pLM), B_TRUE)) !=
1541d14abf15SRobert Mustacchi LM_STATUS_SUCCESS)
1542d14abf15SRobert Mustacchi {
1543d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to close FCoE conn %d (%d)",
1544d14abf15SRobert Mustacchi FCOE_CID(pLM), rc);
1545d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
1546d14abf15SRobert Mustacchi }
1547d14abf15SRobert Mustacchi
1548d14abf15SRobert Mustacchi /*********************************************************/
1549d14abf15SRobert Mustacchi
1550d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Aborting FCoE TX Chains");
1551d14abf15SRobert Mustacchi
1552d14abf15SRobert Mustacchi BnxeTxPktsAbort(pUM, LM_CLI_IDX_FCOE);
1553d14abf15SRobert Mustacchi
1554d14abf15SRobert Mustacchi /*********************************************************/
1555d14abf15SRobert Mustacchi
1556d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Aborting FCoE RX Chains");
1557d14abf15SRobert Mustacchi
1558d14abf15SRobert Mustacchi BnxeRxPktsAbort(pUM, LM_CLI_IDX_FCOE);
1559d14abf15SRobert Mustacchi
1560d14abf15SRobert Mustacchi /*********************************************************/
1561d14abf15SRobert Mustacchi
1562d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Cleaning up FCoE Tx Pkts");
1563d14abf15SRobert Mustacchi
1564d14abf15SRobert Mustacchi BnxeTxPktsFini(pUM, LM_CLI_IDX_FCOE);
1565d14abf15SRobert Mustacchi
1566d14abf15SRobert Mustacchi /*********************************************************/
1567d14abf15SRobert Mustacchi
1568d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Cleaning up FCoE Rx Pkts");
1569d14abf15SRobert Mustacchi
1570d14abf15SRobert Mustacchi BnxeRxPktsFini(pUM, LM_CLI_IDX_FCOE);
1571d14abf15SRobert Mustacchi
1572d14abf15SRobert Mustacchi /*********************************************************/
1573d14abf15SRobert Mustacchi
1574d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Clearing FCoE Resources");
1575d14abf15SRobert Mustacchi
1576d14abf15SRobert Mustacchi if ((rc = lm_fc_clear_resc(pLM)) != LM_STATUS_SUCCESS)
1577d14abf15SRobert Mustacchi {
1578d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to clear FCoE resources (%d)\n", rc);
1579d14abf15SRobert Mustacchi }
1580d14abf15SRobert Mustacchi
1581d14abf15SRobert Mustacchi lm_cid_recycled_cb_deregister(pLM, FCOE_CONNECTION_TYPE);
1582d14abf15SRobert Mustacchi
1583d14abf15SRobert Mustacchi /*********************************************************/
1584d14abf15SRobert Mustacchi
1585d14abf15SRobert Mustacchi BnxeHwStopCore(pUM);
1586d14abf15SRobert Mustacchi
1587d14abf15SRobert Mustacchi /*********************************************************/
1588d14abf15SRobert Mustacchi
1589d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStopFCOE: FCoE stopped (clients %s)",
1590d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1591d14abf15SRobert Mustacchi
1592d14abf15SRobert Mustacchi BNXE_LOCK_EXIT_HWINIT(pUM);
1593d14abf15SRobert Mustacchi }
1594d14abf15SRobert Mustacchi
1595d14abf15SRobert Mustacchi
BnxeHwStopL2(um_device_t * pUM)1596d14abf15SRobert Mustacchi void BnxeHwStopL2(um_device_t * pUM)
1597d14abf15SRobert Mustacchi {
1598d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
1599d14abf15SRobert Mustacchi int idx, rc;
1600d14abf15SRobert Mustacchi
1601d14abf15SRobert Mustacchi BNXE_LOCK_ENTER_HWINIT(pUM);
1602d14abf15SRobert Mustacchi
1603d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStopL2: Stopping L2 (clients %s)",
1604d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1605d14abf15SRobert Mustacchi
1606d14abf15SRobert Mustacchi lm_mcp_indicate_client_unbind(&pUM->lm_dev, LM_CLI_IDX_NDIS);
1607d14abf15SRobert Mustacchi CLIENT_HW_RESET(pUM, LM_CLI_IDX_NDIS);
1608d14abf15SRobert Mustacchi
1609d14abf15SRobert Mustacchi /*********************************************************/
1610d14abf15SRobert Mustacchi
1611d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Turning off L2 RX Mask");
1612d14abf15SRobert Mustacchi
1613d14abf15SRobert Mustacchi BnxeRxMask(pUM, LM_CLI_IDX_NDIS, LM_RX_MASK_ACCEPT_NONE);
1614d14abf15SRobert Mustacchi
1615d14abf15SRobert Mustacchi /*********************************************************/
1616d14abf15SRobert Mustacchi
1617d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Clearing the L2 MAC Address");
1618d14abf15SRobert Mustacchi
1619d14abf15SRobert Mustacchi /*
1620d14abf15SRobert Mustacchi * Reset the mac_addr to hw programmed default and then clear
1621d14abf15SRobert Mustacchi * it in the firmware.
1622d14abf15SRobert Mustacchi */
1623d14abf15SRobert Mustacchi {
1624d14abf15SRobert Mustacchi u8_t mac_to_delete[ETHERNET_ADDRESS_SIZE];
1625d14abf15SRobert Mustacchi COPY_ETH_ADDRESS(pUM->lm_dev.params.mac_addr,
1626d14abf15SRobert Mustacchi mac_to_delete);
1627d14abf15SRobert Mustacchi
1628d14abf15SRobert Mustacchi COPY_ETH_ADDRESS(pUM->lm_dev.hw_info.mac_addr,
1629d14abf15SRobert Mustacchi pUM->lm_dev.params.mac_addr);
1630d14abf15SRobert Mustacchi memset(pUM->gldMac, 0, ETHERNET_ADDRESS_SIZE);
1631d14abf15SRobert Mustacchi
1632d14abf15SRobert Mustacchi #if 0
1633d14abf15SRobert Mustacchi BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_FALSE, mac_to_delete);
1634d14abf15SRobert Mustacchi #else
1635d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "Removing all MAC addresses");
1636d14abf15SRobert Mustacchi
1637d14abf15SRobert Mustacchi if ((rc = lm_clear_all_mac_addr(pLM,
1638d14abf15SRobert Mustacchi LM_CLI_CID(&pUM->lm_dev,
1639d14abf15SRobert Mustacchi LM_CLI_IDX_NDIS))) !=
1640d14abf15SRobert Mustacchi LM_STATUS_SUCCESS)
1641d14abf15SRobert Mustacchi {
1642d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to delete all MAC addresses (%d)", rc);
1643d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
1644d14abf15SRobert Mustacchi }
1645d14abf15SRobert Mustacchi #endif
1646d14abf15SRobert Mustacchi }
1647d14abf15SRobert Mustacchi
1648d14abf15SRobert Mustacchi /*********************************************************/
1649d14abf15SRobert Mustacchi
1650d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Clearing the L2 Multicast Table");
1651d14abf15SRobert Mustacchi
1652d14abf15SRobert Mustacchi BnxeMulticast(pUM, LM_CLI_IDX_NDIS, B_FALSE, NULL, B_TRUE);
1653d14abf15SRobert Mustacchi
1654d14abf15SRobert Mustacchi /*********************************************************/
1655d14abf15SRobert Mustacchi
1656d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Disabling RSS");
1657d14abf15SRobert Mustacchi
1658d14abf15SRobert Mustacchi BnxeRssDisable(pUM);
1659d14abf15SRobert Mustacchi
1660d14abf15SRobert Mustacchi /*********************************************************/
1661d14abf15SRobert Mustacchi
1662d14abf15SRobert Mustacchi /*
1663d14abf15SRobert Mustacchi * In Solaris when RX traffic is accepted, the system might generate and
1664d14abf15SRobert Mustacchi * attempt to send some TX packets (from within gld_recv()!). Claiming any
1665d14abf15SRobert Mustacchi * TX locks before this point would create a deadlock. The ISR would be
1666d14abf15SRobert Mustacchi * waiting for a lock acquired here that would never be freed, since we
1667d14abf15SRobert Mustacchi * in-turn would be waiting for the ISR to finish here. Consequently, we
1668d14abf15SRobert Mustacchi * acquire the TX lock as soon as we know that no TX traffic is a result of
1669d14abf15SRobert Mustacchi * RX traffic.
1670d14abf15SRobert Mustacchi */
1671d14abf15SRobert Mustacchi BNXE_LOCK_ENTER_GLDTX(pUM, RW_WRITER);
1672d14abf15SRobert Mustacchi
1673d14abf15SRobert Mustacchi /*********************************************************/
1674d14abf15SRobert Mustacchi
1675d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Closing L2 Ethernet Connections (%d)",
1676d14abf15SRobert Mustacchi pLM->params.rss_chain_cnt);
1677d14abf15SRobert Mustacchi
1678d14abf15SRobert Mustacchi LM_FOREACH_RSS_IDX(pLM, idx)
1679d14abf15SRobert Mustacchi {
1680d14abf15SRobert Mustacchi if ((rc = lm_close_eth_con(pLM, idx, B_TRUE)) !=
1681d14abf15SRobert Mustacchi LM_STATUS_SUCCESS)
1682d14abf15SRobert Mustacchi {
1683d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to close Ethernet conn on RSS %d (%d)",
1684d14abf15SRobert Mustacchi idx, rc);
1685d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
1686d14abf15SRobert Mustacchi }
1687d14abf15SRobert Mustacchi }
1688d14abf15SRobert Mustacchi
1689d14abf15SRobert Mustacchi /*********************************************************/
1690d14abf15SRobert Mustacchi
1691d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Aborting L2 Tx Chains");
1692d14abf15SRobert Mustacchi
1693d14abf15SRobert Mustacchi BnxeTxPktsAbort(pUM, LM_CLI_IDX_NDIS);
1694d14abf15SRobert Mustacchi
1695d14abf15SRobert Mustacchi /*********************************************************/
1696d14abf15SRobert Mustacchi
1697d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Aborting L2 Rx Chains");
1698d14abf15SRobert Mustacchi
1699d14abf15SRobert Mustacchi BnxeRxPktsAbort(pUM, LM_CLI_IDX_NDIS);
1700d14abf15SRobert Mustacchi
1701d14abf15SRobert Mustacchi /*********************************************************/
1702d14abf15SRobert Mustacchi
1703d14abf15SRobert Mustacchi BNXE_LOCK_EXIT_GLDTX(pUM);
1704d14abf15SRobert Mustacchi
1705d14abf15SRobert Mustacchi /*********************************************************/
1706d14abf15SRobert Mustacchi
1707d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Cleaning up L2 Tx Pkts");
1708d14abf15SRobert Mustacchi
1709d14abf15SRobert Mustacchi BnxeTxPktsFini(pUM, LM_CLI_IDX_NDIS);
1710d14abf15SRobert Mustacchi
1711d14abf15SRobert Mustacchi /*********************************************************/
1712d14abf15SRobert Mustacchi
1713d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Cleaning up L2 Rx Pkts");
1714d14abf15SRobert Mustacchi
1715d14abf15SRobert Mustacchi BnxeRxPktsFini(pUM, LM_CLI_IDX_NDIS);
1716d14abf15SRobert Mustacchi
1717d14abf15SRobert Mustacchi /*********************************************************/
1718d14abf15SRobert Mustacchi
1719d14abf15SRobert Mustacchi BnxeHwStopCore(pUM);
1720d14abf15SRobert Mustacchi
1721d14abf15SRobert Mustacchi /*********************************************************/
1722d14abf15SRobert Mustacchi
1723d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStopL2: L2 stopped (clients %s)",
1724d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1725d14abf15SRobert Mustacchi
1726d14abf15SRobert Mustacchi BNXE_LOCK_EXIT_HWINIT(pUM);
1727d14abf15SRobert Mustacchi }
1728d14abf15SRobert Mustacchi
1729d14abf15SRobert Mustacchi
1730d14abf15SRobert Mustacchi /* Must be called with BNXE_LOCK_ENTER_HWINIT taken! */
BnxeHwStopCore(um_device_t * pUM)1731d14abf15SRobert Mustacchi void BnxeHwStopCore(um_device_t * pUM)
1732d14abf15SRobert Mustacchi {
1733d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
1734d14abf15SRobert Mustacchi BnxeMemBlock * pMemBlock;
1735d14abf15SRobert Mustacchi BnxeMemDma * pMemDma;
1736d14abf15SRobert Mustacchi lm_address_t physAddr;
1737d14abf15SRobert Mustacchi int rc;
1738d14abf15SRobert Mustacchi
1739d14abf15SRobert Mustacchi physAddr.as_ptr = NULL;
1740d14abf15SRobert Mustacchi
1741d14abf15SRobert Mustacchi if (!pUM->hwInitDone)
1742d14abf15SRobert Mustacchi {
1743d14abf15SRobert Mustacchi /* already finished? (should never get here) */
1744d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "BnxeHwStopCore: Hardware already stopped (clients %s)",
1745d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1746d14abf15SRobert Mustacchi return;
1747d14abf15SRobert Mustacchi }
1748d14abf15SRobert Mustacchi
1749d14abf15SRobert Mustacchi if (BnxeIsClientBound(pUM))
1750d14abf15SRobert Mustacchi {
1751d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStopCore: Hardware cannot be stopped (clients %s)",
1752d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1753d14abf15SRobert Mustacchi return;
1754d14abf15SRobert Mustacchi }
1755d14abf15SRobert Mustacchi
1756d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStopCore: Stopping hardware (clients %s)",
1757d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1758d14abf15SRobert Mustacchi
1759d14abf15SRobert Mustacchi mm_indicate_link(pLM, LM_STATUS_LINK_DOWN, pUM->devParams.lastIndMedium);
1760d14abf15SRobert Mustacchi
1761d14abf15SRobert Mustacchi /*********************************************************/
1762d14abf15SRobert Mustacchi
1763d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Stopping Timer");
1764d14abf15SRobert Mustacchi
1765d14abf15SRobert Mustacchi BnxeTimerStop(pUM);
1766d14abf15SRobert Mustacchi
1767d14abf15SRobert Mustacchi /*********************************************************/
1768d14abf15SRobert Mustacchi
1769d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Stopping DCBX");
1770d14abf15SRobert Mustacchi
1771d14abf15SRobert Mustacchi lm_dcbx_free_resc(pLM);
1772d14abf15SRobert Mustacchi
1773d14abf15SRobert Mustacchi /*********************************************************/
1774d14abf15SRobert Mustacchi
1775d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Stopping BRCM Chip");
1776d14abf15SRobert Mustacchi
1777d14abf15SRobert Mustacchi rc = lm_chip_stop(pLM);
1778d14abf15SRobert Mustacchi
1779d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1780d14abf15SRobert Mustacchi BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
1781d14abf15SRobert Mustacchi {
1782d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
1783d14abf15SRobert Mustacchi }
1784d14abf15SRobert Mustacchi
1785d14abf15SRobert Mustacchi if (rc != LM_STATUS_SUCCESS)
1786d14abf15SRobert Mustacchi {
1787d14abf15SRobert Mustacchi BnxeFmErrorReport(pUM, DDI_FM_DEVICE_INVAL_STATE);
1788d14abf15SRobert Mustacchi }
1789d14abf15SRobert Mustacchi
1790d14abf15SRobert Mustacchi atomic_swap_32(&pUM->chipStarted, B_FALSE);
1791d14abf15SRobert Mustacchi
1792d14abf15SRobert Mustacchi /*********************************************************/
1793d14abf15SRobert Mustacchi
1794d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Disabling Interrupts");
1795d14abf15SRobert Mustacchi
1796d14abf15SRobert Mustacchi BnxeIntrDisable(pUM);
1797d14abf15SRobert Mustacchi
1798d14abf15SRobert Mustacchi /*********************************************************/
1799d14abf15SRobert Mustacchi
1800d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Resetting BRCM Chip");
1801d14abf15SRobert Mustacchi
1802d14abf15SRobert Mustacchi lm_chip_reset(pLM, LM_REASON_DRIVER_SHUTDOWN);
1803d14abf15SRobert Mustacchi
1804d14abf15SRobert Mustacchi pUM->phyInitialized = B_FALSE;
1805d14abf15SRobert Mustacchi
1806d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1807d14abf15SRobert Mustacchi BnxeCheckAccHandle(pUM->pPciCfg) != DDI_FM_OK)
1808d14abf15SRobert Mustacchi {
1809d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
1810d14abf15SRobert Mustacchi }
1811d14abf15SRobert Mustacchi
1812d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1813d14abf15SRobert Mustacchi BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
1814d14abf15SRobert Mustacchi {
1815d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
1816d14abf15SRobert Mustacchi }
1817d14abf15SRobert Mustacchi
1818d14abf15SRobert Mustacchi /*********************************************************/
1819d14abf15SRobert Mustacchi
1820d14abf15SRobert Mustacchi while (!d_list_is_empty(&pUM->memBlockList))
1821d14abf15SRobert Mustacchi {
1822d14abf15SRobert Mustacchi pMemBlock = (BnxeMemBlock *)d_list_peek_head(&pUM->memBlockList);
1823d14abf15SRobert Mustacchi mm_rt_free_mem(pLM,
1824d14abf15SRobert Mustacchi ((char *)pMemBlock->pBuf + BNXE_MEM_CHECK_LEN),
1825d14abf15SRobert Mustacchi (pMemBlock->size - (BNXE_MEM_CHECK_LEN * 2)),
1826d14abf15SRobert Mustacchi LM_CLI_IDX_NDIS);
1827d14abf15SRobert Mustacchi }
1828d14abf15SRobert Mustacchi
1829d14abf15SRobert Mustacchi #ifndef BNXE_DEBUG_DMA_LIST
1830d14abf15SRobert Mustacchi while (!d_list_is_empty(&pUM->memDmaList))
1831d14abf15SRobert Mustacchi {
1832d14abf15SRobert Mustacchi pMemDma = (BnxeMemDma *)d_list_peek_head(&pUM->memDmaList);
1833d14abf15SRobert Mustacchi mm_rt_free_phys_mem(pLM,
1834d14abf15SRobert Mustacchi pMemDma->size,
1835d14abf15SRobert Mustacchi pMemDma->pDmaVirt,
1836d14abf15SRobert Mustacchi physAddr,
1837d14abf15SRobert Mustacchi LM_CLI_IDX_NDIS);
1838d14abf15SRobert Mustacchi }
1839d14abf15SRobert Mustacchi #else
1840d14abf15SRobert Mustacchi {
1841d14abf15SRobert Mustacchi BnxeMemDma * pTmp;
1842d14abf15SRobert Mustacchi int i;
1843d14abf15SRobert Mustacchi
1844d14abf15SRobert Mustacchi BNXE_LOCK_ENTER_MEM(pUM);
1845d14abf15SRobert Mustacchi
1846d14abf15SRobert Mustacchi pTmp = (BnxeMemDma *)d_list_peek_head(&pUM->memDmaList);
1847d14abf15SRobert Mustacchi while (pTmp)
1848d14abf15SRobert Mustacchi {
1849d14abf15SRobert Mustacchi for (i = 0; i < pTmp->size; i++)
1850d14abf15SRobert Mustacchi {
1851d14abf15SRobert Mustacchi ((u8_t *)pTmp->pDmaVirt)[i] = 0x0;
1852d14abf15SRobert Mustacchi }
1853d14abf15SRobert Mustacchi
1854d14abf15SRobert Mustacchi pTmp = (BnxeMemDma *)d_list_next_entry(&pTmp->link);
1855d14abf15SRobert Mustacchi }
1856d14abf15SRobert Mustacchi
1857d14abf15SRobert Mustacchi d_list_add_head(&pUM->memDmaListSaved, &pUM->memDmaList);
1858d14abf15SRobert Mustacchi d_list_clear(&pUM->memDmaList);
1859d14abf15SRobert Mustacchi
1860d14abf15SRobert Mustacchi BNXE_LOCK_EXIT_MEM(pUM);
1861d14abf15SRobert Mustacchi
1862d14abf15SRobert Mustacchi BnxeVerifySavedDmaList(pUM);
1863d14abf15SRobert Mustacchi }
1864d14abf15SRobert Mustacchi #endif /* BNXE_DEBUG_DMA_LIST */
1865d14abf15SRobert Mustacchi
1866d14abf15SRobert Mustacchi atomic_swap_32(&pUM->hwInitDone, B_FALSE);
1867d14abf15SRobert Mustacchi
1868d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "BnxeHwStopCore: Hardware stopped (clients %s)",
1869d14abf15SRobert Mustacchi BnxeClientsHw(pUM));
1870d14abf15SRobert Mustacchi }
1871d14abf15SRobert Mustacchi
1872d14abf15SRobert Mustacchi
BnxeHwResume(um_device_t * pUM)1873d14abf15SRobert Mustacchi int BnxeHwResume(um_device_t * pUM)
1874d14abf15SRobert Mustacchi {
1875d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
1876d14abf15SRobert Mustacchi int rc;
1877d14abf15SRobert Mustacchi
1878d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Setting Power State");
1879d14abf15SRobert Mustacchi lm_set_power_state(pLM, LM_POWER_STATE_D0, LM_WAKE_UP_MODE_NONE, FALSE);
1880d14abf15SRobert Mustacchi
1881d14abf15SRobert Mustacchi /* XXX Do we need it? */
1882d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Enabling PCI DMA");
1883d14abf15SRobert Mustacchi lm_enable_pci_dma(pLM);
1884d14abf15SRobert Mustacchi
1885d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1886d14abf15SRobert Mustacchi BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
1887d14abf15SRobert Mustacchi {
1888d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_LOST);
1889d14abf15SRobert Mustacchi return -1;
1890d14abf15SRobert Mustacchi }
1891d14abf15SRobert Mustacchi
1892d14abf15SRobert Mustacchi if (!pUM->plumbed)
1893d14abf15SRobert Mustacchi {
1894d14abf15SRobert Mustacchi /* XXX
1895d14abf15SRobert Mustacchi * Won't work under new model with multiple clients. Need an
1896d14abf15SRobert Mustacchi * extra pause mechanism/layer for suspend and resume.
1897d14abf15SRobert Mustacchi */
1898d14abf15SRobert Mustacchi if (BnxeHwStartCore(pUM))
1899d14abf15SRobert Mustacchi {
1900d14abf15SRobert Mustacchi return -1;
1901d14abf15SRobert Mustacchi }
1902d14abf15SRobert Mustacchi
1903d14abf15SRobert Mustacchi atomic_swap_32(&pUM->plumbed, B_TRUE);
1904d14abf15SRobert Mustacchi }
1905d14abf15SRobert Mustacchi
1906d14abf15SRobert Mustacchi return 0;
1907d14abf15SRobert Mustacchi }
1908d14abf15SRobert Mustacchi
1909d14abf15SRobert Mustacchi
BnxeHwSuspend(um_device_t * pUM)1910d14abf15SRobert Mustacchi int BnxeHwSuspend(um_device_t * pUM)
1911d14abf15SRobert Mustacchi {
1912d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
1913d14abf15SRobert Mustacchi
1914d14abf15SRobert Mustacchi lm_reset_set_inprogress(pLM);
1915d14abf15SRobert Mustacchi lm_reset_mask_attn(pLM);
1916d14abf15SRobert Mustacchi
1917d14abf15SRobert Mustacchi disable_blocks_attention(pLM);
1918d14abf15SRobert Mustacchi
1919d14abf15SRobert Mustacchi if (pUM->plumbed)
1920d14abf15SRobert Mustacchi {
1921d14abf15SRobert Mustacchi /* XXX
1922d14abf15SRobert Mustacchi * Won't work under new model with multiple clients. Need an
1923d14abf15SRobert Mustacchi * extra pause mechanism/layer for suspend and resume.
1924d14abf15SRobert Mustacchi */
1925d14abf15SRobert Mustacchi BnxeHwStopCore(pUM);
1926d14abf15SRobert Mustacchi atomic_swap_32(&pUM->plumbed, B_FALSE);
1927d14abf15SRobert Mustacchi }
1928d14abf15SRobert Mustacchi
1929d14abf15SRobert Mustacchi /* XXX proper lm_wake_up_mode_t when WOL supported */
1930d14abf15SRobert Mustacchi lm_set_d3_nwuf(pLM, LM_WAKE_UP_MODE_NONE);
1931d14abf15SRobert Mustacchi
1932d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1933d14abf15SRobert Mustacchi BnxeCheckAccHandle(pUM->pPciCfg) != DDI_FM_OK)
1934d14abf15SRobert Mustacchi {
1935d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
1936d14abf15SRobert Mustacchi return LM_STATUS_FAILURE;
1937d14abf15SRobert Mustacchi }
1938d14abf15SRobert Mustacchi
1939d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1940d14abf15SRobert Mustacchi BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
1941d14abf15SRobert Mustacchi {
1942d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
1943d14abf15SRobert Mustacchi return -1;
1944d14abf15SRobert Mustacchi }
1945d14abf15SRobert Mustacchi
1946d14abf15SRobert Mustacchi /* XXX proper lm_wake_up_mode_t when WOL supported */
1947d14abf15SRobert Mustacchi lm_set_d3_mpkt(pLM, LM_WAKE_UP_MODE_NONE);
1948d14abf15SRobert Mustacchi
1949d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1950d14abf15SRobert Mustacchi BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
1951d14abf15SRobert Mustacchi {
1952d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
1953d14abf15SRobert Mustacchi return -1;
1954d14abf15SRobert Mustacchi }
1955d14abf15SRobert Mustacchi
1956d14abf15SRobert Mustacchi /* XXX Do we need it? */
1957d14abf15SRobert Mustacchi BnxeLogDbg(pUM, "Disabling PCI DMA");
1958d14abf15SRobert Mustacchi lm_disable_pci_dma(pLM, TRUE);
1959d14abf15SRobert Mustacchi
1960d14abf15SRobert Mustacchi if (pUM->fmCapabilities &&
1961d14abf15SRobert Mustacchi BnxeCheckAccHandle(pLM->vars.reg_handle[BAR_0]) != DDI_FM_OK)
1962d14abf15SRobert Mustacchi {
1963d14abf15SRobert Mustacchi ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
1964d14abf15SRobert Mustacchi return -1;
1965d14abf15SRobert Mustacchi }
1966d14abf15SRobert Mustacchi
1967d14abf15SRobert Mustacchi return 0;
1968d14abf15SRobert Mustacchi }
1969d14abf15SRobert Mustacchi
1970d14abf15SRobert Mustacchi
1971d14abf15SRobert Mustacchi #if (DEVO_REV > 3)
1972d14abf15SRobert Mustacchi
1973d14abf15SRobert Mustacchi /*
1974d14abf15SRobert Mustacchi * This is a non-blocking function to make sure no more interrupt and dma memory
1975d14abf15SRobert Mustacchi * access of this hardware. We don't have to free any resource here.
1976d14abf15SRobert Mustacchi */
BnxeHwQuiesce(um_device_t * pUM)1977d14abf15SRobert Mustacchi int BnxeHwQuiesce(um_device_t * pUM)
1978d14abf15SRobert Mustacchi {
1979d14abf15SRobert Mustacchi lm_device_t * pLM = &pUM->lm_dev;
1980d14abf15SRobert Mustacchi
1981d14abf15SRobert Mustacchi /* XXX temporary block until bnxef supports fast reboot... */
1982d14abf15SRobert Mustacchi if (CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE))
1983d14abf15SRobert Mustacchi {
1984d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Unable to quiesce, FCoE is bound!");
1985d14abf15SRobert Mustacchi return -1;
1986d14abf15SRobert Mustacchi }
1987d14abf15SRobert Mustacchi
1988d14abf15SRobert Mustacchi #if 0
1989d14abf15SRobert Mustacchi lm_chip_stop(pLM);
1990d14abf15SRobert Mustacchi #endif
1991d14abf15SRobert Mustacchi
1992d14abf15SRobert Mustacchi lm_disable_int(pLM);
1993d14abf15SRobert Mustacchi
1994d14abf15SRobert Mustacchi lm_chip_reset(pLM, LM_REASON_DRIVER_SHUTDOWN);
1995d14abf15SRobert Mustacchi
1996d14abf15SRobert Mustacchi BnxeRxPktsAbort(pUM, LM_CLI_IDX_NDIS);
1997d14abf15SRobert Mustacchi BnxeTxPktsAbort(pUM, LM_CLI_IDX_NDIS);
1998d14abf15SRobert Mustacchi
1999d14abf15SRobert Mustacchi return 0;
2000d14abf15SRobert Mustacchi }
2001d14abf15SRobert Mustacchi
2002d14abf15SRobert Mustacchi #endif
2003d14abf15SRobert Mustacchi
2004