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
BnxeFcoeFreeResc(um_device_t * pUM,BnxeFcoeState * pFcoeState)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
BnxeFcoeCqeIndicate(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeInitCqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeInitCqe(um_device_t * pUM,struct fcoe_kcqe * kcqe)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
BnxeFcoeInitWqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeInitWqe(um_device_t * pUM,union fcoe_kwqe ** kwqes)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
BnxeFcoeOffloadConnCqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeOffloadConnCqe(um_device_t * pUM,BnxeFcoeState * pFcoeState,struct fcoe_kcqe * kcqe)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
BnxeFcoeOffloadConnWqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeOffloadConnWqe(um_device_t * pUM,union fcoe_kwqe ** kwqes)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
BnxeFcoeEnableConnCqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeEnableConnCqe(um_device_t * pUM,BnxeFcoeState * pFcoeState,struct fcoe_kcqe * kcqe)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
BnxeFcoeEnableConnWqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeEnableConnWqe(um_device_t * pUM,union fcoe_kwqe ** kwqes)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
BnxeFcoeDisableConnCqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeDisableConnCqe(um_device_t * pUM,BnxeFcoeState * pFcoeState,struct fcoe_kcqe * kcqe)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
BnxeFcoeDisableConnWqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeDisableConnWqe(um_device_t * pUM,union fcoe_kwqe ** kwqes)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
BnxeFcoeDestroyConnCqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeDestroyConnCqe(um_device_t * pUM,BnxeFcoeState * pFcoeState,struct fcoe_kcqe * kcqe)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
BnxeFcoeDestroyConnWqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeDestroyConnWqe(um_device_t * pUM,union fcoe_kwqe ** kwqes)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
BnxeFcoeDestroyCqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeDestroyCqe(um_device_t * pUM,struct fcoe_kcqe * kcqe)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
BnxeFcoeDestroyWqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeDestroyWqe(um_device_t * pUM,union fcoe_kwqe ** kwqes)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
BnxeFcoeStatCqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeStatCqe(um_device_t * pUM,struct fcoe_kcqe * kcqe)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
BnxeFcoeStatWqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeStatWqe(um_device_t * pUM,union fcoe_kwqe ** kwqes)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
BnxeFcoeCompRequestCqeWork(um_device_t * pUM,void * pData,u32_t dataLen)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
BnxeFcoeCompRequestCqe(um_device_t * pUM,struct fcoe_kcqe * kcqes,u32_t num_kcqes)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
BnxeFcoePrvCtl(dev_info_t * pDev,int cmd,void * pData,int dataLen)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
BnxeFcoePrvTx(dev_info_t * pDev,mblk_t * pMblk,u32_t flags,u16_t vlan_tag)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
BnxeFcoePrvPoll(dev_info_t * pDev)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
BnxeFcoePrvSendWqes(dev_info_t * pDev,void * wqes[],int wqeCnt)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
BnxeFcoePrvMapMailboxq(dev_info_t * pDev,u32_t cid,void ** ppMap,ddi_acc_handle_t * pAccHandle)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
BnxeFcoePrvUnmapMailboxq(dev_info_t * pDev,u32_t cid,void * pMap,ddi_acc_handle_t accHandle)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
BnxeFcoeInit(um_device_t * pUM)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
BnxeFcoeFini(um_device_t * pUM)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
BnxeFcoeStartStop(um_device_t * pUM)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