vxgehal-channel.c revision 331722
1/*-
2 * Copyright(c) 2002-2011 Exar Corp.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification are permitted provided the following conditions are met:
7 *
8 *    1. Redistributions of source code must retain the above copyright notice,
9 *       this list of conditions and the following disclaimer.
10 *
11 *    2. Redistributions in binary form must reproduce the above copyright
12 *       notice, this list of conditions and the following disclaimer in the
13 *       documentation and/or other materials provided with the distribution.
14 *
15 *    3. Neither the name of the Exar Corporation nor the names of its
16 *       contributors may be used to endorse or promote products derived from
17 *       this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31/*$FreeBSD: stable/11/sys/dev/vxge/vxgehal/vxgehal-channel.c 331722 2018-03-29 02:50:57Z eadler $*/
32
33#include <dev/vxge/vxgehal/vxgehal.h>
34
35
36/*
37 * vxge_hal_channel_allocate - Allocate memory for channel
38 * @devh: Handle to the device object
39 * @vph: Handle to Virtual Path
40 * @type: Type of channel
41 * @length: Lengths of arrays
42 * @per_dtr_space: ULD requested per dtr space to be allocated in priv
43 * @userdata: User data to be passed back in the callback
44 *
45 * This function allocates required memory for the channel and various arrays
46 * in the channel
47 */
48__hal_channel_t *
49vxge_hal_channel_allocate(
50    vxge_hal_device_h devh,
51    vxge_hal_vpath_h vph,
52    __hal_channel_type_e type,
53    u32 length,
54    u32 per_dtr_space,
55    void *userdata)
56{
57	vxge_hal_device_t *hldev = (vxge_hal_device_t *) devh;
58	__hal_channel_t *channel;
59	u32 i, size = 0;
60
61	vxge_assert((devh != NULL) && (vph != NULL));
62
63	vxge_hal_trace_log_channel("==> %s:%s:%d",
64	    __FILE__, __func__, __LINE__);
65
66	vxge_hal_trace_log_channel("devh = 0x"VXGE_OS_STXFMT", vph = "
67	    "0x"VXGE_OS_STXFMT", type = %d, length = %d, "
68	    "per_dtr_space = %d, userdata = 0x"VXGE_OS_STXFMT,
69	    (ptr_t) devh, (ptr_t) vph, type, length, per_dtr_space,
70	    (ptr_t) userdata);
71
72	switch (type) {
73	case VXGE_HAL_CHANNEL_TYPE_FIFO:
74		size = sizeof(__hal_fifo_t);
75		break;
76	case VXGE_HAL_CHANNEL_TYPE_RING:
77		size = sizeof(__hal_ring_t);
78		break;
79
80
81	default:
82		vxge_assert(size);
83		break;
84
85	}
86
87	channel = (__hal_channel_t *) vxge_os_malloc(hldev->pdev, size);
88	if (channel == NULL) {
89		vxge_hal_trace_log_channel("<== %s:%s:%d  Result: %d",
90		    __FILE__, __func__, __LINE__, VXGE_HAL_ERR_OUT_OF_MEMORY);
91		return (NULL);
92	}
93
94	vxge_os_memzero(channel, size);
95	vxge_list_init(&channel->item);
96
97	channel->pdev = hldev->pdev;
98	channel->type = type;
99	channel->devh = devh;
100	channel->vph = vph;
101
102	channel->userdata = userdata;
103	channel->per_dtr_space = per_dtr_space;
104
105	channel->length = length;
106
107	channel->dtr_arr = (__hal_dtr_item_t *) vxge_os_malloc(hldev->pdev,
108	    sizeof(__hal_dtr_item_t)*length);
109	if (channel->dtr_arr == NULL) {
110		vxge_hal_channel_free(channel);
111		vxge_hal_trace_log_channel("<== %s:%s:%d  Result: %d",
112		    __FILE__, __func__, __LINE__, VXGE_HAL_ERR_OUT_OF_MEMORY);
113		return (NULL);
114	}
115
116	vxge_os_memzero(channel->dtr_arr, sizeof(__hal_dtr_item_t)*length);
117
118	channel->compl_index = 0;
119	channel->reserve_index = 0;
120
121	for (i = 0; i < length; i++)
122		channel->dtr_arr[i].state = VXGE_HAL_CHANNEL_DTR_FREE;
123
124	vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
125	    __FILE__, __func__, __LINE__);
126	return (channel);
127}
128
129/*
130 * __hal_channel_free - Free memory allocated for channel
131 * @channel: channel to be freed
132 *
133 * This function deallocates memory from the channel and various arrays
134 * in the channel
135 */
136void
137vxge_hal_channel_free(
138    __hal_channel_t *channel)
139{
140	int size = 0;
141	vxge_hal_device_t *hldev;
142
143	vxge_assert(channel != NULL);
144
145	hldev = (vxge_hal_device_t *) channel->devh;
146
147	vxge_hal_trace_log_channel("==> %s:%s:%d",
148	    __FILE__, __func__, __LINE__);
149
150	vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
151	    (ptr_t) channel);
152
153	vxge_assert(channel->pdev);
154
155	if (channel->dtr_arr) {
156		vxge_os_free(channel->pdev, channel->dtr_arr,
157		    sizeof(__hal_dtr_item_t)*channel->length);
158		channel->dtr_arr = NULL;
159	}
160
161	switch (channel->type) {
162	case VXGE_HAL_CHANNEL_TYPE_FIFO:
163		size = sizeof(__hal_fifo_t);
164		break;
165	case VXGE_HAL_CHANNEL_TYPE_RING:
166		size = sizeof(__hal_ring_t);
167		break;
168	default:
169		break;
170	}
171
172	vxge_os_free(channel->pdev, channel, size);
173
174	vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
175	    __FILE__, __func__, __LINE__);
176}
177
178/*
179 * __hal_channel_initialize - Initialize a channel
180 * @channel: channel to be initialized
181 *
182 * This function initializes a channel by properly
183 *		setting the various references
184 */
185vxge_hal_status_e
186vxge_hal_channel_initialize(
187    __hal_channel_t *channel)
188{
189	vxge_hal_device_t *hldev;
190	__hal_virtualpath_t *vpath;
191
192	vxge_assert(channel != NULL);
193
194	hldev = (vxge_hal_device_t *) channel->devh;
195	vpath = (__hal_virtualpath_t *)
196	    ((__hal_vpath_handle_t *) channel->vph)->vpath;
197
198	vxge_assert(vpath != NULL);
199
200	vxge_hal_trace_log_channel("==> %s:%s:%d",
201	    __FILE__, __func__, __LINE__);
202
203	vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
204	    (ptr_t) channel);
205
206	switch (channel->type) {
207	case VXGE_HAL_CHANNEL_TYPE_FIFO:
208		vpath->fifoh = (vxge_hal_fifo_h) channel;
209		channel->stats =
210		    &((__hal_fifo_t *) channel)->stats->common_stats;
211		break;
212	case VXGE_HAL_CHANNEL_TYPE_RING:
213		vpath->ringh = (vxge_hal_ring_h) channel;
214		channel->stats =
215		    &((__hal_ring_t *) channel)->stats->common_stats;
216		break;
217
218
219	default:
220		break;
221	}
222
223	channel->is_initd = 1;
224	vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
225	    __FILE__, __func__, __LINE__);
226
227	return (VXGE_HAL_OK);
228}
229
230/*
231 * __hal_channel_reset - Resets a channel
232 * @channel: channel to be reset
233 *
234 * This function resets a channel by properly setting the various references
235 */
236vxge_hal_status_e
237__hal_channel_reset(
238    __hal_channel_t *channel)
239{
240	u32 i;
241	__hal_device_t *hldev;
242
243	vxge_assert(channel != NULL);
244
245	hldev = (__hal_device_t *) channel->devh;
246
247	vxge_hal_trace_log_channel("==> %s:%s:%d",
248	    __FILE__, __func__, __LINE__);
249
250	vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
251	    (ptr_t) channel);
252
253	vxge_assert(channel->pdev);
254
255	channel->compl_index = 0;
256	channel->reserve_index = 0;
257
258	for (i = 0; i < channel->length; i++) {
259		channel->dtr_arr[i].state =
260		    VXGE_HAL_CHANNEL_DTR_FREE;
261	}
262
263	vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
264	    __FILE__, __func__, __LINE__);
265
266	return (VXGE_HAL_OK);
267}
268
269/*
270 * vxge_hal_channel_terminate - Deinitializes a channel
271 * @channel: channel to be deinitialized
272 *
273 * This function deinitializes a channel by properly
274 *		setting the various references
275 */
276void
277vxge_hal_channel_terminate(
278    __hal_channel_t *channel)
279{
280	__hal_device_t *hldev;
281	__hal_virtualpath_t *vpath;
282
283	vxge_assert(channel != NULL);
284
285	if (!channel || !channel->is_initd)
286		return;
287
288	hldev = (__hal_device_t *) channel->devh;
289	vpath = (__hal_virtualpath_t *)
290	    ((__hal_vpath_handle_t *) channel->vph)->vpath;
291
292	vxge_assert(vpath != NULL);
293
294	vxge_hal_trace_log_channel("==> %s:%s:%d",
295	    __FILE__, __func__, __LINE__);
296
297	vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
298	    (ptr_t) channel);
299
300	switch (channel->type) {
301	case VXGE_HAL_CHANNEL_TYPE_FIFO:
302		vpath->fifoh = 0;
303		break;
304	case VXGE_HAL_CHANNEL_TYPE_RING:
305		vpath->ringh = 0;
306		break;
307	case VXGE_HAL_CHANNEL_TYPE_SEND_QUEUE:
308		vxge_list_remove(&channel->item);
309		vpath->sw_stats->obj_counts.no_sqs--;
310		break;
311	case VXGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE:
312		vxge_list_remove(&channel->item);
313		vpath->sw_stats->obj_counts.no_srqs--;
314		break;
315	case VXGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE:
316		vxge_list_remove(&channel->item);
317		vpath->sw_stats->obj_counts.no_cqrqs--;
318		break;
319	default:
320		break;
321	}
322
323	vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
324	    __FILE__, __func__, __LINE__);
325}
326
327void
328__hal_channel_init_pending_list(
329    vxge_hal_device_h devh)
330{
331	__hal_device_t *hldev = (__hal_device_t *) devh;
332
333	vxge_assert(devh != NULL);
334
335	vxge_hal_trace_log_channel("==> %s:%s:%d",
336	    __FILE__, __func__, __LINE__);
337
338	vxge_hal_trace_log_channel("devh = 0x"VXGE_OS_STXFMT,
339	    (ptr_t) devh);
340	vxge_list_init(&hldev->pending_channel_list);
341
342#if defined(VXGE_HAL_VP_CHANNELS)
343	vxge_os_spin_lock_init(&hldev->pending_channel_lock, hldev->pdev);
344#elif defined(VXGE_HAL_VP_CHANNELS_IRQ)
345	vxge_os_spin_lock_init_irq(&hldev->pending_channel_lock, hldev->irqh);
346#endif
347	vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
348	    __FILE__, __func__, __LINE__);
349}
350
351void
352__hal_channel_insert_pending_list(
353    __hal_channel_t * channel)
354{
355	__hal_device_t *hldev = (__hal_device_t *) channel->devh;
356
357	vxge_assert(channel != NULL);
358
359	vxge_hal_trace_log_channel("==> %s:%s:%d",
360	    __FILE__, __func__, __LINE__);
361
362	vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
363	    (ptr_t) channel);
364
365#if defined(VXGE_HAL_PENDING_CHANNELS)
366	vxge_os_spin_lock(&hldev->pending_channel_lock);
367#elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
368	vxge_os_spin_lock_irq(&hldev->pending_channel_lock, flags);
369#endif
370
371	vxge_list_insert_before(&channel->item, &hldev->pending_channel_list);
372
373#if defined(VXGE_HAL_PENDING_CHANNELS)
374	vxge_os_spin_unlock(&hldev->pending_channel_lock);
375#elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
376	vxge_os_spin_unlock_irq(&hldev->pending_channel_lock, flags);
377#endif
378
379	__hal_channel_process_pending_list(channel->devh);
380
381	vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
382	    __FILE__, __func__, __LINE__);
383}
384
385void
386__hal_channel_process_pending_list(
387    vxge_hal_device_h devh)
388{
389	vxge_hal_status_e status;
390	__hal_channel_t *channel;
391	__hal_device_t *hldev = (__hal_device_t *) devh;
392
393	vxge_assert(devh != NULL);
394
395	vxge_hal_trace_log_channel("==> %s:%s:%d",
396	    __FILE__, __func__, __LINE__);
397
398	vxge_hal_trace_log_channel("devh = 0x"VXGE_OS_STXFMT,
399	    (ptr_t) devh);
400
401	for (;;) {
402#if defined(VXGE_HAL_PENDING_CHANNELS)
403		vxge_os_spin_lock(&hldev->pending_channel_lock);
404#elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
405		vxge_os_spin_lock_irq(&hldev->pending_channel_lock, flags);
406#endif
407
408		channel = (__hal_channel_t *)
409		    vxge_list_first_get(&hldev->pending_channel_list);
410
411		if (channel != NULL)
412			vxge_list_remove(&channel->item);
413
414#if defined(VXGE_HAL_PENDING_CHANNELS)
415		vxge_os_spin_unlock(&hldev->pending_channel_lock);
416#elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
417		vxge_os_spin_unlock_irq(&hldev->pending_channel_lock, flags);
418#endif
419
420		if (channel == NULL) {
421			vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
422			    __FILE__, __func__, __LINE__);
423			return;
424		}
425
426		switch (channel->type) {
427		default:
428			status = VXGE_HAL_OK;
429			break;
430		}
431
432		if (status == VXGE_HAL_ERR_OUT_OF_MEMORY) {
433#if defined(VXGE_HAL_PENDING_CHANNELS)
434			vxge_os_spin_lock(&hldev->pending_channel_lock);
435#elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
436			vxge_os_spin_lock_irq(&hldev->pending_channel_lock,
437			    flags);
438#endif
439
440			vxge_list_insert(&channel->item,
441			    &hldev->pending_channel_list);
442
443#if defined(VXGE_HAL_PENDING_CHANNELS)
444			vxge_os_spin_unlock(&hldev->pending_channel_lock);
445#elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
446			vxge_os_spin_unlock_irq(&hldev->pending_channel_lock,
447			    flags);
448#endif
449			vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
450			    __FILE__, __func__, __LINE__);
451
452			return;
453		}
454
455	}
456}
457
458void
459__hal_channel_destroy_pending_list(
460    vxge_hal_device_h devh)
461{
462	vxge_list_t *p, *n;
463	__hal_device_t *hldev = (__hal_device_t *) devh;
464
465	vxge_assert(devh != NULL);
466
467	vxge_hal_trace_log_channel("==> %s:%s:%d",
468	    __FILE__, __func__, __LINE__);
469
470	vxge_hal_trace_log_channel("devh = 0x"VXGE_OS_STXFMT,
471	    (ptr_t) devh);
472
473	vxge_list_for_each_safe(p, n, &hldev->pending_channel_list) {
474
475		vxge_list_remove(p);
476
477		switch (((__hal_channel_t *) p)->type) {
478		default:
479			break;
480		}
481
482	}
483
484#if defined(VXGE_HAL_PENDING_CHANNELS)
485	vxge_os_spin_lock_destroy(&hldev->pending_channel_lock,
486	    hldev->header.pdev);
487#elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
488	vxge_os_spin_lock_destroy_irq(&hldev->pending_channel_lock,
489	    hldev->header.pdev);
490#endif
491	vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
492	    __FILE__, __func__, __LINE__);
493}
494