xref: /titanic_52/usr/src/uts/common/io/bnxe/bnxe_fcoe.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 #include "bnxe.h"
36*d14abf15SRobert Mustacchi 
37*d14abf15SRobert Mustacchi 
38*d14abf15SRobert Mustacchi #define VERIFY_FCOE_BINDING(pUM)                                  \
39*d14abf15SRobert Mustacchi     if (!BNXE_FCOE(pUM))                                          \
40*d14abf15SRobert Mustacchi     {                                                             \
41*d14abf15SRobert Mustacchi         BnxeLogWarn((pUM), "FCoE not supported on this device!"); \
42*d14abf15SRobert Mustacchi         return B_FALSE;                                           \
43*d14abf15SRobert Mustacchi     }                                                             \
44*d14abf15SRobert Mustacchi     if (!(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE)))                    \
45*d14abf15SRobert Mustacchi     {                                                             \
46*d14abf15SRobert Mustacchi         BnxeLogWarn((pUM), "FCoE client not bound!");             \
47*d14abf15SRobert Mustacchi         return B_FALSE;                                           \
48*d14abf15SRobert Mustacchi     }
49*d14abf15SRobert Mustacchi 
50*d14abf15SRobert Mustacchi 
51*d14abf15SRobert Mustacchi void BnxeFcoeFreeResc(um_device_t *   pUM,
52*d14abf15SRobert Mustacchi                       BnxeFcoeState * pFcoeState)
53*d14abf15SRobert Mustacchi {
54*d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_OFFLOAD(pUM);
55*d14abf15SRobert Mustacchi     lm_fc_del_fcoe_state(&pUM->lm_dev, &pFcoeState->lm_fcoe);
56*d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_OFFLOAD(pUM);
57*d14abf15SRobert Mustacchi 
58*d14abf15SRobert Mustacchi     lm_fc_free_con_resc(&pUM->lm_dev, &pFcoeState->lm_fcoe);
59*d14abf15SRobert Mustacchi 
60*d14abf15SRobert Mustacchi     kmem_free(pFcoeState, sizeof(BnxeFcoeState));
61*d14abf15SRobert Mustacchi }
62*d14abf15SRobert Mustacchi 
63*d14abf15SRobert Mustacchi 
64*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeCqeIndicate(um_device_t * pUM,
65*d14abf15SRobert Mustacchi                                      void *        pData,
66*d14abf15SRobert Mustacchi                                      u32_t         dataLen)
67*d14abf15SRobert Mustacchi {
68*d14abf15SRobert Mustacchi     struct fcoe_kcqe * kcqe = (struct fcoe_kcqe *)pData;
69*d14abf15SRobert Mustacchi 
70*d14abf15SRobert Mustacchi     if (dataLen != (sizeof(*kcqe)))
71*d14abf15SRobert Mustacchi     {
72*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Invalid FCoE CQE");
73*d14abf15SRobert Mustacchi         return B_FALSE;
74*d14abf15SRobert Mustacchi     }
75*d14abf15SRobert Mustacchi 
76*d14abf15SRobert Mustacchi     /* XXX
77*d14abf15SRobert Mustacchi      * Need to add a mutex or reference count to ensure that bnxef isn't
78*d14abf15SRobert Mustacchi      * unloaded underneath this taskq dispatch routine.
79*d14abf15SRobert Mustacchi      */
80*d14abf15SRobert Mustacchi 
81*d14abf15SRobert Mustacchi     ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE));
82*d14abf15SRobert Mustacchi     pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev,
83*d14abf15SRobert Mustacchi                                    (void **)&kcqe, 1);
84*d14abf15SRobert Mustacchi 
85*d14abf15SRobert Mustacchi     /* XXX release mutex or decrement reference count */
86*d14abf15SRobert Mustacchi 
87*d14abf15SRobert Mustacchi     return B_TRUE;
88*d14abf15SRobert Mustacchi }
89*d14abf15SRobert Mustacchi 
90*d14abf15SRobert Mustacchi 
91*d14abf15SRobert Mustacchi static void BnxeFcoeInitCqeWork(um_device_t * pUM,
92*d14abf15SRobert Mustacchi                                 void *        pData,
93*d14abf15SRobert Mustacchi                                 u32_t         dataLen)
94*d14abf15SRobert Mustacchi {
95*d14abf15SRobert Mustacchi     if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen))
96*d14abf15SRobert Mustacchi     {
97*d14abf15SRobert Mustacchi         pUM->fcoe.stats.initCqeRxErr++;
98*d14abf15SRobert Mustacchi     }
99*d14abf15SRobert Mustacchi     else
100*d14abf15SRobert Mustacchi     {
101*d14abf15SRobert Mustacchi         pUM->fcoe.stats.initCqeRx++;
102*d14abf15SRobert Mustacchi     }
103*d14abf15SRobert Mustacchi }
104*d14abf15SRobert Mustacchi 
105*d14abf15SRobert Mustacchi 
106*d14abf15SRobert Mustacchi boolean_t BnxeFcoeInitCqe(um_device_t *      pUM,
107*d14abf15SRobert Mustacchi                           struct fcoe_kcqe * kcqe)
108*d14abf15SRobert Mustacchi {
109*d14abf15SRobert Mustacchi     struct fcoe_kcqe tmp_kcqe = {0};
110*d14abf15SRobert Mustacchi 
111*d14abf15SRobert Mustacchi     tmp_kcqe.op_code = FCOE_KCQE_OPCODE_INIT_FUNC;
112*d14abf15SRobert Mustacchi 
113*d14abf15SRobert Mustacchi     tmp_kcqe.flags |=
114*d14abf15SRobert Mustacchi         (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
115*d14abf15SRobert Mustacchi 
116*d14abf15SRobert Mustacchi     tmp_kcqe.completion_status =
117*d14abf15SRobert Mustacchi         mm_cpu_to_le32((mm_le32_to_cpu(kcqe->completion_status) == 0) ?
118*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_SUCCESS :
119*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR);
120*d14abf15SRobert Mustacchi 
121*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeInitCqeWork,
122*d14abf15SRobert Mustacchi                             &tmp_kcqe, sizeof(tmp_kcqe));
123*d14abf15SRobert Mustacchi }
124*d14abf15SRobert Mustacchi 
125*d14abf15SRobert Mustacchi 
126*d14abf15SRobert Mustacchi static void BnxeFcoeInitWqeWork(um_device_t * pUM,
127*d14abf15SRobert Mustacchi                                 void *        pData,
128*d14abf15SRobert Mustacchi                                 u32_t         dataLen)
129*d14abf15SRobert Mustacchi {
130*d14abf15SRobert Mustacchi     union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData;
131*d14abf15SRobert Mustacchi     struct fcoe_kcqe  kcqe  = {0};
132*d14abf15SRobert Mustacchi 
133*d14abf15SRobert Mustacchi     if (dataLen != (3 * sizeof(*kwqe)))
134*d14abf15SRobert Mustacchi     {
135*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Invalid FCoE Init WQE");
136*d14abf15SRobert Mustacchi         pUM->fcoe.stats.initWqeTxErr++;
137*d14abf15SRobert Mustacchi         return;
138*d14abf15SRobert Mustacchi     }
139*d14abf15SRobert Mustacchi 
140*d14abf15SRobert Mustacchi     if (kwqe[1].init2.hsi_major_version != FCOE_HSI_MAJOR_VERSION)
141*d14abf15SRobert Mustacchi     {
142*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "ERROR: Invalid FCoE HSI major version (L5=%d vs FW=%d)",
143*d14abf15SRobert Mustacchi                     kwqe[1].init2.hsi_major_version,
144*d14abf15SRobert Mustacchi                     FCOE_HSI_MAJOR_VERSION);
145*d14abf15SRobert Mustacchi         kcqe.completion_status = FCOE_KCQE_COMPLETION_STATUS_WRONG_HSI_VERSION;
146*d14abf15SRobert Mustacchi         goto BnxeFcoeInitWqeWork_error;
147*d14abf15SRobert Mustacchi     }
148*d14abf15SRobert Mustacchi 
149*d14abf15SRobert Mustacchi     if (lm_fc_init(&pUM->lm_dev,
150*d14abf15SRobert Mustacchi                    &kwqe[0].init1,
151*d14abf15SRobert Mustacchi                    &kwqe[1].init2,
152*d14abf15SRobert Mustacchi                    &kwqe[2].init3) != LM_STATUS_SUCCESS)
153*d14abf15SRobert Mustacchi     {
154*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to post FCoE Init WQE");
155*d14abf15SRobert Mustacchi         kcqe.completion_status = FCOE_KCQE_COMPLETION_STATUS_ERROR;
156*d14abf15SRobert Mustacchi         goto BnxeFcoeInitWqeWork_error;
157*d14abf15SRobert Mustacchi     }
158*d14abf15SRobert Mustacchi 
159*d14abf15SRobert Mustacchi     pUM->fcoe.stats.initWqeTx++;
160*d14abf15SRobert Mustacchi 
161*d14abf15SRobert Mustacchi     return;
162*d14abf15SRobert Mustacchi 
163*d14abf15SRobert Mustacchi BnxeFcoeInitWqeWork_error:
164*d14abf15SRobert Mustacchi 
165*d14abf15SRobert Mustacchi     pUM->fcoe.stats.initWqeTxErr++;
166*d14abf15SRobert Mustacchi 
167*d14abf15SRobert Mustacchi     kcqe.op_code = FCOE_KCQE_OPCODE_INIT_FUNC;
168*d14abf15SRobert Mustacchi     kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
169*d14abf15SRobert Mustacchi     kcqe.completion_status = mm_cpu_to_le32(kcqe.completion_status);
170*d14abf15SRobert Mustacchi     kcqe.fcoe_conn_id = kwqe[1].conn_offload1.fcoe_conn_id;
171*d14abf15SRobert Mustacchi 
172*d14abf15SRobert Mustacchi     /* call here directly (for error case) */
173*d14abf15SRobert Mustacchi 
174*d14abf15SRobert Mustacchi     /* XXX
175*d14abf15SRobert Mustacchi      * Need to add a mutex or reference count to ensure that bnxef isn't
176*d14abf15SRobert Mustacchi      * unloaded underneath this taskq dispatch routine.
177*d14abf15SRobert Mustacchi      */
178*d14abf15SRobert Mustacchi 
179*d14abf15SRobert Mustacchi     {
180*d14abf15SRobert Mustacchi         struct fcoe_kcqe * pKcqe = &kcqe;
181*d14abf15SRobert Mustacchi         ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE));
182*d14abf15SRobert Mustacchi         pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev,
183*d14abf15SRobert Mustacchi                                        (void **)&pKcqe, 1);
184*d14abf15SRobert Mustacchi     }
185*d14abf15SRobert Mustacchi 
186*d14abf15SRobert Mustacchi     /* XXX release mutex or decrement reference count */
187*d14abf15SRobert Mustacchi }
188*d14abf15SRobert Mustacchi 
189*d14abf15SRobert Mustacchi 
190*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeInitWqe(um_device_t *      pUM,
191*d14abf15SRobert Mustacchi                                  union fcoe_kwqe ** kwqes)
192*d14abf15SRobert Mustacchi {
193*d14abf15SRobert Mustacchi     union fcoe_kwqe wqe[3];
194*d14abf15SRobert Mustacchi 
195*d14abf15SRobert Mustacchi     wqe[0] =*(kwqes[0]);
196*d14abf15SRobert Mustacchi     wqe[1] =*(kwqes[1]);
197*d14abf15SRobert Mustacchi     wqe[2] =*(kwqes[2]);
198*d14abf15SRobert Mustacchi 
199*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeInitWqeWork, wqe, sizeof(wqe));
200*d14abf15SRobert Mustacchi }
201*d14abf15SRobert Mustacchi 
202*d14abf15SRobert Mustacchi 
203*d14abf15SRobert Mustacchi static void BnxeFcoeOffloadConnCqeWork(um_device_t * pUM,
204*d14abf15SRobert Mustacchi                                        void *        pData,
205*d14abf15SRobert Mustacchi                                        u32_t         dataLen)
206*d14abf15SRobert Mustacchi {
207*d14abf15SRobert Mustacchi     if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen))
208*d14abf15SRobert Mustacchi     {
209*d14abf15SRobert Mustacchi         pUM->fcoe.stats.offloadConnCqeRxErr++;
210*d14abf15SRobert Mustacchi     }
211*d14abf15SRobert Mustacchi     else
212*d14abf15SRobert Mustacchi     {
213*d14abf15SRobert Mustacchi         pUM->fcoe.stats.offloadConnCqeRx++;
214*d14abf15SRobert Mustacchi     }
215*d14abf15SRobert Mustacchi }
216*d14abf15SRobert Mustacchi 
217*d14abf15SRobert Mustacchi 
218*d14abf15SRobert Mustacchi boolean_t BnxeFcoeOffloadConnCqe(um_device_t *      pUM,
219*d14abf15SRobert Mustacchi                                  BnxeFcoeState *    pFcoeState,
220*d14abf15SRobert Mustacchi                                  struct fcoe_kcqe * kcqe)
221*d14abf15SRobert Mustacchi {
222*d14abf15SRobert Mustacchi     struct fcoe_kcqe tmp_kcqe = {0};
223*d14abf15SRobert Mustacchi 
224*d14abf15SRobert Mustacchi     tmp_kcqe.op_code = FCOE_KCQE_OPCODE_OFFLOAD_CONN;
225*d14abf15SRobert Mustacchi 
226*d14abf15SRobert Mustacchi     tmp_kcqe.flags |=
227*d14abf15SRobert Mustacchi         (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
228*d14abf15SRobert Mustacchi 
229*d14abf15SRobert Mustacchi     tmp_kcqe.fcoe_conn_context_id = kcqe->fcoe_conn_context_id;
230*d14abf15SRobert Mustacchi     tmp_kcqe.fcoe_conn_id         = kcqe->fcoe_conn_id;
231*d14abf15SRobert Mustacchi 
232*d14abf15SRobert Mustacchi     tmp_kcqe.completion_status =
233*d14abf15SRobert Mustacchi         mm_cpu_to_le32((mm_le32_to_cpu(kcqe->completion_status) == 0) ?
234*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_SUCCESS :
235*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE);
236*d14abf15SRobert Mustacchi 
237*d14abf15SRobert Mustacchi     if (pFcoeState != NULL)
238*d14abf15SRobert Mustacchi     {
239*d14abf15SRobert Mustacchi         pFcoeState->lm_fcoe.hdr.status =
240*d14abf15SRobert Mustacchi             (mm_le32_to_cpu(kcqe->completion_status) == 0) ?
241*d14abf15SRobert Mustacchi                 STATE_STATUS_NORMAL :
242*d14abf15SRobert Mustacchi                 STATE_STATUS_INIT_OFFLOAD_ERR;
243*d14abf15SRobert Mustacchi     }
244*d14abf15SRobert Mustacchi 
245*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeOffloadConnCqeWork,
246*d14abf15SRobert Mustacchi                             &tmp_kcqe, sizeof(tmp_kcqe));
247*d14abf15SRobert Mustacchi }
248*d14abf15SRobert Mustacchi 
249*d14abf15SRobert Mustacchi 
250*d14abf15SRobert Mustacchi static void BnxeFcoeOffloadConnWqeWork(um_device_t * pUM,
251*d14abf15SRobert Mustacchi                                        void *        pData,
252*d14abf15SRobert Mustacchi                                        u32_t         dataLen)
253*d14abf15SRobert Mustacchi {
254*d14abf15SRobert Mustacchi     union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData;
255*d14abf15SRobert Mustacchi     struct fcoe_kcqe  kcqe = {0};
256*d14abf15SRobert Mustacchi     BnxeFcoeState *   pFcoeState;
257*d14abf15SRobert Mustacchi     lm_status_t       rc;
258*d14abf15SRobert Mustacchi 
259*d14abf15SRobert Mustacchi     if (dataLen != (4 * sizeof(*kwqe)))
260*d14abf15SRobert Mustacchi     {
261*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Invalid FCoE Offload Conn WQE");
262*d14abf15SRobert Mustacchi         pUM->fcoe.stats.offloadConnWqeTxErr++;
263*d14abf15SRobert Mustacchi         return;
264*d14abf15SRobert Mustacchi     }
265*d14abf15SRobert Mustacchi 
266*d14abf15SRobert Mustacchi     if ((pFcoeState = kmem_zalloc(sizeof(BnxeFcoeState),
267*d14abf15SRobert Mustacchi                                   KM_NOSLEEP)) == NULL)
268*d14abf15SRobert Mustacchi     {
269*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to allocate memory for FCoE state");
270*d14abf15SRobert Mustacchi         goto BnxeFcoeOffloadConnWqeWork_error;
271*d14abf15SRobert Mustacchi     }
272*d14abf15SRobert Mustacchi 
273*d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_OFFLOAD(pUM);
274*d14abf15SRobert Mustacchi     rc = lm_fc_init_fcoe_state(&pUM->lm_dev,
275*d14abf15SRobert Mustacchi                                &pUM->lm_dev.fcoe_info.run_time.state_blk,
276*d14abf15SRobert Mustacchi                                &pFcoeState->lm_fcoe);
277*d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_OFFLOAD(pUM);
278*d14abf15SRobert Mustacchi 
279*d14abf15SRobert Mustacchi     if (rc != LM_STATUS_SUCCESS)
280*d14abf15SRobert Mustacchi     {
281*d14abf15SRobert Mustacchi         kmem_free(pFcoeState, sizeof(BnxeFcoeState));
282*d14abf15SRobert Mustacchi 
283*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to initialize FCoE state");
284*d14abf15SRobert Mustacchi         goto BnxeFcoeOffloadConnWqeWork_error;
285*d14abf15SRobert Mustacchi     }
286*d14abf15SRobert Mustacchi 
287*d14abf15SRobert Mustacchi     pFcoeState->lm_fcoe.ofld1 = kwqe[0].conn_offload1;
288*d14abf15SRobert Mustacchi     pFcoeState->lm_fcoe.ofld2 = kwqe[1].conn_offload2;
289*d14abf15SRobert Mustacchi     pFcoeState->lm_fcoe.ofld3 = kwqe[2].conn_offload3;
290*d14abf15SRobert Mustacchi     pFcoeState->lm_fcoe.ofld4 = kwqe[3].conn_offload4;
291*d14abf15SRobert Mustacchi 
292*d14abf15SRobert Mustacchi     rc = lm_fc_alloc_con_resc(&pUM->lm_dev, &pFcoeState->lm_fcoe);
293*d14abf15SRobert Mustacchi 
294*d14abf15SRobert Mustacchi     if (rc == LM_STATUS_SUCCESS)
295*d14abf15SRobert Mustacchi     {
296*d14abf15SRobert Mustacchi         lm_fc_init_fcoe_context(&pUM->lm_dev, &pFcoeState->lm_fcoe);
297*d14abf15SRobert Mustacchi         lm_fc_post_offload_ramrod(&pUM->lm_dev, &pFcoeState->lm_fcoe);
298*d14abf15SRobert Mustacchi     }
299*d14abf15SRobert Mustacchi     else if (rc == LM_STATUS_PENDING)
300*d14abf15SRobert Mustacchi     {
301*d14abf15SRobert Mustacchi         /*
302*d14abf15SRobert Mustacchi          * the cid is pending - its too soon to initialize the context, it will
303*d14abf15SRobert Mustacchi          * be initialized from the recycle cid callback and completed as well.
304*d14abf15SRobert Mustacchi          */
305*d14abf15SRobert Mustacchi         BnxeLogInfo(pUM, "lm_fc_alloc_con_resc returned pending?");
306*d14abf15SRobert Mustacchi     }
307*d14abf15SRobert Mustacchi     else
308*d14abf15SRobert Mustacchi     {
309*d14abf15SRobert Mustacchi         BnxeFcoeFreeResc(pUM, pFcoeState);
310*d14abf15SRobert Mustacchi         BnxeLogInfo(pUM, "lm_fc_alloc_con_resc failed (%d)", rc);
311*d14abf15SRobert Mustacchi         goto BnxeFcoeOffloadConnWqeWork_error;
312*d14abf15SRobert Mustacchi     }
313*d14abf15SRobert Mustacchi 
314*d14abf15SRobert Mustacchi     pUM->fcoe.stats.offloadConnWqeTx++;
315*d14abf15SRobert Mustacchi 
316*d14abf15SRobert Mustacchi     return;
317*d14abf15SRobert Mustacchi 
318*d14abf15SRobert Mustacchi BnxeFcoeOffloadConnWqeWork_error:
319*d14abf15SRobert Mustacchi 
320*d14abf15SRobert Mustacchi     pUM->fcoe.stats.offloadConnWqeTxErr++;
321*d14abf15SRobert Mustacchi 
322*d14abf15SRobert Mustacchi     kcqe.op_code = FCOE_KCQE_OPCODE_OFFLOAD_CONN;
323*d14abf15SRobert Mustacchi     kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
324*d14abf15SRobert Mustacchi     kcqe.completion_status = mm_cpu_to_le32(FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE);
325*d14abf15SRobert Mustacchi     kcqe.fcoe_conn_id = kwqe[0].conn_offload1.fcoe_conn_id;
326*d14abf15SRobert Mustacchi 
327*d14abf15SRobert Mustacchi     /* call here directly (for error case) */
328*d14abf15SRobert Mustacchi 
329*d14abf15SRobert Mustacchi     /* XXX
330*d14abf15SRobert Mustacchi      * Need to add a mutex or reference count to ensure that bnxef isn't
331*d14abf15SRobert Mustacchi      * unloaded underneath this taskq dispatch routine.
332*d14abf15SRobert Mustacchi      */
333*d14abf15SRobert Mustacchi 
334*d14abf15SRobert Mustacchi     {
335*d14abf15SRobert Mustacchi         struct fcoe_kcqe * pKcqe = &kcqe;
336*d14abf15SRobert Mustacchi         ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE));
337*d14abf15SRobert Mustacchi         pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev,
338*d14abf15SRobert Mustacchi                                        (void **)&pKcqe, 1);
339*d14abf15SRobert Mustacchi     }
340*d14abf15SRobert Mustacchi 
341*d14abf15SRobert Mustacchi     /* XXX release mutex or decrement reference count */
342*d14abf15SRobert Mustacchi }
343*d14abf15SRobert Mustacchi 
344*d14abf15SRobert Mustacchi 
345*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeOffloadConnWqe(um_device_t *      pUM,
346*d14abf15SRobert Mustacchi                                         union fcoe_kwqe ** kwqes)
347*d14abf15SRobert Mustacchi {
348*d14abf15SRobert Mustacchi     union fcoe_kwqe wqe[4];
349*d14abf15SRobert Mustacchi 
350*d14abf15SRobert Mustacchi     wqe[0] =*(kwqes[0]);
351*d14abf15SRobert Mustacchi     wqe[1] =*(kwqes[1]);
352*d14abf15SRobert Mustacchi     wqe[2] =*(kwqes[2]);
353*d14abf15SRobert Mustacchi     wqe[3] =*(kwqes[3]);
354*d14abf15SRobert Mustacchi 
355*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeOffloadConnWqeWork,
356*d14abf15SRobert Mustacchi                             wqe, sizeof(wqe));
357*d14abf15SRobert Mustacchi }
358*d14abf15SRobert Mustacchi 
359*d14abf15SRobert Mustacchi 
360*d14abf15SRobert Mustacchi static void BnxeFcoeEnableConnCqeWork(um_device_t * pUM,
361*d14abf15SRobert Mustacchi                                       void *        pData,
362*d14abf15SRobert Mustacchi                                       u32_t         dataLen)
363*d14abf15SRobert Mustacchi {
364*d14abf15SRobert Mustacchi     if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen))
365*d14abf15SRobert Mustacchi     {
366*d14abf15SRobert Mustacchi         pUM->fcoe.stats.enableConnCqeRxErr++;
367*d14abf15SRobert Mustacchi     }
368*d14abf15SRobert Mustacchi     else
369*d14abf15SRobert Mustacchi     {
370*d14abf15SRobert Mustacchi         pUM->fcoe.stats.enableConnCqeRx++;
371*d14abf15SRobert Mustacchi     }
372*d14abf15SRobert Mustacchi }
373*d14abf15SRobert Mustacchi 
374*d14abf15SRobert Mustacchi 
375*d14abf15SRobert Mustacchi boolean_t BnxeFcoeEnableConnCqe(um_device_t *      pUM,
376*d14abf15SRobert Mustacchi                                 BnxeFcoeState *    pFcoeState,
377*d14abf15SRobert Mustacchi                                 struct fcoe_kcqe * kcqe)
378*d14abf15SRobert Mustacchi {
379*d14abf15SRobert Mustacchi     struct fcoe_kcqe tmp_kcqe = {0};
380*d14abf15SRobert Mustacchi 
381*d14abf15SRobert Mustacchi     tmp_kcqe.op_code = FCOE_KCQE_OPCODE_ENABLE_CONN;
382*d14abf15SRobert Mustacchi 
383*d14abf15SRobert Mustacchi     tmp_kcqe.flags |=
384*d14abf15SRobert Mustacchi         (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
385*d14abf15SRobert Mustacchi 
386*d14abf15SRobert Mustacchi     tmp_kcqe.fcoe_conn_context_id = kcqe->fcoe_conn_context_id;
387*d14abf15SRobert Mustacchi     tmp_kcqe.fcoe_conn_id         = kcqe->fcoe_conn_id;
388*d14abf15SRobert Mustacchi 
389*d14abf15SRobert Mustacchi     tmp_kcqe.completion_status =
390*d14abf15SRobert Mustacchi         mm_cpu_to_le32((mm_le32_to_cpu(kcqe->completion_status) == 0) ?
391*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_SUCCESS :
392*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE);
393*d14abf15SRobert Mustacchi 
394*d14abf15SRobert Mustacchi     if (pFcoeState != NULL)
395*d14abf15SRobert Mustacchi     {
396*d14abf15SRobert Mustacchi         pFcoeState->lm_fcoe.hdr.status =
397*d14abf15SRobert Mustacchi             (mm_le32_to_cpu(kcqe->completion_status) == 0) ?
398*d14abf15SRobert Mustacchi                 STATE_STATUS_NORMAL :
399*d14abf15SRobert Mustacchi                 STATE_STATUS_INIT_OFFLOAD_ERR;
400*d14abf15SRobert Mustacchi     }
401*d14abf15SRobert Mustacchi 
402*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeEnableConnCqeWork,
403*d14abf15SRobert Mustacchi                             &tmp_kcqe, sizeof(tmp_kcqe));
404*d14abf15SRobert Mustacchi }
405*d14abf15SRobert Mustacchi 
406*d14abf15SRobert Mustacchi 
407*d14abf15SRobert Mustacchi static void BnxeFcoeEnableConnWqeWork(um_device_t * pUM,
408*d14abf15SRobert Mustacchi                                       void *        pData,
409*d14abf15SRobert Mustacchi                                       u32_t         dataLen)
410*d14abf15SRobert Mustacchi {
411*d14abf15SRobert Mustacchi     union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData;
412*d14abf15SRobert Mustacchi     struct fcoe_kcqe  kcqe = {0};
413*d14abf15SRobert Mustacchi     BnxeFcoeState *   pFcoeState;
414*d14abf15SRobert Mustacchi 
415*d14abf15SRobert Mustacchi     if (dataLen != sizeof(*kwqe))
416*d14abf15SRobert Mustacchi     {
417*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Invalid FCoE Enable Conn WQE");
418*d14abf15SRobert Mustacchi         pUM->fcoe.stats.enableConnWqeTxErr++;
419*d14abf15SRobert Mustacchi         return;
420*d14abf15SRobert Mustacchi     }
421*d14abf15SRobert Mustacchi 
422*d14abf15SRobert Mustacchi     pFcoeState =
423*d14abf15SRobert Mustacchi         lm_cid_cookie(&pUM->lm_dev,
424*d14abf15SRobert Mustacchi                       FCOE_CONNECTION_TYPE,
425*d14abf15SRobert Mustacchi                       SW_CID(mm_le32_to_cpu(kwqe->conn_enable_disable.context_id)));
426*d14abf15SRobert Mustacchi 
427*d14abf15SRobert Mustacchi     if (pFcoeState == NULL)
428*d14abf15SRobert Mustacchi     {
429*d14abf15SRobert Mustacchi         goto BnxeFcoeEnableConnWqeWork_error;
430*d14abf15SRobert Mustacchi     }
431*d14abf15SRobert Mustacchi 
432*d14abf15SRobert Mustacchi     if (lm_fc_post_enable_ramrod(&pUM->lm_dev,
433*d14abf15SRobert Mustacchi                                  &pFcoeState->lm_fcoe,
434*d14abf15SRobert Mustacchi                                  &kwqe->conn_enable_disable) !=
435*d14abf15SRobert Mustacchi         LM_STATUS_SUCCESS)
436*d14abf15SRobert Mustacchi     {
437*d14abf15SRobert Mustacchi         goto BnxeFcoeEnableConnWqeWork_error;
438*d14abf15SRobert Mustacchi     }
439*d14abf15SRobert Mustacchi 
440*d14abf15SRobert Mustacchi     pUM->fcoe.stats.enableConnWqeTx++;
441*d14abf15SRobert Mustacchi 
442*d14abf15SRobert Mustacchi     return;
443*d14abf15SRobert Mustacchi 
444*d14abf15SRobert Mustacchi BnxeFcoeEnableConnWqeWork_error:
445*d14abf15SRobert Mustacchi 
446*d14abf15SRobert Mustacchi     pUM->fcoe.stats.enableConnWqeTxErr++;
447*d14abf15SRobert Mustacchi 
448*d14abf15SRobert Mustacchi     BnxeLogWarn(pUM, "Failed to post FCoE Enable Conn WQE");
449*d14abf15SRobert Mustacchi 
450*d14abf15SRobert Mustacchi     kcqe.op_code = FCOE_KCQE_OPCODE_ENABLE_CONN;
451*d14abf15SRobert Mustacchi     kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
452*d14abf15SRobert Mustacchi     kcqe.fcoe_conn_context_id = kwqe->conn_enable_disable.context_id;
453*d14abf15SRobert Mustacchi     kcqe.completion_status = mm_cpu_to_le32(FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR);
454*d14abf15SRobert Mustacchi 
455*d14abf15SRobert Mustacchi     /* call here directly (for error case) */
456*d14abf15SRobert Mustacchi 
457*d14abf15SRobert Mustacchi     /* XXX
458*d14abf15SRobert Mustacchi      * Need to add a mutex or reference count to ensure that bnxef isn't
459*d14abf15SRobert Mustacchi      * unloaded underneath this taskq dispatch routine.
460*d14abf15SRobert Mustacchi      */
461*d14abf15SRobert Mustacchi 
462*d14abf15SRobert Mustacchi     {
463*d14abf15SRobert Mustacchi         struct fcoe_kcqe * pKcqe = &kcqe;
464*d14abf15SRobert Mustacchi         ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE));
465*d14abf15SRobert Mustacchi         pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev,
466*d14abf15SRobert Mustacchi                                        (void **)&pKcqe, 1);
467*d14abf15SRobert Mustacchi     }
468*d14abf15SRobert Mustacchi 
469*d14abf15SRobert Mustacchi     /* XXX release mutex or decrement reference count */
470*d14abf15SRobert Mustacchi }
471*d14abf15SRobert Mustacchi 
472*d14abf15SRobert Mustacchi 
473*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeEnableConnWqe(um_device_t *      pUM,
474*d14abf15SRobert Mustacchi                                        union fcoe_kwqe ** kwqes)
475*d14abf15SRobert Mustacchi {
476*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeEnableConnWqeWork,
477*d14abf15SRobert Mustacchi                             kwqes[0], sizeof(*(kwqes[0])));
478*d14abf15SRobert Mustacchi }
479*d14abf15SRobert Mustacchi 
480*d14abf15SRobert Mustacchi 
481*d14abf15SRobert Mustacchi static void BnxeFcoeDisableConnCqeWork(um_device_t * pUM,
482*d14abf15SRobert Mustacchi                                        void *        pData,
483*d14abf15SRobert Mustacchi                                        u32_t         dataLen)
484*d14abf15SRobert Mustacchi {
485*d14abf15SRobert Mustacchi     if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen))
486*d14abf15SRobert Mustacchi     {
487*d14abf15SRobert Mustacchi         pUM->fcoe.stats.disableConnCqeRxErr++;
488*d14abf15SRobert Mustacchi     }
489*d14abf15SRobert Mustacchi     else
490*d14abf15SRobert Mustacchi     {
491*d14abf15SRobert Mustacchi         pUM->fcoe.stats.disableConnCqeRx++;
492*d14abf15SRobert Mustacchi     }
493*d14abf15SRobert Mustacchi }
494*d14abf15SRobert Mustacchi 
495*d14abf15SRobert Mustacchi 
496*d14abf15SRobert Mustacchi boolean_t BnxeFcoeDisableConnCqe(um_device_t *      pUM,
497*d14abf15SRobert Mustacchi                                  BnxeFcoeState *    pFcoeState,
498*d14abf15SRobert Mustacchi                                  struct fcoe_kcqe * kcqe)
499*d14abf15SRobert Mustacchi {
500*d14abf15SRobert Mustacchi     struct fcoe_kcqe tmp_kcqe = {0};
501*d14abf15SRobert Mustacchi 
502*d14abf15SRobert Mustacchi     tmp_kcqe.op_code = FCOE_KCQE_OPCODE_DISABLE_CONN;
503*d14abf15SRobert Mustacchi 
504*d14abf15SRobert Mustacchi     tmp_kcqe.flags |=
505*d14abf15SRobert Mustacchi         (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
506*d14abf15SRobert Mustacchi 
507*d14abf15SRobert Mustacchi     tmp_kcqe.fcoe_conn_context_id = kcqe->fcoe_conn_context_id;
508*d14abf15SRobert Mustacchi     tmp_kcqe.fcoe_conn_id         = kcqe->fcoe_conn_id;
509*d14abf15SRobert Mustacchi 
510*d14abf15SRobert Mustacchi     tmp_kcqe.completion_status =
511*d14abf15SRobert Mustacchi         mm_cpu_to_le32((mm_le32_to_cpu(kcqe->completion_status) == 0) ?
512*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_SUCCESS :
513*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR);
514*d14abf15SRobert Mustacchi 
515*d14abf15SRobert Mustacchi     if (pFcoeState != NULL)
516*d14abf15SRobert Mustacchi     {
517*d14abf15SRobert Mustacchi         pFcoeState->lm_fcoe.hdr.status =
518*d14abf15SRobert Mustacchi             (mm_le32_to_cpu(kcqe->completion_status) == 0) ?
519*d14abf15SRobert Mustacchi                 STATE_STATUS_NORMAL :
520*d14abf15SRobert Mustacchi                 STATE_STATUS_INIT_OFFLOAD_ERR;
521*d14abf15SRobert Mustacchi     }
522*d14abf15SRobert Mustacchi 
523*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeDisableConnCqeWork,
524*d14abf15SRobert Mustacchi                             &tmp_kcqe, sizeof(tmp_kcqe));
525*d14abf15SRobert Mustacchi }
526*d14abf15SRobert Mustacchi 
527*d14abf15SRobert Mustacchi 
528*d14abf15SRobert Mustacchi static void BnxeFcoeDisableConnWqeWork(um_device_t * pUM,
529*d14abf15SRobert Mustacchi                                        void *        pData,
530*d14abf15SRobert Mustacchi                                        u32_t         dataLen)
531*d14abf15SRobert Mustacchi {
532*d14abf15SRobert Mustacchi     union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData;
533*d14abf15SRobert Mustacchi     struct fcoe_kcqe  kcqe = {0};
534*d14abf15SRobert Mustacchi     BnxeFcoeState *   pFcoeState;
535*d14abf15SRobert Mustacchi 
536*d14abf15SRobert Mustacchi     if (dataLen != sizeof(*kwqe))
537*d14abf15SRobert Mustacchi     {
538*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Invalid FCoE Disable Conn WQE");
539*d14abf15SRobert Mustacchi         pUM->fcoe.stats.disableConnWqeTxErr++;
540*d14abf15SRobert Mustacchi         return;
541*d14abf15SRobert Mustacchi     }
542*d14abf15SRobert Mustacchi 
543*d14abf15SRobert Mustacchi     pFcoeState =
544*d14abf15SRobert Mustacchi         lm_cid_cookie(&pUM->lm_dev,
545*d14abf15SRobert Mustacchi                       FCOE_CONNECTION_TYPE,
546*d14abf15SRobert Mustacchi                       SW_CID(mm_le32_to_cpu(kwqe->conn_enable_disable.context_id)));
547*d14abf15SRobert Mustacchi 
548*d14abf15SRobert Mustacchi     if (pFcoeState == NULL)
549*d14abf15SRobert Mustacchi     {
550*d14abf15SRobert Mustacchi         goto BnxeFcoeDisableConnWqeWork_error;
551*d14abf15SRobert Mustacchi     }
552*d14abf15SRobert Mustacchi 
553*d14abf15SRobert Mustacchi     if (lm_fc_post_disable_ramrod(&pUM->lm_dev,
554*d14abf15SRobert Mustacchi                                   &pFcoeState->lm_fcoe,
555*d14abf15SRobert Mustacchi                                   &kwqe->conn_enable_disable) !=
556*d14abf15SRobert Mustacchi         LM_STATUS_SUCCESS)
557*d14abf15SRobert Mustacchi     {
558*d14abf15SRobert Mustacchi         goto BnxeFcoeDisableConnWqeWork_error;
559*d14abf15SRobert Mustacchi     }
560*d14abf15SRobert Mustacchi 
561*d14abf15SRobert Mustacchi     pUM->fcoe.stats.disableConnWqeTx++;
562*d14abf15SRobert Mustacchi 
563*d14abf15SRobert Mustacchi     return;
564*d14abf15SRobert Mustacchi 
565*d14abf15SRobert Mustacchi BnxeFcoeDisableConnWqeWork_error:
566*d14abf15SRobert Mustacchi 
567*d14abf15SRobert Mustacchi     pUM->fcoe.stats.disableConnWqeTxErr++;
568*d14abf15SRobert Mustacchi 
569*d14abf15SRobert Mustacchi     BnxeLogWarn(pUM, "Failed to post FCoE Disable Conn WQE");
570*d14abf15SRobert Mustacchi 
571*d14abf15SRobert Mustacchi     kcqe.op_code = FCOE_KCQE_OPCODE_DISABLE_CONN;
572*d14abf15SRobert Mustacchi     kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
573*d14abf15SRobert Mustacchi     kcqe.fcoe_conn_context_id = kwqe->conn_enable_disable.context_id;
574*d14abf15SRobert Mustacchi     kcqe.completion_status = mm_cpu_to_le32(FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR);
575*d14abf15SRobert Mustacchi 
576*d14abf15SRobert Mustacchi     /* call here directly (for error case) */
577*d14abf15SRobert Mustacchi 
578*d14abf15SRobert Mustacchi     /* XXX
579*d14abf15SRobert Mustacchi      * Need to add a mutex or reference count to ensure that bnxef isn't
580*d14abf15SRobert Mustacchi      * unloaded underneath this taskq dispatch routine.
581*d14abf15SRobert Mustacchi      */
582*d14abf15SRobert Mustacchi 
583*d14abf15SRobert Mustacchi     {
584*d14abf15SRobert Mustacchi         struct fcoe_kcqe * pKcqe = &kcqe;
585*d14abf15SRobert Mustacchi         ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE));
586*d14abf15SRobert Mustacchi         pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev,
587*d14abf15SRobert Mustacchi                                        (void **)&pKcqe, 1);
588*d14abf15SRobert Mustacchi     }
589*d14abf15SRobert Mustacchi 
590*d14abf15SRobert Mustacchi     /* XXX release mutex or decrement reference count */
591*d14abf15SRobert Mustacchi }
592*d14abf15SRobert Mustacchi 
593*d14abf15SRobert Mustacchi 
594*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeDisableConnWqe(um_device_t *      pUM,
595*d14abf15SRobert Mustacchi                                        union fcoe_kwqe ** kwqes)
596*d14abf15SRobert Mustacchi {
597*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeDisableConnWqeWork,
598*d14abf15SRobert Mustacchi                             kwqes[0], sizeof(*(kwqes[0])));
599*d14abf15SRobert Mustacchi }
600*d14abf15SRobert Mustacchi 
601*d14abf15SRobert Mustacchi 
602*d14abf15SRobert Mustacchi static void BnxeFcoeDestroyConnCqeWork(um_device_t * pUM,
603*d14abf15SRobert Mustacchi                                        void *        pData,
604*d14abf15SRobert Mustacchi                                        u32_t         dataLen)
605*d14abf15SRobert Mustacchi {
606*d14abf15SRobert Mustacchi     struct fcoe_kcqe * kcqe = (struct fcoe_kcqe *)pData;
607*d14abf15SRobert Mustacchi     BnxeFcoeState *    pFcoeState;
608*d14abf15SRobert Mustacchi 
609*d14abf15SRobert Mustacchi     if (dataLen != (sizeof(*kcqe)))
610*d14abf15SRobert Mustacchi     {
611*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Invalid FCoE Destroy Conn CQE");
612*d14abf15SRobert Mustacchi         pUM->fcoe.stats.destroyConnCqeRxErr++;
613*d14abf15SRobert Mustacchi         return;
614*d14abf15SRobert Mustacchi     }
615*d14abf15SRobert Mustacchi 
616*d14abf15SRobert Mustacchi     pFcoeState =
617*d14abf15SRobert Mustacchi         lm_cid_cookie(&pUM->lm_dev,
618*d14abf15SRobert Mustacchi                       FCOE_CONNECTION_TYPE,
619*d14abf15SRobert Mustacchi                       SW_CID(mm_le32_to_cpu(kcqe->fcoe_conn_context_id)));
620*d14abf15SRobert Mustacchi 
621*d14abf15SRobert Mustacchi     BnxeFcoeFreeResc(pUM, pFcoeState);
622*d14abf15SRobert Mustacchi 
623*d14abf15SRobert Mustacchi     if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen))
624*d14abf15SRobert Mustacchi     {
625*d14abf15SRobert Mustacchi         pUM->fcoe.stats.destroyConnCqeRxErr++;
626*d14abf15SRobert Mustacchi     }
627*d14abf15SRobert Mustacchi     else
628*d14abf15SRobert Mustacchi     {
629*d14abf15SRobert Mustacchi         pUM->fcoe.stats.destroyConnCqeRx++;
630*d14abf15SRobert Mustacchi     }
631*d14abf15SRobert Mustacchi }
632*d14abf15SRobert Mustacchi 
633*d14abf15SRobert Mustacchi 
634*d14abf15SRobert Mustacchi boolean_t BnxeFcoeDestroyConnCqe(um_device_t *      pUM,
635*d14abf15SRobert Mustacchi                                  BnxeFcoeState *    pFcoeState,
636*d14abf15SRobert Mustacchi                                  struct fcoe_kcqe * kcqe)
637*d14abf15SRobert Mustacchi {
638*d14abf15SRobert Mustacchi     struct fcoe_kcqe tmp_kcqe = {0};
639*d14abf15SRobert Mustacchi 
640*d14abf15SRobert Mustacchi     tmp_kcqe.op_code = FCOE_KCQE_OPCODE_DESTROY_CONN;
641*d14abf15SRobert Mustacchi 
642*d14abf15SRobert Mustacchi     tmp_kcqe.flags |=
643*d14abf15SRobert Mustacchi         (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
644*d14abf15SRobert Mustacchi 
645*d14abf15SRobert Mustacchi     tmp_kcqe.fcoe_conn_context_id = kcqe->fcoe_conn_context_id;
646*d14abf15SRobert Mustacchi     tmp_kcqe.fcoe_conn_id         = kcqe->fcoe_conn_id;
647*d14abf15SRobert Mustacchi 
648*d14abf15SRobert Mustacchi     tmp_kcqe.completion_status =
649*d14abf15SRobert Mustacchi         mm_cpu_to_le32((mm_le32_to_cpu(kcqe->completion_status) == 0) ?
650*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_SUCCESS :
651*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR);
652*d14abf15SRobert Mustacchi 
653*d14abf15SRobert Mustacchi     if (pFcoeState != NULL)
654*d14abf15SRobert Mustacchi     {
655*d14abf15SRobert Mustacchi         pFcoeState->lm_fcoe.hdr.status =
656*d14abf15SRobert Mustacchi             (mm_le32_to_cpu(kcqe->completion_status) == 0) ?
657*d14abf15SRobert Mustacchi                 STATE_STATUS_NORMAL :
658*d14abf15SRobert Mustacchi                 STATE_STATUS_INIT_OFFLOAD_ERR;
659*d14abf15SRobert Mustacchi     }
660*d14abf15SRobert Mustacchi 
661*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeDestroyConnCqeWork,
662*d14abf15SRobert Mustacchi                             &tmp_kcqe, sizeof(tmp_kcqe));
663*d14abf15SRobert Mustacchi }
664*d14abf15SRobert Mustacchi 
665*d14abf15SRobert Mustacchi 
666*d14abf15SRobert Mustacchi static void BnxeFcoeDestroyConnWqeWork(um_device_t * pUM,
667*d14abf15SRobert Mustacchi                                        void *        pData,
668*d14abf15SRobert Mustacchi                                        u32_t         dataLen)
669*d14abf15SRobert Mustacchi {
670*d14abf15SRobert Mustacchi     union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData;
671*d14abf15SRobert Mustacchi     struct fcoe_kcqe  kcqe = {0};
672*d14abf15SRobert Mustacchi     BnxeFcoeState *   pFcoeState;
673*d14abf15SRobert Mustacchi 
674*d14abf15SRobert Mustacchi     if (dataLen != sizeof(*kwqe))
675*d14abf15SRobert Mustacchi     {
676*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Invalid FCoE Destroy Conn WQE");
677*d14abf15SRobert Mustacchi         pUM->fcoe.stats.destroyConnWqeTxErr++;
678*d14abf15SRobert Mustacchi         return;
679*d14abf15SRobert Mustacchi     }
680*d14abf15SRobert Mustacchi 
681*d14abf15SRobert Mustacchi     pFcoeState =
682*d14abf15SRobert Mustacchi         lm_cid_cookie(&pUM->lm_dev,
683*d14abf15SRobert Mustacchi                       FCOE_CONNECTION_TYPE,
684*d14abf15SRobert Mustacchi                       SW_CID(mm_le32_to_cpu(kwqe->conn_destroy.context_id)));
685*d14abf15SRobert Mustacchi 
686*d14abf15SRobert Mustacchi     if (pFcoeState == NULL)
687*d14abf15SRobert Mustacchi     {
688*d14abf15SRobert Mustacchi         goto BnxeFcoeDestroyConnWqeWork_error;
689*d14abf15SRobert Mustacchi     }
690*d14abf15SRobert Mustacchi 
691*d14abf15SRobert Mustacchi     if (lm_fc_post_terminate_ramrod(&pUM->lm_dev,
692*d14abf15SRobert Mustacchi                                     &pFcoeState->lm_fcoe) !=
693*d14abf15SRobert Mustacchi         LM_STATUS_SUCCESS)
694*d14abf15SRobert Mustacchi     {
695*d14abf15SRobert Mustacchi         goto BnxeFcoeDestroyConnWqeWork_error;
696*d14abf15SRobert Mustacchi     }
697*d14abf15SRobert Mustacchi 
698*d14abf15SRobert Mustacchi     pUM->fcoe.stats.destroyConnWqeTx++;
699*d14abf15SRobert Mustacchi 
700*d14abf15SRobert Mustacchi     return;
701*d14abf15SRobert Mustacchi 
702*d14abf15SRobert Mustacchi BnxeFcoeDestroyConnWqeWork_error:
703*d14abf15SRobert Mustacchi 
704*d14abf15SRobert Mustacchi     pUM->fcoe.stats.destroyConnWqeTxErr++;
705*d14abf15SRobert Mustacchi 
706*d14abf15SRobert Mustacchi     BnxeLogWarn(pUM, "Failed to post FCoE Destroy Conn WQE");
707*d14abf15SRobert Mustacchi 
708*d14abf15SRobert Mustacchi     kcqe.op_code = FCOE_KCQE_OPCODE_DESTROY_CONN;
709*d14abf15SRobert Mustacchi     kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
710*d14abf15SRobert Mustacchi     kcqe.fcoe_conn_context_id = kwqe->conn_destroy.context_id;
711*d14abf15SRobert Mustacchi     kcqe.fcoe_conn_id         = kwqe->conn_destroy.conn_id;
712*d14abf15SRobert Mustacchi     kcqe.completion_status = mm_cpu_to_le32(FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR);
713*d14abf15SRobert Mustacchi 
714*d14abf15SRobert Mustacchi     /* call here directly (for error case) */
715*d14abf15SRobert Mustacchi 
716*d14abf15SRobert Mustacchi     /* XXX
717*d14abf15SRobert Mustacchi      * Need to add a mutex or reference count to ensure that bnxef isn't
718*d14abf15SRobert Mustacchi      * unloaded underneath this taskq dispatch routine.
719*d14abf15SRobert Mustacchi      */
720*d14abf15SRobert Mustacchi 
721*d14abf15SRobert Mustacchi     {
722*d14abf15SRobert Mustacchi         struct fcoe_kcqe * pKcqe = &kcqe;
723*d14abf15SRobert Mustacchi         ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE));
724*d14abf15SRobert Mustacchi         pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev,
725*d14abf15SRobert Mustacchi                                        (void **)&pKcqe, 1);
726*d14abf15SRobert Mustacchi     }
727*d14abf15SRobert Mustacchi 
728*d14abf15SRobert Mustacchi     /* XXX release mutex or decrement reference count */
729*d14abf15SRobert Mustacchi }
730*d14abf15SRobert Mustacchi 
731*d14abf15SRobert Mustacchi 
732*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeDestroyConnWqe(um_device_t *      pUM,
733*d14abf15SRobert Mustacchi                                        union fcoe_kwqe ** kwqes)
734*d14abf15SRobert Mustacchi {
735*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeDestroyConnWqeWork,
736*d14abf15SRobert Mustacchi                             kwqes[0], sizeof(*(kwqes[0])));
737*d14abf15SRobert Mustacchi }
738*d14abf15SRobert Mustacchi 
739*d14abf15SRobert Mustacchi 
740*d14abf15SRobert Mustacchi static void BnxeFcoeDestroyCqeWork(um_device_t * pUM,
741*d14abf15SRobert Mustacchi                                    void *        pData,
742*d14abf15SRobert Mustacchi                                    u32_t         dataLen)
743*d14abf15SRobert Mustacchi {
744*d14abf15SRobert Mustacchi     if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen))
745*d14abf15SRobert Mustacchi     {
746*d14abf15SRobert Mustacchi         pUM->fcoe.stats.destroyCqeRxErr++;
747*d14abf15SRobert Mustacchi     }
748*d14abf15SRobert Mustacchi     else
749*d14abf15SRobert Mustacchi     {
750*d14abf15SRobert Mustacchi         pUM->fcoe.stats.destroyCqeRx++;
751*d14abf15SRobert Mustacchi     }
752*d14abf15SRobert Mustacchi }
753*d14abf15SRobert Mustacchi 
754*d14abf15SRobert Mustacchi 
755*d14abf15SRobert Mustacchi boolean_t BnxeFcoeDestroyCqe(um_device_t *      pUM,
756*d14abf15SRobert Mustacchi                              struct fcoe_kcqe * kcqe)
757*d14abf15SRobert Mustacchi {
758*d14abf15SRobert Mustacchi     struct fcoe_kcqe tmp_kcqe = {0};
759*d14abf15SRobert Mustacchi 
760*d14abf15SRobert Mustacchi     tmp_kcqe.op_code = FCOE_KCQE_OPCODE_DESTROY_FUNC;
761*d14abf15SRobert Mustacchi 
762*d14abf15SRobert Mustacchi     tmp_kcqe.flags |=
763*d14abf15SRobert Mustacchi         (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
764*d14abf15SRobert Mustacchi 
765*d14abf15SRobert Mustacchi     tmp_kcqe.completion_status =
766*d14abf15SRobert Mustacchi         mm_le32_to_cpu((mm_le32_to_cpu(kcqe->completion_status) == 0) ?
767*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_SUCCESS :
768*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR);
769*d14abf15SRobert Mustacchi 
770*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeDestroyCqeWork,
771*d14abf15SRobert Mustacchi                             &tmp_kcqe, sizeof(tmp_kcqe));
772*d14abf15SRobert Mustacchi }
773*d14abf15SRobert Mustacchi 
774*d14abf15SRobert Mustacchi 
775*d14abf15SRobert Mustacchi static void BnxeFcoeDestroyWqeWork(um_device_t * pUM,
776*d14abf15SRobert Mustacchi                                    void *        pData,
777*d14abf15SRobert Mustacchi                                    u32_t         dataLen)
778*d14abf15SRobert Mustacchi {
779*d14abf15SRobert Mustacchi     union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData;
780*d14abf15SRobert Mustacchi     struct fcoe_kcqe  kcqe = {0};
781*d14abf15SRobert Mustacchi     BnxeFcoeState *   pFcoeState;
782*d14abf15SRobert Mustacchi 
783*d14abf15SRobert Mustacchi     if (dataLen != sizeof(*kwqe))
784*d14abf15SRobert Mustacchi     {
785*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Invalid FCoE Destroy WQE");
786*d14abf15SRobert Mustacchi         pUM->fcoe.stats.destroyWqeTxErr++;
787*d14abf15SRobert Mustacchi         return;
788*d14abf15SRobert Mustacchi     }
789*d14abf15SRobert Mustacchi 
790*d14abf15SRobert Mustacchi     if (lm_fc_post_destroy_ramrod(&pUM->lm_dev) == LM_STATUS_SUCCESS)
791*d14abf15SRobert Mustacchi     {
792*d14abf15SRobert Mustacchi         pUM->fcoe.stats.destroyWqeTx++;
793*d14abf15SRobert Mustacchi         return;
794*d14abf15SRobert Mustacchi     }
795*d14abf15SRobert Mustacchi 
796*d14abf15SRobert Mustacchi     pUM->fcoe.stats.destroyWqeTxErr++;
797*d14abf15SRobert Mustacchi 
798*d14abf15SRobert Mustacchi     BnxeLogWarn(pUM, "Failed to post FCoE Destroy WQE");
799*d14abf15SRobert Mustacchi 
800*d14abf15SRobert Mustacchi     kcqe.op_code = FCOE_KCQE_OPCODE_DESTROY_FUNC;
801*d14abf15SRobert Mustacchi     kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
802*d14abf15SRobert Mustacchi     kcqe.completion_status = mm_cpu_to_le32(FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR);
803*d14abf15SRobert Mustacchi 
804*d14abf15SRobert Mustacchi     /* call here directly (for error case) */
805*d14abf15SRobert Mustacchi 
806*d14abf15SRobert Mustacchi     /* XXX
807*d14abf15SRobert Mustacchi      * Need to add a mutex or reference count to ensure that bnxef isn't
808*d14abf15SRobert Mustacchi      * unloaded underneath this taskq dispatch routine.
809*d14abf15SRobert Mustacchi      */
810*d14abf15SRobert Mustacchi 
811*d14abf15SRobert Mustacchi     {
812*d14abf15SRobert Mustacchi         struct fcoe_kcqe * pKcqe = &kcqe;
813*d14abf15SRobert Mustacchi         ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE));
814*d14abf15SRobert Mustacchi         pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev,
815*d14abf15SRobert Mustacchi                                        (void **)&pKcqe, 1);
816*d14abf15SRobert Mustacchi     }
817*d14abf15SRobert Mustacchi 
818*d14abf15SRobert Mustacchi     /* XXX release mutex or decrement reference count */
819*d14abf15SRobert Mustacchi }
820*d14abf15SRobert Mustacchi 
821*d14abf15SRobert Mustacchi 
822*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeDestroyWqe(um_device_t *      pUM,
823*d14abf15SRobert Mustacchi                                     union fcoe_kwqe ** kwqes)
824*d14abf15SRobert Mustacchi {
825*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeDestroyWqeWork,
826*d14abf15SRobert Mustacchi                             kwqes[0], sizeof(*(kwqes[0])));
827*d14abf15SRobert Mustacchi }
828*d14abf15SRobert Mustacchi 
829*d14abf15SRobert Mustacchi 
830*d14abf15SRobert Mustacchi static void BnxeFcoeStatCqeWork(um_device_t * pUM,
831*d14abf15SRobert Mustacchi                                 void *        pData,
832*d14abf15SRobert Mustacchi                                 u32_t         dataLen)
833*d14abf15SRobert Mustacchi {
834*d14abf15SRobert Mustacchi     if (!BnxeFcoeCqeIndicate(pUM, pData, dataLen))
835*d14abf15SRobert Mustacchi     {
836*d14abf15SRobert Mustacchi         pUM->fcoe.stats.statCqeRxErr++;
837*d14abf15SRobert Mustacchi     }
838*d14abf15SRobert Mustacchi     else
839*d14abf15SRobert Mustacchi     {
840*d14abf15SRobert Mustacchi         pUM->fcoe.stats.statCqeRx++;
841*d14abf15SRobert Mustacchi     }
842*d14abf15SRobert Mustacchi }
843*d14abf15SRobert Mustacchi 
844*d14abf15SRobert Mustacchi 
845*d14abf15SRobert Mustacchi boolean_t BnxeFcoeStatCqe(um_device_t *      pUM,
846*d14abf15SRobert Mustacchi                           struct fcoe_kcqe * kcqe)
847*d14abf15SRobert Mustacchi {
848*d14abf15SRobert Mustacchi     struct fcoe_kcqe tmp_kcqe = {0};
849*d14abf15SRobert Mustacchi 
850*d14abf15SRobert Mustacchi     tmp_kcqe.op_code = FCOE_KCQE_OPCODE_STAT_FUNC;
851*d14abf15SRobert Mustacchi 
852*d14abf15SRobert Mustacchi     tmp_kcqe.flags |=
853*d14abf15SRobert Mustacchi         (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
854*d14abf15SRobert Mustacchi 
855*d14abf15SRobert Mustacchi     tmp_kcqe.completion_status =
856*d14abf15SRobert Mustacchi         mm_cpu_to_le32((mm_le32_to_cpu(kcqe->completion_status) == 0) ?
857*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_SUCCESS :
858*d14abf15SRobert Mustacchi                            FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR);
859*d14abf15SRobert Mustacchi 
860*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeStatCqeWork,
861*d14abf15SRobert Mustacchi                             &tmp_kcqe, sizeof(tmp_kcqe));
862*d14abf15SRobert Mustacchi }
863*d14abf15SRobert Mustacchi 
864*d14abf15SRobert Mustacchi 
865*d14abf15SRobert Mustacchi static void BnxeFcoeStatWqeWork(um_device_t * pUM,
866*d14abf15SRobert Mustacchi                                 void *        pData,
867*d14abf15SRobert Mustacchi                                 u32_t         dataLen)
868*d14abf15SRobert Mustacchi {
869*d14abf15SRobert Mustacchi     union fcoe_kwqe * kwqe = (union fcoe_kwqe *)pData;
870*d14abf15SRobert Mustacchi     struct fcoe_kcqe  kcqe = {0};
871*d14abf15SRobert Mustacchi 
872*d14abf15SRobert Mustacchi     if (dataLen != sizeof(*kwqe))
873*d14abf15SRobert Mustacchi     {
874*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Invalid FCoE Stat WQE");
875*d14abf15SRobert Mustacchi         pUM->fcoe.stats.statWqeTxErr++;
876*d14abf15SRobert Mustacchi         return;
877*d14abf15SRobert Mustacchi     }
878*d14abf15SRobert Mustacchi 
879*d14abf15SRobert Mustacchi     if (lm_fc_post_stat_ramrod(&pUM->lm_dev,
880*d14abf15SRobert Mustacchi                                &kwqe->statistics) == LM_STATUS_SUCCESS)
881*d14abf15SRobert Mustacchi     {
882*d14abf15SRobert Mustacchi         pUM->fcoe.stats.statWqeTx++;
883*d14abf15SRobert Mustacchi         return;
884*d14abf15SRobert Mustacchi     }
885*d14abf15SRobert Mustacchi 
886*d14abf15SRobert Mustacchi     pUM->fcoe.stats.statWqeTxErr++;
887*d14abf15SRobert Mustacchi 
888*d14abf15SRobert Mustacchi     BnxeLogWarn(pUM, "Failed to post FCoE Stat WQE");
889*d14abf15SRobert Mustacchi 
890*d14abf15SRobert Mustacchi     kcqe.op_code = FCOE_KCQE_OPCODE_STAT_FUNC;
891*d14abf15SRobert Mustacchi     kcqe.flags |= (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
892*d14abf15SRobert Mustacchi     kcqe.completion_status = mm_cpu_to_le32(FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR);
893*d14abf15SRobert Mustacchi 
894*d14abf15SRobert Mustacchi     /* call here directly (for error case) */
895*d14abf15SRobert Mustacchi 
896*d14abf15SRobert Mustacchi     /* XXX
897*d14abf15SRobert Mustacchi      * Need to add a mutex or reference count to ensure that bnxef isn't
898*d14abf15SRobert Mustacchi      * unloaded underneath this taskq dispatch routine.
899*d14abf15SRobert Mustacchi      */
900*d14abf15SRobert Mustacchi 
901*d14abf15SRobert Mustacchi     {
902*d14abf15SRobert Mustacchi         struct fcoe_kcqe * pKcqe = &kcqe;
903*d14abf15SRobert Mustacchi         ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE));
904*d14abf15SRobert Mustacchi         pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev,
905*d14abf15SRobert Mustacchi                                        (void **)&pKcqe, 1);
906*d14abf15SRobert Mustacchi     }
907*d14abf15SRobert Mustacchi 
908*d14abf15SRobert Mustacchi     /* XXX release mutex or decrement reference count */
909*d14abf15SRobert Mustacchi }
910*d14abf15SRobert Mustacchi 
911*d14abf15SRobert Mustacchi 
912*d14abf15SRobert Mustacchi static boolean_t BnxeFcoeStatWqe(um_device_t *      pUM,
913*d14abf15SRobert Mustacchi                                  union fcoe_kwqe ** kwqes)
914*d14abf15SRobert Mustacchi {
915*d14abf15SRobert Mustacchi     return BnxeWorkQueueAdd(pUM, BnxeFcoeStatWqeWork,
916*d14abf15SRobert Mustacchi                             kwqes[0], sizeof(*(kwqes[0])));
917*d14abf15SRobert Mustacchi }
918*d14abf15SRobert Mustacchi 
919*d14abf15SRobert Mustacchi 
920*d14abf15SRobert Mustacchi #define KCQE_LIMIT 64
921*d14abf15SRobert Mustacchi 
922*d14abf15SRobert Mustacchi static void BnxeFcoeCompRequestCqeWork(um_device_t * pUM,
923*d14abf15SRobert Mustacchi                                        void *        pData,
924*d14abf15SRobert Mustacchi                                        u32_t         dataLen)
925*d14abf15SRobert Mustacchi {
926*d14abf15SRobert Mustacchi     struct fcoe_kcqe * kcqe_arr = (struct fcoe_kcqe *)pData;
927*d14abf15SRobert Mustacchi     struct fcoe_kcqe * kcqes[KCQE_LIMIT];
928*d14abf15SRobert Mustacchi     u32_t              num_kcqes;
929*d14abf15SRobert Mustacchi     int i;
930*d14abf15SRobert Mustacchi 
931*d14abf15SRobert Mustacchi     if ((dataLen % (sizeof(*kcqe_arr))) != 0)
932*d14abf15SRobert Mustacchi     {
933*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Invalid FCoE Comp Request CQE array");
934*d14abf15SRobert Mustacchi         pUM->fcoe.stats.compRequestCqeRxErr++;
935*d14abf15SRobert Mustacchi         return;
936*d14abf15SRobert Mustacchi     }
937*d14abf15SRobert Mustacchi 
938*d14abf15SRobert Mustacchi     num_kcqes = (dataLen / (sizeof(*kcqe_arr)));
939*d14abf15SRobert Mustacchi 
940*d14abf15SRobert Mustacchi     /* init the kcqe pointer array */
941*d14abf15SRobert Mustacchi 
942*d14abf15SRobert Mustacchi     for (i = 0; i < num_kcqes; i++)
943*d14abf15SRobert Mustacchi     {
944*d14abf15SRobert Mustacchi         kcqes[i] = &kcqe_arr[i];
945*d14abf15SRobert Mustacchi     }
946*d14abf15SRobert Mustacchi 
947*d14abf15SRobert Mustacchi     ASSERT(CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE));
948*d14abf15SRobert Mustacchi 
949*d14abf15SRobert Mustacchi     if (!pUM->fcoe.bind.cliIndicateCqes(pUM->fcoe.pDev,
950*d14abf15SRobert Mustacchi                                         (void **)kcqes,
951*d14abf15SRobert Mustacchi                                         num_kcqes))
952*d14abf15SRobert Mustacchi     {
953*d14abf15SRobert Mustacchi         pUM->fcoe.stats.compRequestCqeRxErr++;
954*d14abf15SRobert Mustacchi     }
955*d14abf15SRobert Mustacchi     else
956*d14abf15SRobert Mustacchi     {
957*d14abf15SRobert Mustacchi         pUM->fcoe.stats.compRequestCqeRx += num_kcqes;
958*d14abf15SRobert Mustacchi     }
959*d14abf15SRobert Mustacchi }
960*d14abf15SRobert Mustacchi 
961*d14abf15SRobert Mustacchi 
962*d14abf15SRobert Mustacchi boolean_t BnxeFcoeCompRequestCqe(um_device_t *      pUM,
963*d14abf15SRobert Mustacchi                                  struct fcoe_kcqe * kcqes,
964*d14abf15SRobert Mustacchi                                  u32_t              num_kcqes)
965*d14abf15SRobert Mustacchi {
966*d14abf15SRobert Mustacchi     u32_t kcqesIdx = 0;
967*d14abf15SRobert Mustacchi     u32_t kcqesLimit = 0;
968*d14abf15SRobert Mustacchi     u32_t numUp;
969*d14abf15SRobert Mustacchi 
970*d14abf15SRobert Mustacchi     /* Send up KCQE_LIMIT kcqes at a time... */
971*d14abf15SRobert Mustacchi 
972*d14abf15SRobert Mustacchi     while (kcqesIdx < num_kcqes)
973*d14abf15SRobert Mustacchi     {
974*d14abf15SRobert Mustacchi         if (num_kcqes - kcqesIdx > KCQE_LIMIT)
975*d14abf15SRobert Mustacchi         {
976*d14abf15SRobert Mustacchi             kcqesLimit += KCQE_LIMIT;
977*d14abf15SRobert Mustacchi         }
978*d14abf15SRobert Mustacchi         else
979*d14abf15SRobert Mustacchi         {
980*d14abf15SRobert Mustacchi             kcqesLimit = num_kcqes;
981*d14abf15SRobert Mustacchi         }
982*d14abf15SRobert Mustacchi 
983*d14abf15SRobert Mustacchi         numUp = (kcqesLimit % KCQE_LIMIT == 0) ? KCQE_LIMIT :
984*d14abf15SRobert Mustacchi                                                  (kcqesLimit % KCQE_LIMIT);
985*d14abf15SRobert Mustacchi 
986*d14abf15SRobert Mustacchi #if 0
987*d14abf15SRobert Mustacchi         if (!BnxeWorkQueueAdd(pUM, BnxeFcoeCompRequestCqeWork,
988*d14abf15SRobert Mustacchi                               kcqes + kcqesIdx,
989*d14abf15SRobert Mustacchi                               (sizeof(struct fcoe_kcqe) * numUp)))
990*d14abf15SRobert Mustacchi         {
991*d14abf15SRobert Mustacchi             return B_FALSE;
992*d14abf15SRobert Mustacchi         }
993*d14abf15SRobert Mustacchi #else
994*d14abf15SRobert Mustacchi         BnxeFcoeCompRequestCqeWork(pUM,
995*d14abf15SRobert Mustacchi                                    kcqes + kcqesIdx,
996*d14abf15SRobert Mustacchi                                    (sizeof(struct fcoe_kcqe) * numUp));
997*d14abf15SRobert Mustacchi #endif
998*d14abf15SRobert Mustacchi 
999*d14abf15SRobert Mustacchi         kcqesIdx += (kcqesLimit - kcqesIdx);
1000*d14abf15SRobert Mustacchi     }
1001*d14abf15SRobert Mustacchi 
1002*d14abf15SRobert Mustacchi     return B_TRUE;
1003*d14abf15SRobert Mustacchi }
1004*d14abf15SRobert Mustacchi 
1005*d14abf15SRobert Mustacchi 
1006*d14abf15SRobert Mustacchi boolean_t BnxeFcoePrvCtl(dev_info_t * pDev,
1007*d14abf15SRobert Mustacchi                          int          cmd,
1008*d14abf15SRobert Mustacchi                          void *       pData,
1009*d14abf15SRobert Mustacchi                          int          dataLen)
1010*d14abf15SRobert Mustacchi {
1011*d14abf15SRobert Mustacchi     um_device_t *  pUM = (um_device_t *)ddi_get_driver_private(pDev);
1012*d14abf15SRobert Mustacchi     BnxeFcoeInfo * pFcoeInfo;
1013*d14abf15SRobert Mustacchi     int rc, i;
1014*d14abf15SRobert Mustacchi 
1015*d14abf15SRobert Mustacchi     /* sanity check */
1016*d14abf15SRobert Mustacchi     if (pUM == NULL || pUM->pDev != pDev)
1017*d14abf15SRobert Mustacchi     {
1018*d14abf15SRobert Mustacchi         BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__);
1019*d14abf15SRobert Mustacchi         return B_FALSE;
1020*d14abf15SRobert Mustacchi     }
1021*d14abf15SRobert Mustacchi 
1022*d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "*** %s ***", __func__);
1023*d14abf15SRobert Mustacchi 
1024*d14abf15SRobert Mustacchi     VERIFY_FCOE_BINDING(pUM);
1025*d14abf15SRobert Mustacchi 
1026*d14abf15SRobert Mustacchi     switch (cmd)
1027*d14abf15SRobert Mustacchi     {
1028*d14abf15SRobert Mustacchi     case PRV_CTL_GET_MAC_ADDR:
1029*d14abf15SRobert Mustacchi 
1030*d14abf15SRobert Mustacchi         if (dataLen < ETHERNET_ADDRESS_SIZE)
1031*d14abf15SRobert Mustacchi         {
1032*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Invalid MAC Address buffer length for get (%d)",
1033*d14abf15SRobert Mustacchi                         dataLen);
1034*d14abf15SRobert Mustacchi             return B_FALSE;
1035*d14abf15SRobert Mustacchi         }
1036*d14abf15SRobert Mustacchi 
1037*d14abf15SRobert Mustacchi         if (!pData)
1038*d14abf15SRobert Mustacchi         {
1039*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "NULL MAC Address buffer for get");
1040*d14abf15SRobert Mustacchi             return B_FALSE;
1041*d14abf15SRobert Mustacchi         }
1042*d14abf15SRobert Mustacchi 
1043*d14abf15SRobert Mustacchi         COPY_ETH_ADDRESS(pUM->lm_dev.hw_info.fcoe_mac_addr, pData);
1044*d14abf15SRobert Mustacchi 
1045*d14abf15SRobert Mustacchi         return B_TRUE;
1046*d14abf15SRobert Mustacchi 
1047*d14abf15SRobert Mustacchi     case PRV_CTL_SET_MAC_ADDR:
1048*d14abf15SRobert Mustacchi 
1049*d14abf15SRobert Mustacchi         if (dataLen < ETHERNET_ADDRESS_SIZE)
1050*d14abf15SRobert Mustacchi         {
1051*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Invalid MAC Address length for set (%d)",
1052*d14abf15SRobert Mustacchi                         dataLen);
1053*d14abf15SRobert Mustacchi             return B_FALSE;
1054*d14abf15SRobert Mustacchi         }
1055*d14abf15SRobert Mustacchi 
1056*d14abf15SRobert Mustacchi         if (!pData)
1057*d14abf15SRobert Mustacchi         {
1058*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "NULL MAC Address buffer for set");
1059*d14abf15SRobert Mustacchi             return B_FALSE;
1060*d14abf15SRobert Mustacchi         }
1061*d14abf15SRobert Mustacchi 
1062*d14abf15SRobert Mustacchi         /* Validate MAC address */
1063*d14abf15SRobert Mustacchi         if (IS_ETH_MULTICAST(pData))
1064*d14abf15SRobert Mustacchi         {
1065*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Cannot program a mcast/bcast address as an MAC Address.");
1066*d14abf15SRobert Mustacchi             return B_FALSE;
1067*d14abf15SRobert Mustacchi         }
1068*d14abf15SRobert Mustacchi 
1069*d14abf15SRobert Mustacchi         BNXE_LOCK_ENTER_HWINIT(pUM);
1070*d14abf15SRobert Mustacchi 
1071*d14abf15SRobert Mustacchi         /* XXX wrong? (overwriting fcoe hw programmed address!) */
1072*d14abf15SRobert Mustacchi         COPY_ETH_ADDRESS(pData, pUM->lm_dev.hw_info.fcoe_mac_addr);
1073*d14abf15SRobert Mustacchi 
1074*d14abf15SRobert Mustacchi         rc = BnxeMacAddress(pUM, LM_CLI_IDX_FCOE, B_TRUE,
1075*d14abf15SRobert Mustacchi                             pUM->lm_dev.hw_info.fcoe_mac_addr);
1076*d14abf15SRobert Mustacchi 
1077*d14abf15SRobert Mustacchi         BNXE_LOCK_EXIT_HWINIT(pUM);
1078*d14abf15SRobert Mustacchi 
1079*d14abf15SRobert Mustacchi         return (rc < 0) ? B_FALSE : B_TRUE;
1080*d14abf15SRobert Mustacchi 
1081*d14abf15SRobert Mustacchi     case PRV_CTL_QUERY_PARAMS:
1082*d14abf15SRobert Mustacchi 
1083*d14abf15SRobert Mustacchi         if (dataLen != sizeof(BnxeFcoeInfo))
1084*d14abf15SRobert Mustacchi         {
1085*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Invalid query buffer for FCoE (%d)",
1086*d14abf15SRobert Mustacchi                         dataLen);
1087*d14abf15SRobert Mustacchi             return B_FALSE;
1088*d14abf15SRobert Mustacchi         }
1089*d14abf15SRobert Mustacchi 
1090*d14abf15SRobert Mustacchi         if (!pData)
1091*d14abf15SRobert Mustacchi         {
1092*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Invalid query buffer for FCoE");
1093*d14abf15SRobert Mustacchi             return B_FALSE;
1094*d14abf15SRobert Mustacchi         }
1095*d14abf15SRobert Mustacchi 
1096*d14abf15SRobert Mustacchi         pFcoeInfo = (BnxeFcoeInfo *)pData;
1097*d14abf15SRobert Mustacchi 
1098*d14abf15SRobert Mustacchi         pFcoeInfo->flags = 0;
1099*d14abf15SRobert Mustacchi 
1100*d14abf15SRobert Mustacchi         /*
1101*d14abf15SRobert Mustacchi          * Always set the FORCE_LOAD flags which tells bnxef to perform any
1102*d14abf15SRobert Mustacchi          * necessary delays needed when bringing up targets. This allows ample
1103*d14abf15SRobert Mustacchi          * time for bnxef to come up and finish for FCoE boot. If we don't
1104*d14abf15SRobert Mustacchi          * force a delay then there is a race condition and the kernel won't
1105*d14abf15SRobert Mustacchi          * find the root disk.
1106*d14abf15SRobert Mustacchi          */
1107*d14abf15SRobert Mustacchi         pFcoeInfo->flags |= FCOE_INFO_FLAG_FORCE_LOAD;
1108*d14abf15SRobert Mustacchi 
1109*d14abf15SRobert Mustacchi         switch (pUM->lm_dev.params.mf_mode)
1110*d14abf15SRobert Mustacchi         {
1111*d14abf15SRobert Mustacchi         case SINGLE_FUNCTION:
1112*d14abf15SRobert Mustacchi             pFcoeInfo->flags |= FCOE_INFO_FLAG_MF_MODE_SF;
1113*d14abf15SRobert Mustacchi             break;
1114*d14abf15SRobert Mustacchi         case MULTI_FUNCTION_SD:
1115*d14abf15SRobert Mustacchi             pFcoeInfo->flags |= FCOE_INFO_FLAG_MF_MODE_SD;
1116*d14abf15SRobert Mustacchi             break;
1117*d14abf15SRobert Mustacchi         case MULTI_FUNCTION_SI:
1118*d14abf15SRobert Mustacchi             pFcoeInfo->flags |= FCOE_INFO_FLAG_MF_MODE_SI;
1119*d14abf15SRobert Mustacchi             break;
1120*d14abf15SRobert Mustacchi         case MULTI_FUNCTION_AFEX:
1121*d14abf15SRobert Mustacchi             pFcoeInfo->flags |= FCOE_INFO_FLAG_MF_MODE_AFEX;
1122*d14abf15SRobert Mustacchi             break;
1123*d14abf15SRobert Mustacchi         default:
1124*d14abf15SRobert Mustacchi             break;
1125*d14abf15SRobert Mustacchi         }
1126*d14abf15SRobert Mustacchi 
1127*d14abf15SRobert Mustacchi         pFcoeInfo->max_fcoe_conn      = pUM->lm_dev.params.max_func_fcoe_cons;
1128*d14abf15SRobert Mustacchi         pFcoeInfo->max_fcoe_exchanges = pUM->lm_dev.params.max_fcoe_task;
1129*d14abf15SRobert Mustacchi 
1130*d14abf15SRobert Mustacchi         memcpy(&pFcoeInfo->wwn, &pUM->fcoe.wwn, sizeof(BnxeWwnInfo));
1131*d14abf15SRobert Mustacchi 
1132*d14abf15SRobert Mustacchi         return B_TRUE;
1133*d14abf15SRobert Mustacchi 
1134*d14abf15SRobert Mustacchi     case PRV_CTL_DISABLE_INTR:
1135*d14abf15SRobert Mustacchi 
1136*d14abf15SRobert Mustacchi         BnxeIntrIguSbDisable(pUM, FCOE_CID(&pUM->lm_dev), B_FALSE);
1137*d14abf15SRobert Mustacchi         return B_TRUE;
1138*d14abf15SRobert Mustacchi 
1139*d14abf15SRobert Mustacchi     case PRV_CTL_ENABLE_INTR:
1140*d14abf15SRobert Mustacchi 
1141*d14abf15SRobert Mustacchi         BnxeIntrIguSbEnable(pUM, FCOE_CID(&pUM->lm_dev), B_FALSE);
1142*d14abf15SRobert Mustacchi         return B_TRUE;
1143*d14abf15SRobert Mustacchi 
1144*d14abf15SRobert Mustacchi     case PRV_CTL_MBA_BOOT:
1145*d14abf15SRobert Mustacchi 
1146*d14abf15SRobert Mustacchi         if (dataLen != sizeof(boolean_t))
1147*d14abf15SRobert Mustacchi         {
1148*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Invalid MBA boot check buffer for FCoE (%d)",
1149*d14abf15SRobert Mustacchi                         dataLen);
1150*d14abf15SRobert Mustacchi             return B_FALSE;
1151*d14abf15SRobert Mustacchi         }
1152*d14abf15SRobert Mustacchi 
1153*d14abf15SRobert Mustacchi         if (!pData)
1154*d14abf15SRobert Mustacchi         {
1155*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Invalid MBA boot check buffer for FCoE");
1156*d14abf15SRobert Mustacchi             return B_FALSE;
1157*d14abf15SRobert Mustacchi         }
1158*d14abf15SRobert Mustacchi 
1159*d14abf15SRobert Mustacchi         *((boolean_t *)pData) =
1160*d14abf15SRobert Mustacchi             (pUM->iscsiInfo.signature != 0) ? B_TRUE : B_FALSE;
1161*d14abf15SRobert Mustacchi 
1162*d14abf15SRobert Mustacchi         return B_TRUE;
1163*d14abf15SRobert Mustacchi 
1164*d14abf15SRobert Mustacchi     case PRV_CTL_LINK_STATE:
1165*d14abf15SRobert Mustacchi 
1166*d14abf15SRobert Mustacchi         if (dataLen != sizeof(boolean_t))
1167*d14abf15SRobert Mustacchi         {
1168*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Invalid link state buffer for FCoE (%d)",
1169*d14abf15SRobert Mustacchi                         dataLen);
1170*d14abf15SRobert Mustacchi             return B_FALSE;
1171*d14abf15SRobert Mustacchi         }
1172*d14abf15SRobert Mustacchi 
1173*d14abf15SRobert Mustacchi         if (!pData)
1174*d14abf15SRobert Mustacchi         {
1175*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Invalid link state buffer for FCoE");
1176*d14abf15SRobert Mustacchi             return B_FALSE;
1177*d14abf15SRobert Mustacchi         }
1178*d14abf15SRobert Mustacchi 
1179*d14abf15SRobert Mustacchi         *((boolean_t *)pData) =
1180*d14abf15SRobert Mustacchi             (pUM->devParams.lastIndLink == LM_STATUS_LINK_ACTIVE) ?
1181*d14abf15SRobert Mustacchi                 B_TRUE : B_FALSE;
1182*d14abf15SRobert Mustacchi 
1183*d14abf15SRobert Mustacchi         return B_TRUE;
1184*d14abf15SRobert Mustacchi 
1185*d14abf15SRobert Mustacchi     case PRV_CTL_BOARD_TYPE:
1186*d14abf15SRobert Mustacchi 
1187*d14abf15SRobert Mustacchi         if (!pData || (dataLen <= 0))
1188*d14abf15SRobert Mustacchi         {
1189*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Invalid board type buffer for FCoE");
1190*d14abf15SRobert Mustacchi             return B_FALSE;
1191*d14abf15SRobert Mustacchi         }
1192*d14abf15SRobert Mustacchi 
1193*d14abf15SRobert Mustacchi         snprintf((char *)pData, dataLen, "%s", pUM->chipName);
1194*d14abf15SRobert Mustacchi 
1195*d14abf15SRobert Mustacchi         return B_TRUE;
1196*d14abf15SRobert Mustacchi 
1197*d14abf15SRobert Mustacchi     case PRV_CTL_BOARD_SERNUM:
1198*d14abf15SRobert Mustacchi 
1199*d14abf15SRobert Mustacchi         if (!pData || (dataLen <= 0))
1200*d14abf15SRobert Mustacchi         {
1201*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Invalid board serial number buffer for FCoE");
1202*d14abf15SRobert Mustacchi             return B_FALSE;
1203*d14abf15SRobert Mustacchi         }
1204*d14abf15SRobert Mustacchi 
1205*d14abf15SRobert Mustacchi         snprintf((char *)pData, dataLen,
1206*d14abf15SRobert Mustacchi                  "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
1207*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[0],
1208*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[1],
1209*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[2],
1210*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[3],
1211*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[4],
1212*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[5],
1213*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[6],
1214*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[7],
1215*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[8],
1216*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[9],
1217*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[10],
1218*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[11],
1219*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[12],
1220*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[13],
1221*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[14],
1222*d14abf15SRobert Mustacchi                  pUM->lm_dev.hw_info.board_num[15]);
1223*d14abf15SRobert Mustacchi 
1224*d14abf15SRobert Mustacchi         return B_TRUE;
1225*d14abf15SRobert Mustacchi 
1226*d14abf15SRobert Mustacchi     case PRV_CTL_BOOTCODE_VERSION:
1227*d14abf15SRobert Mustacchi 
1228*d14abf15SRobert Mustacchi         if (!pData || (dataLen <= 0))
1229*d14abf15SRobert Mustacchi         {
1230*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Invalid boot code version buffer for FCoE");
1231*d14abf15SRobert Mustacchi             return B_FALSE;
1232*d14abf15SRobert Mustacchi         }
1233*d14abf15SRobert Mustacchi 
1234*d14abf15SRobert Mustacchi         snprintf((char *)pData, dataLen, "%s", pUM->versionBC);
1235*d14abf15SRobert Mustacchi 
1236*d14abf15SRobert Mustacchi         return B_TRUE;
1237*d14abf15SRobert Mustacchi 
1238*d14abf15SRobert Mustacchi     case PRV_CTL_REPORT_FCOE_STATS:
1239*d14abf15SRobert Mustacchi 
1240*d14abf15SRobert Mustacchi         if (!pData ||
1241*d14abf15SRobert Mustacchi             (dataLen !=
1242*d14abf15SRobert Mustacchi              sizeof(pUM->lm_dev.vars.stats.stats_mirror.
1243*d14abf15SRobert Mustacchi                                      stats_drv.drv_info_to_mfw.fcoe_stats)))
1244*d14abf15SRobert Mustacchi         {
1245*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Invalid stats reporting buffer for FCoE");
1246*d14abf15SRobert Mustacchi             return B_FALSE;
1247*d14abf15SRobert Mustacchi         }
1248*d14abf15SRobert Mustacchi 
1249*d14abf15SRobert Mustacchi         memcpy(&pUM->lm_dev.vars.stats.stats_mirror.
1250*d14abf15SRobert Mustacchi                                 stats_drv.drv_info_to_mfw.fcoe_stats,
1251*d14abf15SRobert Mustacchi                (fcoe_stats_info_t *)pData,
1252*d14abf15SRobert Mustacchi                sizeof(fcoe_stats_info_t));
1253*d14abf15SRobert Mustacchi 
1254*d14abf15SRobert Mustacchi         return B_TRUE;
1255*d14abf15SRobert Mustacchi 
1256*d14abf15SRobert Mustacchi     case PRV_CTL_SET_CAPS:
1257*d14abf15SRobert Mustacchi 
1258*d14abf15SRobert Mustacchi         if (!pData || (dataLen != sizeof(struct fcoe_capabilities)))
1259*d14abf15SRobert Mustacchi         {
1260*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Invalid capabilities buffer for FCoE");
1261*d14abf15SRobert Mustacchi             return B_FALSE;
1262*d14abf15SRobert Mustacchi         }
1263*d14abf15SRobert Mustacchi 
1264*d14abf15SRobert Mustacchi         memcpy(&pUM->lm_dev.vars.stats.stats_mirror.stats_drv.
1265*d14abf15SRobert Mustacchi                                  drv_info_to_shmem.fcoe_capabilities,
1266*d14abf15SRobert Mustacchi                pData,
1267*d14abf15SRobert Mustacchi                sizeof(pUM->lm_dev.vars.stats.stats_mirror.stats_drv.
1268*d14abf15SRobert Mustacchi                                        drv_info_to_shmem.fcoe_capabilities));
1269*d14abf15SRobert Mustacchi 
1270*d14abf15SRobert Mustacchi         lm_ncsi_fcoe_cap_to_scratchpad(&pUM->lm_dev);
1271*d14abf15SRobert Mustacchi 
1272*d14abf15SRobert Mustacchi         return B_TRUE;
1273*d14abf15SRobert Mustacchi 
1274*d14abf15SRobert Mustacchi     default:
1275*d14abf15SRobert Mustacchi 
1276*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Unknown provider command %d", cmd);
1277*d14abf15SRobert Mustacchi         return B_FALSE;
1278*d14abf15SRobert Mustacchi     }
1279*d14abf15SRobert Mustacchi }
1280*d14abf15SRobert Mustacchi 
1281*d14abf15SRobert Mustacchi 
1282*d14abf15SRobert Mustacchi mblk_t * BnxeFcoePrvTx(dev_info_t * pDev,
1283*d14abf15SRobert Mustacchi                        mblk_t *     pMblk,
1284*d14abf15SRobert Mustacchi                        u32_t        flags,
1285*d14abf15SRobert Mustacchi                        u16_t        vlan_tag)
1286*d14abf15SRobert Mustacchi {
1287*d14abf15SRobert Mustacchi     um_device_t * pUM = (um_device_t *)ddi_get_driver_private(pDev);
1288*d14abf15SRobert Mustacchi     lm_device_t * pLM = &pUM->lm_dev;
1289*d14abf15SRobert Mustacchi     mblk_t *      pNextMblk = NULL;
1290*d14abf15SRobert Mustacchi     int           txCount = 0;
1291*d14abf15SRobert Mustacchi     int rc;
1292*d14abf15SRobert Mustacchi 
1293*d14abf15SRobert Mustacchi     /* sanity check */
1294*d14abf15SRobert Mustacchi     if (pUM == NULL || pUM->pDev != pDev)
1295*d14abf15SRobert Mustacchi     {
1296*d14abf15SRobert Mustacchi         BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__);
1297*d14abf15SRobert Mustacchi         return pMblk;
1298*d14abf15SRobert Mustacchi     }
1299*d14abf15SRobert Mustacchi 
1300*d14abf15SRobert Mustacchi     VERIFY_FCOE_BINDING(pUM);
1301*d14abf15SRobert Mustacchi 
1302*d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "*** %s ***", __func__);
1303*d14abf15SRobert Mustacchi 
1304*d14abf15SRobert Mustacchi     while (pMblk)
1305*d14abf15SRobert Mustacchi     {
1306*d14abf15SRobert Mustacchi         txCount++;
1307*d14abf15SRobert Mustacchi 
1308*d14abf15SRobert Mustacchi         pNextMblk = pMblk->b_next;
1309*d14abf15SRobert Mustacchi         pMblk->b_next = NULL;
1310*d14abf15SRobert Mustacchi 
1311*d14abf15SRobert Mustacchi         rc = BnxeTxSendMblk(pUM, FCOE_CID(pLM), pMblk, flags, vlan_tag);
1312*d14abf15SRobert Mustacchi 
1313*d14abf15SRobert Mustacchi         if (rc == BNXE_TX_GOODXMIT)
1314*d14abf15SRobert Mustacchi         {
1315*d14abf15SRobert Mustacchi             pMblk = pNextMblk;
1316*d14abf15SRobert Mustacchi             continue;
1317*d14abf15SRobert Mustacchi         }
1318*d14abf15SRobert Mustacchi         else if (rc == BNXE_TX_DEFERPKT)
1319*d14abf15SRobert Mustacchi         {
1320*d14abf15SRobert Mustacchi             pMblk = pNextMblk;
1321*d14abf15SRobert Mustacchi         }
1322*d14abf15SRobert Mustacchi         else
1323*d14abf15SRobert Mustacchi         {
1324*d14abf15SRobert Mustacchi             pMblk->b_next = pNextMblk;
1325*d14abf15SRobert Mustacchi         }
1326*d14abf15SRobert Mustacchi 
1327*d14abf15SRobert Mustacchi         break;
1328*d14abf15SRobert Mustacchi     }
1329*d14abf15SRobert Mustacchi 
1330*d14abf15SRobert Mustacchi     return pMblk;
1331*d14abf15SRobert Mustacchi }
1332*d14abf15SRobert Mustacchi 
1333*d14abf15SRobert Mustacchi 
1334*d14abf15SRobert Mustacchi boolean_t BnxeFcoePrvPoll(dev_info_t * pDev)
1335*d14abf15SRobert Mustacchi {
1336*d14abf15SRobert Mustacchi     um_device_t * pUM  = (um_device_t *)ddi_get_driver_private(pDev);
1337*d14abf15SRobert Mustacchi     RxQueue *     pRxQ = &pUM->rxq[FCOE_CID(&pUM->lm_dev)];
1338*d14abf15SRobert Mustacchi     u32_t         idx  = pRxQ->idx;
1339*d14abf15SRobert Mustacchi 
1340*d14abf15SRobert Mustacchi     /* sanity check */
1341*d14abf15SRobert Mustacchi     if (pUM == NULL || pUM->pDev != pDev)
1342*d14abf15SRobert Mustacchi     {
1343*d14abf15SRobert Mustacchi         BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__);
1344*d14abf15SRobert Mustacchi         return B_FALSE;
1345*d14abf15SRobert Mustacchi     }
1346*d14abf15SRobert Mustacchi 
1347*d14abf15SRobert Mustacchi     VERIFY_FCOE_BINDING(pUM);
1348*d14abf15SRobert Mustacchi 
1349*d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "*** %s ***", __func__);
1350*d14abf15SRobert Mustacchi 
1351*d14abf15SRobert Mustacchi     if (pRxQ->inPollMode == B_FALSE)
1352*d14abf15SRobert Mustacchi     {
1353*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Polling on FCoE ring %d when NOT in poll mode!", idx);
1354*d14abf15SRobert Mustacchi         return NULL;
1355*d14abf15SRobert Mustacchi     }
1356*d14abf15SRobert Mustacchi 
1357*d14abf15SRobert Mustacchi     pRxQ->pollCnt++;
1358*d14abf15SRobert Mustacchi 
1359*d14abf15SRobert Mustacchi     BnxePollRxRingFCOE(pUM);
1360*d14abf15SRobert Mustacchi 
1361*d14abf15SRobert Mustacchi     return B_TRUE;
1362*d14abf15SRobert Mustacchi }
1363*d14abf15SRobert Mustacchi 
1364*d14abf15SRobert Mustacchi 
1365*d14abf15SRobert Mustacchi boolean_t BnxeFcoePrvSendWqes(dev_info_t * pDev,
1366*d14abf15SRobert Mustacchi                               void *       wqes[],
1367*d14abf15SRobert Mustacchi                               int          wqeCnt)
1368*d14abf15SRobert Mustacchi {
1369*d14abf15SRobert Mustacchi     union fcoe_kwqe ** kwqes = (union fcoe_kwqe **)wqes;
1370*d14abf15SRobert Mustacchi     int                kwqeCnt = 0;
1371*d14abf15SRobert Mustacchi 
1372*d14abf15SRobert Mustacchi     um_device_t * pUM = (um_device_t *)ddi_get_driver_private(pDev);
1373*d14abf15SRobert Mustacchi 
1374*d14abf15SRobert Mustacchi     /* sanity check */
1375*d14abf15SRobert Mustacchi     if (pUM == NULL || pUM->pDev != pDev)
1376*d14abf15SRobert Mustacchi     {
1377*d14abf15SRobert Mustacchi         BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__);
1378*d14abf15SRobert Mustacchi         return B_FALSE;
1379*d14abf15SRobert Mustacchi     }
1380*d14abf15SRobert Mustacchi 
1381*d14abf15SRobert Mustacchi     VERIFY_FCOE_BINDING(pUM);
1382*d14abf15SRobert Mustacchi 
1383*d14abf15SRobert Mustacchi     if ((kwqes == NULL) || (kwqes[0] == NULL))
1384*d14abf15SRobert Mustacchi     {
1385*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Invalid WQE array");
1386*d14abf15SRobert Mustacchi         return B_FALSE;
1387*d14abf15SRobert Mustacchi     }
1388*d14abf15SRobert Mustacchi 
1389*d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "*** %s ***", __func__);
1390*d14abf15SRobert Mustacchi 
1391*d14abf15SRobert Mustacchi     while (kwqeCnt < wqeCnt)
1392*d14abf15SRobert Mustacchi     {
1393*d14abf15SRobert Mustacchi         switch (kwqes[kwqeCnt]->init1.hdr.op_code)
1394*d14abf15SRobert Mustacchi         {
1395*d14abf15SRobert Mustacchi         case FCOE_KWQE_OPCODE_INIT1:
1396*d14abf15SRobert Mustacchi 
1397*d14abf15SRobert Mustacchi             BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_INIT", __func__);
1398*d14abf15SRobert Mustacchi 
1399*d14abf15SRobert Mustacchi             if ((wqeCnt <= kwqeCnt + 2) ||
1400*d14abf15SRobert Mustacchi                 (kwqes[kwqeCnt + 1] == NULL) ||
1401*d14abf15SRobert Mustacchi                 (kwqes[kwqeCnt + 2] == NULL) ||
1402*d14abf15SRobert Mustacchi                 (kwqes[kwqeCnt + 1]->init2.hdr.op_code != FCOE_KWQE_OPCODE_INIT2) ||
1403*d14abf15SRobert Mustacchi                 (kwqes[kwqeCnt + 2]->init3.hdr.op_code != FCOE_KWQE_OPCODE_INIT3))
1404*d14abf15SRobert Mustacchi             {
1405*d14abf15SRobert Mustacchi                 BnxeLogWarn(pUM, "FCoE Init kwqes error");
1406*d14abf15SRobert Mustacchi                 pUM->fcoe.stats.initWqeTxErr++;
1407*d14abf15SRobert Mustacchi                 return B_FALSE;
1408*d14abf15SRobert Mustacchi             }
1409*d14abf15SRobert Mustacchi 
1410*d14abf15SRobert Mustacchi             if (!BnxeFcoeInitWqe(pUM, &kwqes[kwqeCnt]))
1411*d14abf15SRobert Mustacchi             {
1412*d14abf15SRobert Mustacchi                 BnxeLogWarn(pUM, "Failed to init FCoE Init WQE work");
1413*d14abf15SRobert Mustacchi                 return B_FALSE;
1414*d14abf15SRobert Mustacchi             }
1415*d14abf15SRobert Mustacchi 
1416*d14abf15SRobert Mustacchi             kwqeCnt += 3;
1417*d14abf15SRobert Mustacchi 
1418*d14abf15SRobert Mustacchi             break;
1419*d14abf15SRobert Mustacchi 
1420*d14abf15SRobert Mustacchi         case FCOE_KWQE_OPCODE_OFFLOAD_CONN1:
1421*d14abf15SRobert Mustacchi 
1422*d14abf15SRobert Mustacchi             BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_OFFLOAD_CONN1", __func__);
1423*d14abf15SRobert Mustacchi 
1424*d14abf15SRobert Mustacchi             if ((wqeCnt <= kwqeCnt + 3) ||
1425*d14abf15SRobert Mustacchi                 (kwqes[kwqeCnt + 1] == NULL) ||
1426*d14abf15SRobert Mustacchi                 (kwqes[kwqeCnt + 2] == NULL) ||
1427*d14abf15SRobert Mustacchi                 (kwqes[kwqeCnt + 3] == NULL) ||
1428*d14abf15SRobert Mustacchi                 (kwqes[kwqeCnt + 1]->conn_offload2.hdr.op_code != FCOE_KWQE_OPCODE_OFFLOAD_CONN2) ||
1429*d14abf15SRobert Mustacchi                 (kwqes[kwqeCnt + 2]->conn_offload3.hdr.op_code != FCOE_KWQE_OPCODE_OFFLOAD_CONN3) ||
1430*d14abf15SRobert Mustacchi                 (kwqes[kwqeCnt + 3]->conn_offload4.hdr.op_code != FCOE_KWQE_OPCODE_OFFLOAD_CONN4))
1431*d14abf15SRobert Mustacchi             {
1432*d14abf15SRobert Mustacchi                 BnxeLogWarn(pUM, "FCoE Offload Conn kwqes error");
1433*d14abf15SRobert Mustacchi                 pUM->fcoe.stats.offloadConnWqeTxErr++;
1434*d14abf15SRobert Mustacchi                 return B_FALSE;
1435*d14abf15SRobert Mustacchi             }
1436*d14abf15SRobert Mustacchi 
1437*d14abf15SRobert Mustacchi             if (!BnxeFcoeOffloadConnWqe(pUM, &kwqes[kwqeCnt]))
1438*d14abf15SRobert Mustacchi             {
1439*d14abf15SRobert Mustacchi                 BnxeLogWarn(pUM, "Failed to init FCoE Offload Conn WQE work");
1440*d14abf15SRobert Mustacchi                 return B_FALSE;
1441*d14abf15SRobert Mustacchi             }
1442*d14abf15SRobert Mustacchi 
1443*d14abf15SRobert Mustacchi             kwqeCnt += 4;
1444*d14abf15SRobert Mustacchi 
1445*d14abf15SRobert Mustacchi             break;
1446*d14abf15SRobert Mustacchi 
1447*d14abf15SRobert Mustacchi         case FCOE_KWQE_OPCODE_ENABLE_CONN:
1448*d14abf15SRobert Mustacchi 
1449*d14abf15SRobert Mustacchi             BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_ENABLE_CONN", __func__);
1450*d14abf15SRobert Mustacchi 
1451*d14abf15SRobert Mustacchi             if (!BnxeFcoeEnableConnWqe(pUM, &kwqes[kwqeCnt]))
1452*d14abf15SRobert Mustacchi             {
1453*d14abf15SRobert Mustacchi                 BnxeLogWarn(pUM, "Failed to init FCoE Enable Conn WQE work");
1454*d14abf15SRobert Mustacchi                 return B_FALSE;
1455*d14abf15SRobert Mustacchi             }
1456*d14abf15SRobert Mustacchi 
1457*d14abf15SRobert Mustacchi             kwqeCnt += 1;
1458*d14abf15SRobert Mustacchi 
1459*d14abf15SRobert Mustacchi             break;
1460*d14abf15SRobert Mustacchi 
1461*d14abf15SRobert Mustacchi         case FCOE_KWQE_OPCODE_DISABLE_CONN:
1462*d14abf15SRobert Mustacchi 
1463*d14abf15SRobert Mustacchi             BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_DISABLE_CONN", __func__);
1464*d14abf15SRobert Mustacchi 
1465*d14abf15SRobert Mustacchi             if (!BnxeFcoeDisableConnWqe(pUM, &kwqes[kwqeCnt]))
1466*d14abf15SRobert Mustacchi             {
1467*d14abf15SRobert Mustacchi                 BnxeLogWarn(pUM, "Failed to init FCoE Disable Conn WQE work");
1468*d14abf15SRobert Mustacchi                 return B_FALSE;
1469*d14abf15SRobert Mustacchi             }
1470*d14abf15SRobert Mustacchi 
1471*d14abf15SRobert Mustacchi             kwqeCnt += 1;
1472*d14abf15SRobert Mustacchi 
1473*d14abf15SRobert Mustacchi             break;
1474*d14abf15SRobert Mustacchi 
1475*d14abf15SRobert Mustacchi         case FCOE_KWQE_OPCODE_DESTROY_CONN:
1476*d14abf15SRobert Mustacchi 
1477*d14abf15SRobert Mustacchi             BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_DESTROY_CONN", __func__);
1478*d14abf15SRobert Mustacchi 
1479*d14abf15SRobert Mustacchi             if (!BnxeFcoeDestroyConnWqe(pUM, &kwqes[kwqeCnt]))
1480*d14abf15SRobert Mustacchi             {
1481*d14abf15SRobert Mustacchi                 BnxeLogWarn(pUM, "Failed to init FCoE Destroy Conn WQE work");
1482*d14abf15SRobert Mustacchi                 return B_FALSE;
1483*d14abf15SRobert Mustacchi             }
1484*d14abf15SRobert Mustacchi 
1485*d14abf15SRobert Mustacchi             kwqeCnt += 1;
1486*d14abf15SRobert Mustacchi 
1487*d14abf15SRobert Mustacchi             break;
1488*d14abf15SRobert Mustacchi 
1489*d14abf15SRobert Mustacchi         case FCOE_KWQE_OPCODE_DESTROY:
1490*d14abf15SRobert Mustacchi 
1491*d14abf15SRobert Mustacchi             BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_DESTROY", __func__);
1492*d14abf15SRobert Mustacchi 
1493*d14abf15SRobert Mustacchi             if (!BnxeFcoeDestroyWqe(pUM, &kwqes[kwqeCnt]))
1494*d14abf15SRobert Mustacchi             {
1495*d14abf15SRobert Mustacchi                 BnxeLogWarn(pUM, "Failed to init FCoE Destroy WQE work");
1496*d14abf15SRobert Mustacchi                 return B_FALSE;
1497*d14abf15SRobert Mustacchi             }
1498*d14abf15SRobert Mustacchi 
1499*d14abf15SRobert Mustacchi             kwqeCnt += 1;
1500*d14abf15SRobert Mustacchi 
1501*d14abf15SRobert Mustacchi             break;
1502*d14abf15SRobert Mustacchi 
1503*d14abf15SRobert Mustacchi         case FCOE_KWQE_OPCODE_STAT:
1504*d14abf15SRobert Mustacchi 
1505*d14abf15SRobert Mustacchi             BnxeLogDbg(pUM, "*** %s - FCOE_KWQE_OPCODE_STAT", __func__);
1506*d14abf15SRobert Mustacchi 
1507*d14abf15SRobert Mustacchi             if (!BnxeFcoeStatWqe(pUM, &kwqes[kwqeCnt]))
1508*d14abf15SRobert Mustacchi             {
1509*d14abf15SRobert Mustacchi                 BnxeLogWarn(pUM, "Failed to init FCoE Stat WQE work");
1510*d14abf15SRobert Mustacchi                 return B_FALSE;
1511*d14abf15SRobert Mustacchi             }
1512*d14abf15SRobert Mustacchi 
1513*d14abf15SRobert Mustacchi             kwqeCnt += 1;
1514*d14abf15SRobert Mustacchi 
1515*d14abf15SRobert Mustacchi             break;
1516*d14abf15SRobert Mustacchi 
1517*d14abf15SRobert Mustacchi         default:
1518*d14abf15SRobert Mustacchi 
1519*d14abf15SRobert Mustacchi             BnxeDbgBreakMsg(pUM, "Invalid KWQE opcode");
1520*d14abf15SRobert Mustacchi             return B_FALSE;
1521*d14abf15SRobert Mustacchi         }
1522*d14abf15SRobert Mustacchi     }
1523*d14abf15SRobert Mustacchi 
1524*d14abf15SRobert Mustacchi     return B_TRUE;
1525*d14abf15SRobert Mustacchi }
1526*d14abf15SRobert Mustacchi 
1527*d14abf15SRobert Mustacchi 
1528*d14abf15SRobert Mustacchi boolean_t BnxeFcoePrvMapMailboxq(dev_info_t *       pDev,
1529*d14abf15SRobert Mustacchi                                  u32_t              cid,
1530*d14abf15SRobert Mustacchi                                  void **            ppMap,
1531*d14abf15SRobert Mustacchi                                  ddi_acc_handle_t * pAccHandle)
1532*d14abf15SRobert Mustacchi {
1533*d14abf15SRobert Mustacchi     um_device_t * pUM = (um_device_t *)ddi_get_driver_private(pDev);
1534*d14abf15SRobert Mustacchi 
1535*d14abf15SRobert Mustacchi     /* sanity check */
1536*d14abf15SRobert Mustacchi     if (pUM == NULL || pUM->pDev != pDev)
1537*d14abf15SRobert Mustacchi     {
1538*d14abf15SRobert Mustacchi         BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__);
1539*d14abf15SRobert Mustacchi         return B_FALSE;
1540*d14abf15SRobert Mustacchi     }
1541*d14abf15SRobert Mustacchi 
1542*d14abf15SRobert Mustacchi     VERIFY_FCOE_BINDING(pUM);
1543*d14abf15SRobert Mustacchi 
1544*d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "*** %s ***", __func__);
1545*d14abf15SRobert Mustacchi 
1546*d14abf15SRobert Mustacchi     /* get the right offset from the mapped bar */
1547*d14abf15SRobert Mustacchi 
1548*d14abf15SRobert Mustacchi     *ppMap = (void *)((u8_t *)pUM->lm_dev.context_info->array[SW_CID(cid)].cid_resc.mapped_cid_bar_addr + DPM_TRIGER_TYPE);
1549*d14abf15SRobert Mustacchi     *pAccHandle = pUM->lm_dev.context_info->array[SW_CID(cid)].cid_resc.reg_handle;
1550*d14abf15SRobert Mustacchi 
1551*d14abf15SRobert Mustacchi     if (!(*ppMap) || !(*pAccHandle))
1552*d14abf15SRobert Mustacchi     {
1553*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Cannot map mailboxq base address for FCoE");
1554*d14abf15SRobert Mustacchi         return B_FALSE;
1555*d14abf15SRobert Mustacchi     }
1556*d14abf15SRobert Mustacchi 
1557*d14abf15SRobert Mustacchi     return B_TRUE;
1558*d14abf15SRobert Mustacchi }
1559*d14abf15SRobert Mustacchi 
1560*d14abf15SRobert Mustacchi 
1561*d14abf15SRobert Mustacchi boolean_t BnxeFcoePrvUnmapMailboxq(dev_info_t *     pDev,
1562*d14abf15SRobert Mustacchi                                    u32_t            cid,
1563*d14abf15SRobert Mustacchi                                    void *           pMap,
1564*d14abf15SRobert Mustacchi                                    ddi_acc_handle_t accHandle)
1565*d14abf15SRobert Mustacchi {
1566*d14abf15SRobert Mustacchi     um_device_t *    pUM = (um_device_t *)ddi_get_driver_private(pDev);
1567*d14abf15SRobert Mustacchi     void *           pTmp;
1568*d14abf15SRobert Mustacchi     ddi_acc_handle_t tmpAcc;
1569*d14abf15SRobert Mustacchi 
1570*d14abf15SRobert Mustacchi     /* sanity check */
1571*d14abf15SRobert Mustacchi     if (pUM == NULL || pUM->pDev != pDev)
1572*d14abf15SRobert Mustacchi     {
1573*d14abf15SRobert Mustacchi         BnxeLogWarn(NULL, "%s: dev_info_t match failed", __func__);
1574*d14abf15SRobert Mustacchi         return B_FALSE;
1575*d14abf15SRobert Mustacchi     }
1576*d14abf15SRobert Mustacchi 
1577*d14abf15SRobert Mustacchi     VERIFY_FCOE_BINDING(pUM);
1578*d14abf15SRobert Mustacchi 
1579*d14abf15SRobert Mustacchi     BnxeLogDbg(pUM, "*** %s ***", __func__);
1580*d14abf15SRobert Mustacchi 
1581*d14abf15SRobert Mustacchi     /* verify the mapped bar address */
1582*d14abf15SRobert Mustacchi     pTmp = (void *)((u8_t *)pUM->lm_dev.context_info->array[SW_CID(cid)].cid_resc.mapped_cid_bar_addr + DPM_TRIGER_TYPE);
1583*d14abf15SRobert Mustacchi     tmpAcc = pUM->lm_dev.context_info->array[SW_CID(cid)].cid_resc.reg_handle;
1584*d14abf15SRobert Mustacchi 
1585*d14abf15SRobert Mustacchi     if ((pMap != pTmp) || (accHandle != tmpAcc))
1586*d14abf15SRobert Mustacchi     {
1587*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Invalid map info for FCoE (%p)", pMap);
1588*d14abf15SRobert Mustacchi         return B_FALSE;
1589*d14abf15SRobert Mustacchi     }
1590*d14abf15SRobert Mustacchi 
1591*d14abf15SRobert Mustacchi     return B_TRUE;
1592*d14abf15SRobert Mustacchi }
1593*d14abf15SRobert Mustacchi 
1594*d14abf15SRobert Mustacchi 
1595*d14abf15SRobert Mustacchi int BnxeFcoeInit(um_device_t * pUM)
1596*d14abf15SRobert Mustacchi {
1597*d14abf15SRobert Mustacchi     char * pCompat[2] = { BNXEF_NAME, NULL };
1598*d14abf15SRobert Mustacchi     char   name[256];
1599*d14abf15SRobert Mustacchi     int    rc;
1600*d14abf15SRobert Mustacchi 
1601*d14abf15SRobert Mustacchi     BnxeLogInfo(pUM, "Starting FCoE");
1602*d14abf15SRobert Mustacchi 
1603*d14abf15SRobert Mustacchi     if (!BNXE_FCOE(pUM))
1604*d14abf15SRobert Mustacchi     {
1605*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "FCoE not supported on this device");
1606*d14abf15SRobert Mustacchi         return ENOTSUP;
1607*d14abf15SRobert Mustacchi     }
1608*d14abf15SRobert Mustacchi 
1609*d14abf15SRobert Mustacchi     //if (CLIENT_DEVI(pUM, LM_CLI_IDX_FCOE))
1610*d14abf15SRobert Mustacchi     if (pUM->fcoe.pDev)
1611*d14abf15SRobert Mustacchi     {
1612*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "FCoE child node already initialized");
1613*d14abf15SRobert Mustacchi         return EEXIST;
1614*d14abf15SRobert Mustacchi     }
1615*d14abf15SRobert Mustacchi 
1616*d14abf15SRobert Mustacchi     if (ndi_devi_alloc(pUM->pDev,
1617*d14abf15SRobert Mustacchi                        BNXEF_NAME,
1618*d14abf15SRobert Mustacchi                        DEVI_PSEUDO_NODEID,
1619*d14abf15SRobert Mustacchi                        &pUM->fcoe.pDev) != NDI_SUCCESS)
1620*d14abf15SRobert Mustacchi     {
1621*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to allocate a child node for FCoE");
1622*d14abf15SRobert Mustacchi         pUM->fcoe.pDev = NULL;
1623*d14abf15SRobert Mustacchi         return ENOMEM;
1624*d14abf15SRobert Mustacchi     }
1625*d14abf15SRobert Mustacchi 
1626*d14abf15SRobert Mustacchi     if (ndi_prop_update_string_array(DDI_DEV_T_NONE,
1627*d14abf15SRobert Mustacchi                                      pUM->fcoe.pDev,
1628*d14abf15SRobert Mustacchi                                      "name",
1629*d14abf15SRobert Mustacchi                                      pCompat,
1630*d14abf15SRobert Mustacchi                                      1) != DDI_PROP_SUCCESS)
1631*d14abf15SRobert Mustacchi     {
1632*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to set the name string for FCoE");
1633*d14abf15SRobert Mustacchi         /* XXX see other call to ndi_devi_free below */
1634*d14abf15SRobert Mustacchi         //ndi_devi_free(pUM->fcoe.pDev);
1635*d14abf15SRobert Mustacchi         pUM->fcoe.pDev = NULL;
1636*d14abf15SRobert Mustacchi         return ENOENT;
1637*d14abf15SRobert Mustacchi     }
1638*d14abf15SRobert Mustacchi 
1639*d14abf15SRobert Mustacchi     CLIENT_DEVI_SET(pUM, LM_CLI_IDX_FCOE);
1640*d14abf15SRobert Mustacchi 
1641*d14abf15SRobert Mustacchi     /*
1642*d14abf15SRobert Mustacchi      * XXX If/when supporting custom wwn's then prime them
1643*d14abf15SRobert Mustacchi      * here in so they will be passed to bnxef during BINDING.
1644*d14abf15SRobert Mustacchi      * Ideally custom wwn's will be set via the driver .conf
1645*d14abf15SRobert Mustacchi      * file and via a private driver property.
1646*d14abf15SRobert Mustacchi      */
1647*d14abf15SRobert Mustacchi     memset(&pUM->fcoe.wwn, 0, sizeof(BnxeWwnInfo));
1648*d14abf15SRobert Mustacchi     pUM->fcoe.wwn.fcp_pwwn_provided = B_TRUE;
1649*d14abf15SRobert Mustacchi     memcpy(pUM->fcoe.wwn.fcp_pwwn, pUM->lm_dev.hw_info.fcoe_wwn_port_name,
1650*d14abf15SRobert Mustacchi            BNXE_FCOE_WWN_SIZE);
1651*d14abf15SRobert Mustacchi     pUM->fcoe.wwn.fcp_nwwn_provided = B_TRUE;
1652*d14abf15SRobert Mustacchi     memcpy(pUM->fcoe.wwn.fcp_nwwn, pUM->lm_dev.hw_info.fcoe_wwn_node_name,
1653*d14abf15SRobert Mustacchi            BNXE_FCOE_WWN_SIZE);
1654*d14abf15SRobert Mustacchi 
1655*d14abf15SRobert Mustacchi     BnxeLogInfo(pUM, "Created the FCoE child node %s@%s",
1656*d14abf15SRobert Mustacchi                 BNXEF_NAME, ddi_get_name_addr(pUM->pDev));
1657*d14abf15SRobert Mustacchi 
1658*d14abf15SRobert Mustacchi     if ((rc = ndi_devi_online(pUM->fcoe.pDev, NDI_ONLINE_ATTACH)) !=
1659*d14abf15SRobert Mustacchi         NDI_SUCCESS)
1660*d14abf15SRobert Mustacchi     {
1661*d14abf15SRobert Mustacchi         /* XXX
1662*d14abf15SRobert Mustacchi          * ndi_devi_free will cause a panic. Don't know why and we've
1663*d14abf15SRobert Mustacchi          * verified that Sun's FCoE driver does not free it either.
1664*d14abf15SRobert Mustacchi          */
1665*d14abf15SRobert Mustacchi         //ndi_devi_free(pUM->fcoe.pDev);
1666*d14abf15SRobert Mustacchi         CLIENT_DEVI_RESET(pUM, LM_CLI_IDX_FCOE);
1667*d14abf15SRobert Mustacchi         pUM->fcoe.pDev = NULL;
1668*d14abf15SRobert Mustacchi         BnxeLogInfo(pUM, "Unable to bind the QLogic FCoE driver (%d)", rc);
1669*d14abf15SRobert Mustacchi         return ECHILD;
1670*d14abf15SRobert Mustacchi     }
1671*d14abf15SRobert Mustacchi 
1672*d14abf15SRobert Mustacchi #if 0
1673*d14abf15SRobert Mustacchi     /* bring bnxef online and attach it */
1674*d14abf15SRobert Mustacchi     if (ndi_devi_bind_driver(pUM->fcoe.pDev, 0) != NDI_SUCCESS)
1675*d14abf15SRobert Mustacchi     {
1676*d14abf15SRobert Mustacchi         BnxeLogInfo(pUM, "Unable to bind the QLogic FCoE driver");
1677*d14abf15SRobert Mustacchi     }
1678*d14abf15SRobert Mustacchi #endif
1679*d14abf15SRobert Mustacchi 
1680*d14abf15SRobert Mustacchi     return 0;
1681*d14abf15SRobert Mustacchi }
1682*d14abf15SRobert Mustacchi 
1683*d14abf15SRobert Mustacchi 
1684*d14abf15SRobert Mustacchi int BnxeFcoeFini(um_device_t * pUM)
1685*d14abf15SRobert Mustacchi {
1686*d14abf15SRobert Mustacchi     int rc = 0;
1687*d14abf15SRobert Mustacchi     int nullDev = B_FALSE; /* false = wait for bnxef UNBIND */
1688*d14abf15SRobert Mustacchi 
1689*d14abf15SRobert Mustacchi     BnxeLogInfo(pUM, "Stopping FCoE");
1690*d14abf15SRobert Mustacchi 
1691*d14abf15SRobert Mustacchi     if (!BNXE_FCOE(pUM))
1692*d14abf15SRobert Mustacchi     {
1693*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "FCoE not supported on this device");
1694*d14abf15SRobert Mustacchi         return ENOTSUP;
1695*d14abf15SRobert Mustacchi     }
1696*d14abf15SRobert Mustacchi 
1697*d14abf15SRobert Mustacchi     if (CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE))
1698*d14abf15SRobert Mustacchi     {
1699*d14abf15SRobert Mustacchi         if (pUM->fcoe.pDev == NULL)
1700*d14abf15SRobert Mustacchi         {
1701*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "FCoE Client bound and pDev is NULL, FINI failed! %s@%s",
1702*d14abf15SRobert Mustacchi                         BNXEF_NAME, ddi_get_name_addr(pUM->pDev));
1703*d14abf15SRobert Mustacchi             return ENOENT;
1704*d14abf15SRobert Mustacchi         }
1705*d14abf15SRobert Mustacchi         else if (pUM->fcoe.bind.cliCtl == NULL)
1706*d14abf15SRobert Mustacchi         {
1707*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "FCoE Client bound and cliCtl is NULL, FINI failed! %s@%s",
1708*d14abf15SRobert Mustacchi                         BNXEF_NAME, ddi_get_name_addr(pUM->pDev));
1709*d14abf15SRobert Mustacchi             return ENOENT;
1710*d14abf15SRobert Mustacchi         }
1711*d14abf15SRobert Mustacchi         else if (pUM->fcoe.bind.cliCtl(pUM->fcoe.pDev,
1712*d14abf15SRobert Mustacchi                                        CLI_CTL_UNLOAD,
1713*d14abf15SRobert Mustacchi                                        NULL,
1714*d14abf15SRobert Mustacchi                                        0) == B_FALSE)
1715*d14abf15SRobert Mustacchi         {
1716*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "FCoE Client bound and UNLOAD failed! %s@%s",
1717*d14abf15SRobert Mustacchi                         BNXEF_NAME, ddi_get_name_addr(pUM->pDev));
1718*d14abf15SRobert Mustacchi             return ENOMSG; /* no graceful unload with bnxef */
1719*d14abf15SRobert Mustacchi         }
1720*d14abf15SRobert Mustacchi     }
1721*d14abf15SRobert Mustacchi     else
1722*d14abf15SRobert Mustacchi     {
1723*d14abf15SRobert Mustacchi         rc = ENODEV;
1724*d14abf15SRobert Mustacchi         nullDev = B_TRUE;
1725*d14abf15SRobert Mustacchi     }
1726*d14abf15SRobert Mustacchi 
1727*d14abf15SRobert Mustacchi     /*
1728*d14abf15SRobert Mustacchi      * There are times when delete-port doesn't fully work and bnxef is unable
1729*d14abf15SRobert Mustacchi      * to detach and never calls UNBIND.  So here we'll just make sure that
1730*d14abf15SRobert Mustacchi      * the child dev node is not NULL which semi-gaurantees the UNBIND hasn't
1731*d14abf15SRobert Mustacchi      * been called yet.  Multiple offline calls will hopefully kick bnxef...
1732*d14abf15SRobert Mustacchi      */
1733*d14abf15SRobert Mustacchi     //if (CLIENT_DEVI(pUM, LM_CLI_IDX_FCOE))
1734*d14abf15SRobert Mustacchi     if (pUM->fcoe.pDev)
1735*d14abf15SRobert Mustacchi     {
1736*d14abf15SRobert Mustacchi         CLIENT_DEVI_RESET(pUM, LM_CLI_IDX_FCOE);
1737*d14abf15SRobert Mustacchi 
1738*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Bringing down QLogic FCoE driver %s@%s",
1739*d14abf15SRobert Mustacchi                     BNXEF_NAME, ddi_get_name_addr(pUM->pDev));
1740*d14abf15SRobert Mustacchi 
1741*d14abf15SRobert Mustacchi #if 1
1742*d14abf15SRobert Mustacchi         if (ndi_devi_offline(pUM->fcoe.pDev, NDI_DEVI_REMOVE) != NDI_SUCCESS)
1743*d14abf15SRobert Mustacchi         {
1744*d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Failed to bring the QLogic FCoE driver offline %s@%s",
1745*d14abf15SRobert Mustacchi                         BNXEF_NAME, ddi_get_name_addr(pUM->pDev));
1746*d14abf15SRobert Mustacchi             return EBUSY;
1747*d14abf15SRobert Mustacchi         }
1748*d14abf15SRobert Mustacchi #else
1749*d14abf15SRobert Mustacchi         ndi_devi_offline(pUM->fcoe.pDev, NDI_DEVI_REMOVE);
1750*d14abf15SRobert Mustacchi         if (nullDev) pUM->fcoe.pDev = NULL;
1751*d14abf15SRobert Mustacchi #endif
1752*d14abf15SRobert Mustacchi 
1753*d14abf15SRobert Mustacchi         memset(&pUM->fcoe.wwn, 0, sizeof(BnxeWwnInfo));
1754*d14abf15SRobert Mustacchi 
1755*d14abf15SRobert Mustacchi         BnxeLogInfo(pUM, "Destroyed the FCoE child node %s@%s",
1756*d14abf15SRobert Mustacchi                     BNXEF_NAME, ddi_get_name_addr(pUM->pDev));
1757*d14abf15SRobert Mustacchi     }
1758*d14abf15SRobert Mustacchi 
1759*d14abf15SRobert Mustacchi     return rc;
1760*d14abf15SRobert Mustacchi }
1761*d14abf15SRobert Mustacchi 
1762*d14abf15SRobert Mustacchi 
1763*d14abf15SRobert Mustacchi void BnxeFcoeStartStop(um_device_t * pUM)
1764*d14abf15SRobert Mustacchi {
1765*d14abf15SRobert Mustacchi     int rc;
1766*d14abf15SRobert Mustacchi 
1767*d14abf15SRobert Mustacchi     if (!BNXE_FCOE(pUM))
1768*d14abf15SRobert Mustacchi     {
1769*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "FCoE is not supported on this device");
1770*d14abf15SRobert Mustacchi         return;
1771*d14abf15SRobert Mustacchi     }
1772*d14abf15SRobert Mustacchi 
1773*d14abf15SRobert Mustacchi     if (pUM->devParams.fcoeEnable)
1774*d14abf15SRobert Mustacchi     {
1775*d14abf15SRobert Mustacchi         BnxeFcoeInit(pUM);
1776*d14abf15SRobert Mustacchi     }
1777*d14abf15SRobert Mustacchi     else
1778*d14abf15SRobert Mustacchi     {
1779*d14abf15SRobert Mustacchi         BnxeFcoeFini(pUM);
1780*d14abf15SRobert Mustacchi     }
1781*d14abf15SRobert Mustacchi }
1782*d14abf15SRobert Mustacchi 
1783