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