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 typedef struct _BnxeWorkItem
39*d14abf15SRobert Mustacchi {
40*d14abf15SRobert Mustacchi s_list_entry_t link;
41*d14abf15SRobert Mustacchi void * pWorkData;
42*d14abf15SRobert Mustacchi u32_t workDataLen;
43*d14abf15SRobert Mustacchi u32_t delayMs;
44*d14abf15SRobert Mustacchi void (*pWorkCbkCopy)(um_device_t *, void *, u32_t);
45*d14abf15SRobert Mustacchi void (*pWorkCbkNoCopy)(um_device_t *, void *);
46*d14abf15SRobert Mustacchi void (*pWorkCbkGeneric)(um_device_t *);
47*d14abf15SRobert Mustacchi } BnxeWorkItem;
48*d14abf15SRobert Mustacchi
49*d14abf15SRobert Mustacchi
BnxeWorkQueueInstanceWaitAndDestroy(BnxeWorkQueueInstance * pWorkq)50*d14abf15SRobert Mustacchi static void BnxeWorkQueueInstanceWaitAndDestroy(BnxeWorkQueueInstance * pWorkq)
51*d14abf15SRobert Mustacchi {
52*d14abf15SRobert Mustacchi if (pWorkq->pTaskq)
53*d14abf15SRobert Mustacchi {
54*d14abf15SRobert Mustacchi ddi_taskq_wait(pWorkq->pTaskq);
55*d14abf15SRobert Mustacchi ddi_taskq_destroy(pWorkq->pTaskq);
56*d14abf15SRobert Mustacchi mutex_destroy(&pWorkq->workQueueMutex);
57*d14abf15SRobert Mustacchi }
58*d14abf15SRobert Mustacchi
59*d14abf15SRobert Mustacchi memset(pWorkq, 0, sizeof(BnxeWorkQueueInstance));
60*d14abf15SRobert Mustacchi }
61*d14abf15SRobert Mustacchi
62*d14abf15SRobert Mustacchi
BnxeWorkQueueInit(um_device_t * pUM)63*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueInit(um_device_t * pUM)
64*d14abf15SRobert Mustacchi {
65*d14abf15SRobert Mustacchi pUM->workqs.instq.pUM = pUM;
66*d14abf15SRobert Mustacchi
67*d14abf15SRobert Mustacchi strcpy(pUM->workqs.instq.taskqName, pUM->devName);
68*d14abf15SRobert Mustacchi strcat(pUM->workqs.instq.taskqName, "_inst_q");
69*d14abf15SRobert Mustacchi
70*d14abf15SRobert Mustacchi mutex_init(&pUM->workqs.instq.workQueueMutex, NULL,
71*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
72*d14abf15SRobert Mustacchi
73*d14abf15SRobert Mustacchi if ((pUM->workqs.instq.pTaskq =
74*d14abf15SRobert Mustacchi ddi_taskq_create(pUM->pDev,
75*d14abf15SRobert Mustacchi pUM->workqs.instq.taskqName,
76*d14abf15SRobert Mustacchi 1,
77*d14abf15SRobert Mustacchi TASKQ_DEFAULTPRI,
78*d14abf15SRobert Mustacchi 0)) == NULL)
79*d14abf15SRobert Mustacchi {
80*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to create the workqs instq");
81*d14abf15SRobert Mustacchi return B_FALSE;
82*d14abf15SRobert Mustacchi }
83*d14abf15SRobert Mustacchi
84*d14abf15SRobert Mustacchi pUM->workqs.instq.pUM = pUM;
85*d14abf15SRobert Mustacchi
86*d14abf15SRobert Mustacchi strcpy(pUM->workqs.delayq.taskqName, pUM->devName);
87*d14abf15SRobert Mustacchi strcat(pUM->workqs.delayq.taskqName, "_delay_q");
88*d14abf15SRobert Mustacchi
89*d14abf15SRobert Mustacchi mutex_init(&pUM->workqs.delayq.workQueueMutex, NULL,
90*d14abf15SRobert Mustacchi MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
91*d14abf15SRobert Mustacchi
92*d14abf15SRobert Mustacchi if ((pUM->workqs.delayq.pTaskq =
93*d14abf15SRobert Mustacchi ddi_taskq_create(pUM->pDev,
94*d14abf15SRobert Mustacchi pUM->workqs.delayq.taskqName,
95*d14abf15SRobert Mustacchi 16, /* XXX Is this enough? */
96*d14abf15SRobert Mustacchi TASKQ_DEFAULTPRI,
97*d14abf15SRobert Mustacchi 0)) == NULL)
98*d14abf15SRobert Mustacchi {
99*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to create the workqs delayq");
100*d14abf15SRobert Mustacchi BnxeWorkQueueInstanceWaitAndDestroy(&pUM->workqs.instq);
101*d14abf15SRobert Mustacchi return B_FALSE;
102*d14abf15SRobert Mustacchi }
103*d14abf15SRobert Mustacchi
104*d14abf15SRobert Mustacchi pUM->workqs.delayq.pUM = pUM;
105*d14abf15SRobert Mustacchi
106*d14abf15SRobert Mustacchi return B_TRUE;
107*d14abf15SRobert Mustacchi }
108*d14abf15SRobert Mustacchi
109*d14abf15SRobert Mustacchi
BnxeWorkQueueWaitAndDestroy(um_device_t * pUM)110*d14abf15SRobert Mustacchi void BnxeWorkQueueWaitAndDestroy(um_device_t * pUM)
111*d14abf15SRobert Mustacchi {
112*d14abf15SRobert Mustacchi BnxeWorkQueueInstanceWaitAndDestroy(&pUM->workqs.instq);
113*d14abf15SRobert Mustacchi BnxeWorkQueueInstanceWaitAndDestroy(&pUM->workqs.delayq);
114*d14abf15SRobert Mustacchi }
115*d14abf15SRobert Mustacchi
116*d14abf15SRobert Mustacchi
BnxeWorkQueueDispatch(void * pArg)117*d14abf15SRobert Mustacchi static void BnxeWorkQueueDispatch(void * pArg)
118*d14abf15SRobert Mustacchi {
119*d14abf15SRobert Mustacchi BnxeWorkQueueInstance * pWorkq = (BnxeWorkQueueInstance *)pArg;
120*d14abf15SRobert Mustacchi um_device_t * pUM = (um_device_t *)pWorkq->pUM;
121*d14abf15SRobert Mustacchi BnxeWorkItem * pWorkItem;
122*d14abf15SRobert Mustacchi
123*d14abf15SRobert Mustacchi mutex_enter(&pWorkq->workQueueMutex);
124*d14abf15SRobert Mustacchi pWorkItem = (BnxeWorkItem *)s_list_pop_head(&pWorkq->workQueue);
125*d14abf15SRobert Mustacchi mutex_exit(&pWorkq->workQueueMutex);
126*d14abf15SRobert Mustacchi
127*d14abf15SRobert Mustacchi if (pWorkItem == NULL)
128*d14abf15SRobert Mustacchi {
129*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Work item is NULL!");
130*d14abf15SRobert Mustacchi pWorkq->workItemError++;
131*d14abf15SRobert Mustacchi return;
132*d14abf15SRobert Mustacchi }
133*d14abf15SRobert Mustacchi
134*d14abf15SRobert Mustacchi if ((pWorkItem->pWorkCbkCopy == NULL) &&
135*d14abf15SRobert Mustacchi (pWorkItem->pWorkCbkNoCopy == NULL) &&
136*d14abf15SRobert Mustacchi (pWorkItem->pWorkCbkGeneric == NULL))
137*d14abf15SRobert Mustacchi {
138*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Work item callback is NULL!");
139*d14abf15SRobert Mustacchi pWorkq->workItemError++;
140*d14abf15SRobert Mustacchi goto BnxeWorkQueueDispatch_done;
141*d14abf15SRobert Mustacchi }
142*d14abf15SRobert Mustacchi
143*d14abf15SRobert Mustacchi if (pWorkItem->delayMs > 0)
144*d14abf15SRobert Mustacchi {
145*d14abf15SRobert Mustacchi /* this only occurs when processing the delayq */
146*d14abf15SRobert Mustacchi drv_usecwait(pWorkItem->delayMs * 1000);
147*d14abf15SRobert Mustacchi }
148*d14abf15SRobert Mustacchi
149*d14abf15SRobert Mustacchi if (pWorkItem->pWorkCbkCopy)
150*d14abf15SRobert Mustacchi {
151*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkCopy(pUM,
152*d14abf15SRobert Mustacchi pWorkItem->pWorkData,
153*d14abf15SRobert Mustacchi pWorkItem->workDataLen);
154*d14abf15SRobert Mustacchi }
155*d14abf15SRobert Mustacchi else if (pWorkItem->pWorkCbkNoCopy)
156*d14abf15SRobert Mustacchi {
157*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkNoCopy(pUM,
158*d14abf15SRobert Mustacchi pWorkItem->pWorkData);
159*d14abf15SRobert Mustacchi }
160*d14abf15SRobert Mustacchi else /* (pWorkItem->pWorkCbkGeneric) */
161*d14abf15SRobert Mustacchi {
162*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkGeneric(pUM);
163*d14abf15SRobert Mustacchi }
164*d14abf15SRobert Mustacchi
165*d14abf15SRobert Mustacchi pWorkq->workItemComplete++;
166*d14abf15SRobert Mustacchi
167*d14abf15SRobert Mustacchi BnxeWorkQueueDispatch_done:
168*d14abf15SRobert Mustacchi
169*d14abf15SRobert Mustacchi kmem_free(pWorkItem, (sizeof(BnxeWorkItem) + pWorkItem->workDataLen));
170*d14abf15SRobert Mustacchi }
171*d14abf15SRobert Mustacchi
172*d14abf15SRobert Mustacchi
BnxeWorkQueueTrigger(um_device_t * pUM,BnxeWorkQueueInstance * pWorkq)173*d14abf15SRobert Mustacchi static void BnxeWorkQueueTrigger(um_device_t * pUM,
174*d14abf15SRobert Mustacchi BnxeWorkQueueInstance * pWorkq)
175*d14abf15SRobert Mustacchi {
176*d14abf15SRobert Mustacchi if (pUM->chipStarted)
177*d14abf15SRobert Mustacchi {
178*d14abf15SRobert Mustacchi ddi_taskq_dispatch(pWorkq->pTaskq,
179*d14abf15SRobert Mustacchi BnxeWorkQueueDispatch,
180*d14abf15SRobert Mustacchi (void *)pWorkq,
181*d14abf15SRobert Mustacchi DDI_NOSLEEP);
182*d14abf15SRobert Mustacchi }
183*d14abf15SRobert Mustacchi else
184*d14abf15SRobert Mustacchi {
185*d14abf15SRobert Mustacchi BnxeLogInfo(pUM, "Delaying WorkQ item since chip not yet started.");
186*d14abf15SRobert Mustacchi }
187*d14abf15SRobert Mustacchi }
188*d14abf15SRobert Mustacchi
189*d14abf15SRobert Mustacchi
BnxeWorkQueueStartPending(um_device_t * pUM)190*d14abf15SRobert Mustacchi void BnxeWorkQueueStartPending(um_device_t * pUM)
191*d14abf15SRobert Mustacchi {
192*d14abf15SRobert Mustacchi u32_t cnt;
193*d14abf15SRobert Mustacchi
194*d14abf15SRobert Mustacchi if (!pUM->chipStarted)
195*d14abf15SRobert Mustacchi {
196*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Triggering WorkQs and chip not started!");
197*d14abf15SRobert Mustacchi return;
198*d14abf15SRobert Mustacchi }
199*d14abf15SRobert Mustacchi
200*d14abf15SRobert Mustacchi mutex_enter(&pUM->workqs.instq.workQueueMutex);
201*d14abf15SRobert Mustacchi cnt = s_list_entry_cnt(&pUM->workqs.instq.workQueue);
202*d14abf15SRobert Mustacchi mutex_exit(&pUM->workqs.instq.workQueueMutex);
203*d14abf15SRobert Mustacchi
204*d14abf15SRobert Mustacchi if (cnt)
205*d14abf15SRobert Mustacchi {
206*d14abf15SRobert Mustacchi BnxeWorkQueueTrigger(pUM, &pUM->workqs.instq);
207*d14abf15SRobert Mustacchi }
208*d14abf15SRobert Mustacchi
209*d14abf15SRobert Mustacchi mutex_enter(&pUM->workqs.delayq.workQueueMutex);
210*d14abf15SRobert Mustacchi cnt = s_list_entry_cnt(&pUM->workqs.delayq.workQueue);
211*d14abf15SRobert Mustacchi mutex_exit(&pUM->workqs.delayq.workQueueMutex);
212*d14abf15SRobert Mustacchi
213*d14abf15SRobert Mustacchi if (cnt)
214*d14abf15SRobert Mustacchi {
215*d14abf15SRobert Mustacchi BnxeWorkQueueTrigger(pUM, &pUM->workqs.delayq);
216*d14abf15SRobert Mustacchi }
217*d14abf15SRobert Mustacchi }
218*d14abf15SRobert Mustacchi
219*d14abf15SRobert Mustacchi
BnxeWorkQueueAdd(um_device_t * pUM,void (* pWorkCbkCopy)(um_device_t *,void *,u32_t),void * pWorkData,u32_t workDataLen)220*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueAdd(um_device_t * pUM,
221*d14abf15SRobert Mustacchi void (*pWorkCbkCopy)(um_device_t *, void *, u32_t),
222*d14abf15SRobert Mustacchi void * pWorkData,
223*d14abf15SRobert Mustacchi u32_t workDataLen)
224*d14abf15SRobert Mustacchi {
225*d14abf15SRobert Mustacchi BnxeWorkItem * pWorkItem;
226*d14abf15SRobert Mustacchi
227*d14abf15SRobert Mustacchi if ((pWorkItem = kmem_zalloc((sizeof(BnxeWorkItem) + workDataLen),
228*d14abf15SRobert Mustacchi KM_NOSLEEP)) == NULL)
229*d14abf15SRobert Mustacchi {
230*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate memory for work item!");
231*d14abf15SRobert Mustacchi return B_FALSE;
232*d14abf15SRobert Mustacchi }
233*d14abf15SRobert Mustacchi
234*d14abf15SRobert Mustacchi pWorkItem->pWorkData = (pWorkItem + 1);
235*d14abf15SRobert Mustacchi pWorkItem->workDataLen = workDataLen;
236*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkCopy = pWorkCbkCopy;
237*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkNoCopy = NULL;
238*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkGeneric = NULL;
239*d14abf15SRobert Mustacchi pWorkItem->delayMs = 0;
240*d14abf15SRobert Mustacchi
241*d14abf15SRobert Mustacchi memcpy(pWorkItem->pWorkData, pWorkData, workDataLen);
242*d14abf15SRobert Mustacchi
243*d14abf15SRobert Mustacchi mutex_enter(&pUM->workqs.instq.workQueueMutex);
244*d14abf15SRobert Mustacchi
245*d14abf15SRobert Mustacchi s_list_push_tail(&pUM->workqs.instq.workQueue, &pWorkItem->link);
246*d14abf15SRobert Mustacchi pUM->workqs.instq.workItemQueued++;
247*d14abf15SRobert Mustacchi if (s_list_entry_cnt(&pUM->workqs.instq.workQueue) >
248*d14abf15SRobert Mustacchi pUM->workqs.instq.highWater)
249*d14abf15SRobert Mustacchi {
250*d14abf15SRobert Mustacchi pUM->workqs.instq.highWater =
251*d14abf15SRobert Mustacchi s_list_entry_cnt(&pUM->workqs.instq.workQueue);
252*d14abf15SRobert Mustacchi }
253*d14abf15SRobert Mustacchi
254*d14abf15SRobert Mustacchi mutex_exit(&pUM->workqs.instq.workQueueMutex);
255*d14abf15SRobert Mustacchi
256*d14abf15SRobert Mustacchi BnxeWorkQueueTrigger(pUM, &pUM->workqs.instq);
257*d14abf15SRobert Mustacchi
258*d14abf15SRobert Mustacchi return B_TRUE;
259*d14abf15SRobert Mustacchi }
260*d14abf15SRobert Mustacchi
261*d14abf15SRobert Mustacchi
BnxeWorkQueueAddNoCopy(um_device_t * pUM,void (* pWorkCbkNoCopy)(um_device_t *,void *),void * pWorkData)262*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueAddNoCopy(um_device_t * pUM,
263*d14abf15SRobert Mustacchi void (*pWorkCbkNoCopy)(um_device_t *, void *),
264*d14abf15SRobert Mustacchi void * pWorkData)
265*d14abf15SRobert Mustacchi {
266*d14abf15SRobert Mustacchi BnxeWorkItem * pWorkItem;
267*d14abf15SRobert Mustacchi
268*d14abf15SRobert Mustacchi if ((pWorkItem = kmem_zalloc(sizeof(BnxeWorkItem), KM_NOSLEEP)) == NULL)
269*d14abf15SRobert Mustacchi {
270*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate memory for work item!");
271*d14abf15SRobert Mustacchi return B_FALSE;
272*d14abf15SRobert Mustacchi }
273*d14abf15SRobert Mustacchi
274*d14abf15SRobert Mustacchi pWorkItem->pWorkData = pWorkData;
275*d14abf15SRobert Mustacchi pWorkItem->workDataLen = 0;
276*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkCopy = NULL;
277*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkNoCopy = pWorkCbkNoCopy;
278*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkGeneric = NULL;
279*d14abf15SRobert Mustacchi pWorkItem->delayMs = 0;
280*d14abf15SRobert Mustacchi
281*d14abf15SRobert Mustacchi mutex_enter(&pUM->workqs.instq.workQueueMutex);
282*d14abf15SRobert Mustacchi
283*d14abf15SRobert Mustacchi s_list_push_tail(&pUM->workqs.instq.workQueue, &pWorkItem->link);
284*d14abf15SRobert Mustacchi pUM->workqs.instq.workItemQueued++;
285*d14abf15SRobert Mustacchi if (s_list_entry_cnt(&pUM->workqs.instq.workQueue) >
286*d14abf15SRobert Mustacchi pUM->workqs.instq.highWater)
287*d14abf15SRobert Mustacchi {
288*d14abf15SRobert Mustacchi pUM->workqs.instq.highWater =
289*d14abf15SRobert Mustacchi s_list_entry_cnt(&pUM->workqs.instq.workQueue);
290*d14abf15SRobert Mustacchi }
291*d14abf15SRobert Mustacchi
292*d14abf15SRobert Mustacchi mutex_exit(&pUM->workqs.instq.workQueueMutex);
293*d14abf15SRobert Mustacchi
294*d14abf15SRobert Mustacchi BnxeWorkQueueTrigger(pUM, &pUM->workqs.instq);
295*d14abf15SRobert Mustacchi
296*d14abf15SRobert Mustacchi return B_TRUE;
297*d14abf15SRobert Mustacchi }
298*d14abf15SRobert Mustacchi
299*d14abf15SRobert Mustacchi
BnxeWorkQueueAddGeneric(um_device_t * pUM,void (* pWorkCbkGeneric)(um_device_t *))300*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueAddGeneric(um_device_t * pUM,
301*d14abf15SRobert Mustacchi void (*pWorkCbkGeneric)(um_device_t *))
302*d14abf15SRobert Mustacchi {
303*d14abf15SRobert Mustacchi BnxeWorkItem * pWorkItem;
304*d14abf15SRobert Mustacchi
305*d14abf15SRobert Mustacchi if ((pWorkItem = kmem_zalloc(sizeof(BnxeWorkItem), KM_NOSLEEP)) == NULL)
306*d14abf15SRobert Mustacchi {
307*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate memory for work item!");
308*d14abf15SRobert Mustacchi return B_FALSE;
309*d14abf15SRobert Mustacchi }
310*d14abf15SRobert Mustacchi
311*d14abf15SRobert Mustacchi pWorkItem->pWorkData = NULL;
312*d14abf15SRobert Mustacchi pWorkItem->workDataLen = 0;
313*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkCopy = NULL;
314*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkNoCopy = NULL;
315*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkGeneric = pWorkCbkGeneric;
316*d14abf15SRobert Mustacchi pWorkItem->delayMs = 0;
317*d14abf15SRobert Mustacchi
318*d14abf15SRobert Mustacchi mutex_enter(&pUM->workqs.instq.workQueueMutex);
319*d14abf15SRobert Mustacchi
320*d14abf15SRobert Mustacchi s_list_push_tail(&pUM->workqs.instq.workQueue, &pWorkItem->link);
321*d14abf15SRobert Mustacchi pUM->workqs.instq.workItemQueued++;
322*d14abf15SRobert Mustacchi if (s_list_entry_cnt(&pUM->workqs.instq.workQueue) >
323*d14abf15SRobert Mustacchi pUM->workqs.instq.highWater)
324*d14abf15SRobert Mustacchi {
325*d14abf15SRobert Mustacchi pUM->workqs.instq.highWater =
326*d14abf15SRobert Mustacchi s_list_entry_cnt(&pUM->workqs.instq.workQueue);
327*d14abf15SRobert Mustacchi }
328*d14abf15SRobert Mustacchi
329*d14abf15SRobert Mustacchi mutex_exit(&pUM->workqs.instq.workQueueMutex);
330*d14abf15SRobert Mustacchi
331*d14abf15SRobert Mustacchi BnxeWorkQueueTrigger(pUM, &pUM->workqs.instq);
332*d14abf15SRobert Mustacchi
333*d14abf15SRobert Mustacchi return B_TRUE;
334*d14abf15SRobert Mustacchi }
335*d14abf15SRobert Mustacchi
336*d14abf15SRobert Mustacchi
BnxeWorkQueueAddDelay(um_device_t * pUM,void (* pWorkCbkCopy)(um_device_t *,void *,u32_t),void * pWorkData,u32_t workDataLen,u32_t delayMs)337*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueAddDelay(um_device_t * pUM,
338*d14abf15SRobert Mustacchi void (*pWorkCbkCopy)(um_device_t *, void *, u32_t),
339*d14abf15SRobert Mustacchi void * pWorkData,
340*d14abf15SRobert Mustacchi u32_t workDataLen,
341*d14abf15SRobert Mustacchi u32_t delayMs)
342*d14abf15SRobert Mustacchi {
343*d14abf15SRobert Mustacchi BnxeWorkItem * pWorkItem;
344*d14abf15SRobert Mustacchi
345*d14abf15SRobert Mustacchi if ((pWorkItem = kmem_zalloc((sizeof(BnxeWorkItem) + workDataLen),
346*d14abf15SRobert Mustacchi KM_NOSLEEP)) == NULL)
347*d14abf15SRobert Mustacchi {
348*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate memory for work item!");
349*d14abf15SRobert Mustacchi return B_FALSE;
350*d14abf15SRobert Mustacchi }
351*d14abf15SRobert Mustacchi
352*d14abf15SRobert Mustacchi pWorkItem->pWorkData = (pWorkItem + 1);
353*d14abf15SRobert Mustacchi pWorkItem->workDataLen = workDataLen;
354*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkCopy = pWorkCbkCopy;
355*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkNoCopy = NULL;
356*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkGeneric = NULL;
357*d14abf15SRobert Mustacchi pWorkItem->delayMs = delayMs;
358*d14abf15SRobert Mustacchi
359*d14abf15SRobert Mustacchi memcpy(pWorkItem->pWorkData, pWorkData, workDataLen);
360*d14abf15SRobert Mustacchi
361*d14abf15SRobert Mustacchi mutex_enter(&pUM->workqs.delayq.workQueueMutex);
362*d14abf15SRobert Mustacchi
363*d14abf15SRobert Mustacchi s_list_push_tail(&pUM->workqs.delayq.workQueue, &pWorkItem->link);
364*d14abf15SRobert Mustacchi pUM->workqs.delayq.workItemQueued++;
365*d14abf15SRobert Mustacchi if (s_list_entry_cnt(&pUM->workqs.delayq.workQueue) >
366*d14abf15SRobert Mustacchi pUM->workqs.delayq.highWater)
367*d14abf15SRobert Mustacchi {
368*d14abf15SRobert Mustacchi pUM->workqs.delayq.highWater =
369*d14abf15SRobert Mustacchi s_list_entry_cnt(&pUM->workqs.delayq.workQueue);
370*d14abf15SRobert Mustacchi }
371*d14abf15SRobert Mustacchi
372*d14abf15SRobert Mustacchi mutex_exit(&pUM->workqs.delayq.workQueueMutex);
373*d14abf15SRobert Mustacchi
374*d14abf15SRobert Mustacchi BnxeWorkQueueTrigger(pUM, &pUM->workqs.delayq);
375*d14abf15SRobert Mustacchi
376*d14abf15SRobert Mustacchi return B_TRUE;
377*d14abf15SRobert Mustacchi }
378*d14abf15SRobert Mustacchi
379*d14abf15SRobert Mustacchi
BnxeWorkQueueAddDelayNoCopy(um_device_t * pUM,void (* pWorkCbkNoCopy)(um_device_t *,void *),void * pWorkData,u32_t delayMs)380*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueAddDelayNoCopy(um_device_t * pUM,
381*d14abf15SRobert Mustacchi void (*pWorkCbkNoCopy)(um_device_t *, void *),
382*d14abf15SRobert Mustacchi void * pWorkData,
383*d14abf15SRobert Mustacchi u32_t delayMs)
384*d14abf15SRobert Mustacchi {
385*d14abf15SRobert Mustacchi BnxeWorkItem * pWorkItem;
386*d14abf15SRobert Mustacchi
387*d14abf15SRobert Mustacchi if ((pWorkItem = kmem_zalloc(sizeof(BnxeWorkItem), KM_NOSLEEP)) == NULL)
388*d14abf15SRobert Mustacchi {
389*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate memory for work item!");
390*d14abf15SRobert Mustacchi return B_FALSE;
391*d14abf15SRobert Mustacchi }
392*d14abf15SRobert Mustacchi
393*d14abf15SRobert Mustacchi pWorkItem->pWorkData = pWorkData;
394*d14abf15SRobert Mustacchi pWorkItem->workDataLen = 0;
395*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkCopy = NULL;
396*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkNoCopy = pWorkCbkNoCopy;
397*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkGeneric = NULL;
398*d14abf15SRobert Mustacchi pWorkItem->delayMs = delayMs;
399*d14abf15SRobert Mustacchi
400*d14abf15SRobert Mustacchi mutex_enter(&pUM->workqs.delayq.workQueueMutex);
401*d14abf15SRobert Mustacchi
402*d14abf15SRobert Mustacchi s_list_push_tail(&pUM->workqs.delayq.workQueue, &pWorkItem->link);
403*d14abf15SRobert Mustacchi pUM->workqs.delayq.workItemQueued++;
404*d14abf15SRobert Mustacchi if (s_list_entry_cnt(&pUM->workqs.delayq.workQueue) >
405*d14abf15SRobert Mustacchi pUM->workqs.delayq.highWater)
406*d14abf15SRobert Mustacchi {
407*d14abf15SRobert Mustacchi pUM->workqs.delayq.highWater =
408*d14abf15SRobert Mustacchi s_list_entry_cnt(&pUM->workqs.delayq.workQueue);
409*d14abf15SRobert Mustacchi }
410*d14abf15SRobert Mustacchi
411*d14abf15SRobert Mustacchi mutex_exit(&pUM->workqs.delayq.workQueueMutex);
412*d14abf15SRobert Mustacchi
413*d14abf15SRobert Mustacchi BnxeWorkQueueTrigger(pUM, &pUM->workqs.delayq);
414*d14abf15SRobert Mustacchi
415*d14abf15SRobert Mustacchi return B_TRUE;
416*d14abf15SRobert Mustacchi }
417*d14abf15SRobert Mustacchi
418*d14abf15SRobert Mustacchi
BnxeWorkQueueAddDelayGeneric(um_device_t * pUM,void (* pWorkCbkGeneric)(um_device_t *),u32_t delayMs)419*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueAddDelayGeneric(um_device_t * pUM,
420*d14abf15SRobert Mustacchi void (*pWorkCbkGeneric)(um_device_t *),
421*d14abf15SRobert Mustacchi u32_t delayMs)
422*d14abf15SRobert Mustacchi {
423*d14abf15SRobert Mustacchi BnxeWorkItem * pWorkItem;
424*d14abf15SRobert Mustacchi
425*d14abf15SRobert Mustacchi if ((pWorkItem = kmem_zalloc(sizeof(BnxeWorkItem), KM_NOSLEEP)) == NULL)
426*d14abf15SRobert Mustacchi {
427*d14abf15SRobert Mustacchi BnxeLogWarn(pUM, "Failed to allocate memory for work item!");
428*d14abf15SRobert Mustacchi return B_FALSE;
429*d14abf15SRobert Mustacchi }
430*d14abf15SRobert Mustacchi
431*d14abf15SRobert Mustacchi pWorkItem->pWorkData = NULL;
432*d14abf15SRobert Mustacchi pWorkItem->workDataLen = 0;
433*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkCopy = NULL;
434*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkNoCopy = NULL;
435*d14abf15SRobert Mustacchi pWorkItem->pWorkCbkGeneric = pWorkCbkGeneric;
436*d14abf15SRobert Mustacchi pWorkItem->delayMs = delayMs;
437*d14abf15SRobert Mustacchi
438*d14abf15SRobert Mustacchi mutex_enter(&pUM->workqs.delayq.workQueueMutex);
439*d14abf15SRobert Mustacchi
440*d14abf15SRobert Mustacchi s_list_push_tail(&pUM->workqs.delayq.workQueue, &pWorkItem->link);
441*d14abf15SRobert Mustacchi pUM->workqs.delayq.workItemQueued++;
442*d14abf15SRobert Mustacchi if (s_list_entry_cnt(&pUM->workqs.delayq.workQueue) >
443*d14abf15SRobert Mustacchi pUM->workqs.delayq.highWater)
444*d14abf15SRobert Mustacchi {
445*d14abf15SRobert Mustacchi pUM->workqs.delayq.highWater =
446*d14abf15SRobert Mustacchi s_list_entry_cnt(&pUM->workqs.delayq.workQueue);
447*d14abf15SRobert Mustacchi }
448*d14abf15SRobert Mustacchi
449*d14abf15SRobert Mustacchi mutex_exit(&pUM->workqs.delayq.workQueueMutex);
450*d14abf15SRobert Mustacchi
451*d14abf15SRobert Mustacchi BnxeWorkQueueTrigger(pUM, &pUM->workqs.delayq);
452*d14abf15SRobert Mustacchi
453*d14abf15SRobert Mustacchi return B_TRUE;
454*d14abf15SRobert Mustacchi }
455*d14abf15SRobert Mustacchi
456