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