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