1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * Copyright (c) 2002-2006 Neterion, Inc. 22 */ 23 24 #ifndef XGE_HAL_CHANNEL_H 25 #define XGE_HAL_CHANNEL_H 26 27 #include "xge-os-pal.h" 28 #include "xge-list.h" 29 #include "xgehal-types.h" 30 #include "xgehal-stats.h" 31 32 __EXTERN_BEGIN_DECLS 33 34 /** 35 * enum xge_hal_channel_type_e - Enumerated channel types. 36 * @XGE_HAL_CHANNEL_TYPE_FIFO: fifo. 37 * @XGE_HAL_CHANNEL_TYPE_RING: ring. 38 * @XGE_HAL_CHANNEL_TYPE_SEND_QUEUE: TBD. 39 * @XGE_HAL_CHANNEL_TYPE_HW_RECEIVE_QUEUE: TBD. 40 * @XGE_HAL_CHANNEL_TYPE_HW_COMPLETION_QUEUE: TBD. 41 * @XGE_HAL_CHANNEL_TYPE_LRO_RECEIVE_QUEUE: TBD. 42 * @XGE_HAL_CHANNEL_TYPE_LRO_COMPLETION_QUEUE: TBD. 43 * @XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE: TBD. 44 * @XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE: TBD. 45 * @XGE_HAL_CHANNEL_TYPE_MAX: Maximum number of HAL-supported 46 * (and recognized) channel types. Currently: two. 47 * 48 * Enumerated channel types. Currently there are only two link-layer 49 * channels - Xframe fifo and Xframe ring. In the future the list will grow. 50 */ 51 typedef enum xge_hal_channel_type_e { 52 XGE_HAL_CHANNEL_TYPE_FIFO, 53 XGE_HAL_CHANNEL_TYPE_RING, 54 XGE_HAL_CHANNEL_TYPE_SEND_QUEUE, 55 XGE_HAL_CHANNEL_TYPE_HW_RECEIVE_QUEUE, 56 XGE_HAL_CHANNEL_TYPE_HW_COMPLETION_QUEUE, 57 XGE_HAL_CHANNEL_TYPE_LRO_RECEIVE_QUEUE, 58 XGE_HAL_CHANNEL_TYPE_LRO_COMPLETION_QUEUE, 59 XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE, 60 XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE, 61 XGE_HAL_CHANNEL_TYPE_MAX 62 } xge_hal_channel_type_e; 63 64 /** 65 * enum xge_hal_channel_flag_e - Channel flags. 66 * @XGE_HAL_CHANNEL_FLAG_NONE: zero (nil) flag. 67 * @XGE_HAL_CHANNEL_FLAG_USE_TX_LOCK: use lock when posting transmit 68 * descriptor. 69 * @XGE_HAL_CHANNEL_FLAG_FREE_RXD: to-be-defined. 70 * 71 * Channel opening flags. Reserved for future usage. 72 */ 73 typedef enum xge_hal_channel_flag_e { 74 XGE_HAL_CHANNEL_FLAG_NONE = 0x0, 75 XGE_HAL_CHANNEL_FLAG_USE_TX_LOCK = 0x1, 76 XGE_HAL_CHANNEL_FLAG_FREE_RXD = 0x2 77 } xge_hal_channel_flag_e; 78 79 /** 80 * enum xge_hal_dtr_state_e - Descriptor (DTR) state. 81 * @XGE_HAL_DTR_STATE_NONE: Invalid state. 82 * @XGE_HAL_DTR_STATE_AVAIL: Descriptor is available for reservation 83 * (via xge_hal_fifo_dtr_reserve(), xge_hal_ring_dtr_reserve(), etc.). 84 * @XGE_HAL_DTR_STATE_POSTED: Descriptor is posted for processing by the 85 * device. 86 * @XGE_HAL_DTR_STATE_FREED: Descriptor is free and can be reused for 87 * filling-in and posting later. 88 * 89 * Xframe/HAL descriptor states. For more on descriptor states and transitions 90 * please refer to ch_intern{}. 91 * 92 * See also: xge_hal_channel_dtr_term_f{}. 93 */ 94 typedef enum xge_hal_dtr_state_e { 95 XGE_HAL_DTR_STATE_NONE = 0, 96 XGE_HAL_DTR_STATE_AVAIL = 1, 97 XGE_HAL_DTR_STATE_POSTED = 2, 98 XGE_HAL_DTR_STATE_FREED = 3 99 } xge_hal_dtr_state_e; 100 101 /** 102 * enum xge_hal_channel_reopen_e - Channel open, close, or reopen option. 103 * @XGE_HAL_CHANNEL_RESET_ONLY: Do not (de)allocate channel; used with 104 * xge_hal_channel_open(), xge_hal_channel_close(). 105 * @XGE_HAL_CHANNEL_OC_NORMAL: Do (de)allocate channel; used with 106 * xge_hal_channel_open(), xge_hal_channel_close(). 107 * 108 * Enumerates options used with channel open and close operations. 109 * The @XGE_HAL_CHANNEL_RESET_ONLY can be used when resetting the device; 110 * in this case there is actually no need to free and then again malloc 111 * the memory (including DMA-able memory) used for channel operation. 112 */ 113 typedef enum xge_hal_channel_reopen_e { 114 XGE_HAL_CHANNEL_RESET_ONLY = 1, 115 XGE_HAL_CHANNEL_OC_NORMAL = 2 116 } xge_hal_channel_reopen_e; 117 118 /** 119 * function xge_hal_channel_callback_f - Channel callback. 120 * @channelh: Channel "containing" 1 or more completed descriptors. 121 * @dtrh: First completed descriptor. 122 * @t_code: Transfer code, as per Xframe User Guide. 123 * Returned by HAL. 124 * @host_control: Opaque 64bit data stored by ULD inside the Xframe 125 * descriptor prior to posting the latter on the channel 126 * via xge_hal_fifo_dtr_post() or xge_hal_ring_dtr_post(). 127 * The @host_control is returned as is to the ULD with each 128 * completed descriptor. 129 * @userdata: Opaque per-channel data specified at channel open 130 * time, via xge_hal_channel_open(). 131 * 132 * Channel completion callback (type declaration). A single per-channel 133 * callback is specified at channel open time, via 134 * xge_hal_channel_open(). 135 * Typically gets called as part of the processing of the Interrupt 136 * Service Routine. 137 * 138 * Channel callback gets called by HAL if, and only if, there is at least 139 * one new completion on a given ring or fifo channel. Upon processing the 140 * first @dtrh ULD is _supposed_ to continue consuming completions 141 * using�one of the following HAL APIs: 142 * - xge_hal_fifo_dtr_next_completed() 143 * or 144 * - xge_hal_ring_dtr_next_completed(). 145 * 146 * Note that failure to process new completions in a timely fashion 147 * leads to XGE_HAL_INF_OUT_OF_DESCRIPTORS condition. 148 * 149 * Non-zero @t_code means failure to process (transmit or receive, depending 150 * on the channel type) the descriptor. 151 * 152 * In the "transmit" case the failure could happen, for instance, when the 153 * link is down, in which case Xframe completes the descriptor because it 154 * is not able to send the data out. 155 * 156 * For details please refer to Xframe User Guide. 157 * 158 * See also: xge_hal_fifo_dtr_next_completed(), 159 * xge_hal_ring_dtr_next_completed(), xge_hal_channel_dtr_term_f{}. 160 */ 161 typedef xge_hal_status_e (*xge_hal_channel_callback_f) 162 (xge_hal_channel_h channelh, xge_hal_dtr_h dtrh, 163 u8 t_code, void *userdata); 164 165 /** 166 * function xge_hal_channel_dtr_init_f - Initialize descriptor callback. 167 * @channelh: Channel "containing" the @dtrh descriptor. 168 * @dtrh: Descriptor. 169 * @index: Index of the descriptor in the channel's set of descriptors. 170 * @userdata: Per-channel user data (a.k.a. context) specified at 171 * channel open time, via xge_hal_channel_open(). 172 * @reopen: See xge_hal_channel_reopen_e{}. 173 * 174 * Initialize descriptor callback. Unless NULL is specified in the 175 * xge_hal_channel_attr_t{} structure passed to xge_hal_channel_open()), 176 * HAL invokes the callback as part of the xge_hal_channel_open() 177 * implementation. 178 * For the ring type of channel the ULD is expected to fill in this descriptor 179 * with buffer(s) and control information. 180 * For the fifo type of channel the ULD could use the callback to 181 * pre-set DMA mappings and/or alignment buffers. 182 * 183 * See also: xge_hal_channel_attr_t{}, xge_hal_channel_dtr_term_f{}. 184 */ 185 typedef xge_hal_status_e (*xge_hal_channel_dtr_init_f) 186 (xge_hal_channel_h channelh, 187 xge_hal_dtr_h dtrh, 188 int index, 189 void *userdata, 190 xge_hal_channel_reopen_e reopen); 191 192 /** 193 * function xge_hal_channel_dtr_term_f - Terminate descriptor callback. 194 * @channelh: Channel "containing" the @dtrh descriptor. 195 * @dtrh: First completed descriptor. 196 * @state: One of the xge_hal_dtr_state_e{} enumerated states. 197 * @userdata: Per-channel user data (a.k.a. context) specified at 198 * channel open time, via xge_hal_channel_open(). 199 * @reopen: See xge_hal_channel_reopen_e{}. 200 * 201 * Terminate descriptor callback. Unless NULL is specified in the 202 * xge_hal_channel_attr_t{} structure passed to xge_hal_channel_open()), 203 * HAL invokes the callback as part of closing the corresponding 204 * channel, prior to de-allocating the channel and associated data 205 * structures (including descriptors). 206 * ULD should utilize the callback to (for instance) unmap 207 * and free DMA data buffers associated with the posted (state = 208 * XGE_HAL_DTR_STATE_POSTED) descriptors, 209 * as well as other relevant cleanup functions. 210 * 211 * See also: xge_hal_channel_attr_t{}, xge_hal_channel_dtr_init_f{}. 212 */ 213 typedef void (*xge_hal_channel_dtr_term_f) (xge_hal_channel_h channelh, 214 xge_hal_dtr_h dtrh, 215 xge_hal_dtr_state_e state, 216 void *userdata, 217 xge_hal_channel_reopen_e reopen); 218 219 220 /** 221 * struct xge_hal_channel_attr_t - Channel open "template". 222 * @type: xge_hal_channel_type_e channel type. 223 * @post_qid: Queue ID to post descriptors. For the link layer this 224 * number should be in the 0..7 range. 225 * @compl_qid: Completion queue ID. Must be set to zero for the link layer. 226 * @callback: Channel completion callback. HAL invokes the callback when there 227 * are new completions on that channel. In many implementations 228 * the @callback executes in the hw interrupt context. 229 * @dtr_init: Channel's descriptor-initialize callback. 230 * See xge_hal_channel_dtr_init_f{}. 231 * If not NULL, HAL invokes the callback when opening 232 * the channel via xge_hal_channel_open(). 233 * @dtr_term: Channel's descriptor-terminate callback. If not NULL, 234 * HAL invokes the callback when closing the corresponding channel. 235 * See also xge_hal_channel_dtr_term_f{}. 236 * @userdata: User-defined "context" of _that_ channel. Passed back to the 237 * user as one of the @callback, @dtr_init, and @dtr_term arguments. 238 * @sq_config: Send queue config 239 * @hrq_config: HW receive queue config 240 * @hcq_config: HW completion queue config 241 * @lrq_config: LRO receive queue config 242 * @lcq_config: LRO completion queue config 243 * @dmq_config: Down Message queue config 244 * @umq_config: Up Message queue config 245 * 246 * @per_dtr_space: If specified (i.e., greater than zero): extra space 247 * reserved by HAL per each transmit or receive (depending on the 248 * channel type) descriptor. Can be used to store, 249 * and retrieve on completion, information specific 250 * to the upper-layer. 251 * @flags: xge_hal_channel_flag_e enumerated flags. 252 * 253 * Channel open "template". User fills the structure with channel 254 * attributes and passes it to xge_hal_channel_open(). 255 * Usage: See ex_open{}. 256 */ 257 typedef struct xge_hal_channel_attr_t { 258 xge_hal_channel_type_e type; 259 int post_qid; 260 int compl_qid; 261 xge_hal_channel_callback_f callback; 262 xge_hal_channel_dtr_init_f dtr_init; 263 xge_hal_channel_dtr_term_f dtr_term; 264 void *userdata; 265 int per_dtr_space; 266 xge_hal_channel_flag_e flags; 267 } xge_hal_channel_attr_t; 268 269 /* 270 * xge_hal_channel_t 271 * ---------- complete/free section --------------- 272 * @item: List item; used to maintain a list of open channels. 273 * @callback: Channel completion callback. See 274 * xge_hal_channel_callback_f. 275 * @compl_index: Completion index. At any point in time points on the 276 * position in the channel, which will contain next 277 * to-be-completed descriptor. 278 * @length: Channel length. Currently allocated number of descriptors. 279 * The channel length "grows" when more descriptors get allocated. 280 * See _hal_mempool_grow. 281 * @free_arr: Free array. Contains completed descriptors that were freed 282 * (i.e., handed over back to HAL) by ULD. 283 * See xge_hal_fifo_dtr_free(), xge_hal_ring_dtr_free(). 284 * @free_lock: Lock to protect @free_arr. 285 * ----------- reserve/post section --------------- 286 * @post_index: Post index. At any point in time points on the 287 * position in the channel, which'll contain next to-be-posted 288 * descriptor. 289 * @post_lock: Lock to serialize multiple concurrent "posters" of descriptors 290 * on the given channel. 291 * @reserve_arr: Reserve array. Contains descriptors that can be reserved 292 * by ULD for the subsequent send or receive operation. 293 * See xge_hal_fifo_dtr_reserve(), 294 * xge_hal_ring_dtr_reserve(). 295 * @reserve_length: Length of the @reserve_arr. The length dynamically 296 * changes: it decrements each time descriptor is reserved. 297 * @reserve_lock: Lock to serialize multiple concurrent threads accessing 298 * @reserve_arr. 299 * @reserve_threshold: Reserve threshold. Minimal number of free descriptors 300 * that ought to be preserved in the channel at all times. 301 * Note that @reserve_threshold >= 0 && 302 * @reserve_threshold < @reserve_max. 303 * ------------ common section -------------------- 304 * @devh: Device handle. HAL device object that contains _this_ channel. 305 * @dmah: Channel's DMA address. Used to synchronize (to/from device) 306 * descriptors. 307 * @regh0: Base address of the device memory space handle. Copied from HAL device 308 * at channel open time. 309 * @regh1: Base address of the device memory space handle. Copied from HAL device 310 * at channel open time. 311 * @userdata: Per-channel opaque (void*) user-defined context, which may be 312 * upper-layer driver object, ULP connection, etc. 313 * Once channel is open, @userdata is passed back to user via 314 * xge_hal_channel_callback_f. 315 * @work_arr: Work array. Contains descriptors posted to the channel. 316 * Note that at any point in time @work_arr contains 3 types of 317 * descriptors: 318 * 1) posted but not yet consumed by Xframe device; 319 * 2) consumed but not yet completed; 320 * 3) completed but not yet freed 321 * (via xge_hal_fifo_dtr_free() or xge_hal_ring_dtr_free()) 322 * @saved_arr: Array used internally to optimize channel full-duplex 323 * operation. 324 * @stats: Channel statistcis. Includes HAL internal counters, including 325 * for instance, number of times out-of-descriptors 326 * (see XGE_HAL_INF_OUT_OF_DESCRIPTORS) condition happened. 327 * ------------- "slow" section ------------------ 328 * @type: Channel type. See xge_hal_channel_type_e{}. 329 * @post_qid: Identifies Xframe queue used for posting descriptors. 330 * @compl_qid: Identifies Xframe completion queue. 331 * @flags: Channel flags. See xge_hal_channel_flag_e{}. 332 * @reserve_initial: Initial number of descriptors allocated at channel open 333 * time (see xge_hal_channel_open()). The number of 334 * channel descriptors can grow at runtime 335 * up to @reserve_max value. 336 * @reserve_max: Maximum number of channel descriptors. See @reserve_initial. 337 * @is_open: True, if channel is open; false - otherwise. 338 * @per_dtr_space: Per-descriptor space (in bytes) that channel user can utilize 339 * to store per-operation control information. 340 * HAL channel object. HAL devices (see xge_hal_device_t{}) contains 341 * zero or more channels. HAL channel contains zero or more descriptors. The 342 * latter are used by ULD(s) to manage the device and/or send and receive data 343 * to remote peer(s) via the channel. 344 * 345 * See also: xge_hal_channel_type_e{}, xge_hal_channel_flag_e, 346 * xge_hal_channel_callback_f{} 347 */ 348 typedef struct { 349 /* complete/free section */ 350 xge_list_t item; 351 xge_hal_channel_callback_f callback; 352 void **free_arr; 353 int length; 354 int free_length; 355 #if defined(XGE_HAL_RX_MULTI_FREE_IRQ) || defined(XGE_HAL_TX_MULTI_FREE_IRQ) || \ 356 defined(XGE_HAL_RX_MULTI_FREE) || defined(XGE_HAL_TX_MULTI_FREE) 357 spinlock_t free_lock; 358 #endif 359 int compl_index; 360 unsigned int usage_cnt; 361 unsigned int poll_bytes; 362 int unused0; 363 364 /* reserve/post data path section */ 365 #ifdef __XGE_WIN__ 366 int __xge_os_attr_cacheline_aligned 367 post_index; 368 #else 369 int post_index 370 __xge_os_attr_cacheline_aligned; 371 #endif 372 spinlock_t reserve_lock; 373 spinlock_t post_lock; 374 375 void **reserve_arr; 376 int reserve_length; 377 int reserve_threshold; 378 int reserve_top; 379 int unused1; 380 381 /* common section */ 382 xge_hal_device_h devh; 383 pci_dev_h pdev; 384 pci_reg_h regh0; 385 pci_reg_h regh1; 386 void *userdata; 387 void **work_arr; 388 void **saved_arr; 389 void **orig_arr; 390 xge_hal_stats_channel_info_t stats; 391 392 /* slow section */ 393 xge_hal_channel_type_e type; 394 int post_qid; 395 int compl_qid; 396 xge_hal_channel_flag_e flags; 397 int reserve_initial; 398 int reserve_max; 399 int is_open; 400 int per_dtr_space; 401 xge_hal_channel_dtr_term_f dtr_term; 402 xge_hal_channel_dtr_init_f dtr_init; 403 xge_hal_msix_vector_t msix_vect; 404 #if defined(XGE_HAL_MSI) 405 u32 msi_msg; 406 u8 rti; 407 u8 tti; 408 u16 unused2; 409 #endif 410 #if defined(XGE_HAL_MSI_X) 411 u64 msix_address; 412 u32 msix_data; 413 int msix_idx; 414 #endif 415 unsigned int magic; 416 #ifdef __XGE_WIN__ 417 } __xge_os_attr_cacheline_aligned xge_hal_channel_t ; 418 #else 419 } xge_hal_channel_t __xge_os_attr_cacheline_aligned; 420 #endif 421 422 /* ========================== CHANNEL PRIVATE API ========================= */ 423 424 xge_hal_status_e 425 __hal_channel_initialize(xge_hal_channel_h channelh, 426 xge_hal_channel_attr_t *attr, void **reserve_arr, 427 int reserve_initial, int reserve_max, int reserve_threshold); 428 429 void __hal_channel_terminate(xge_hal_channel_h channelh); 430 431 xge_hal_channel_t* 432 __hal_channel_allocate(xge_hal_device_h devh, int post_qid, 433 xge_hal_channel_type_e type); 434 435 void __hal_channel_free(xge_hal_channel_t *channel); 436 437 void __hal_channel_xmsi_set(xge_hal_channel_h channelh); 438 439 static inline int 440 __hal_channel_msix_idx(xge_hal_channel_h channelh) 441 { 442 return ((xge_hal_channel_t*)channelh)->msix_vect.idx; 443 } 444 445 #if defined(XGE_DEBUG_FP) && (XGE_DEBUG_FP & XGE_DEBUG_FP_CHANNEL) 446 #define __HAL_STATIC_CHANNEL 447 #define __HAL_INLINE_CHANNEL 448 449 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL xge_hal_status_e 450 __hal_channel_dtr_alloc(xge_hal_channel_h channelh, xge_hal_dtr_h *dtrh); 451 452 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void 453 __hal_channel_dtr_post(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh); 454 455 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void 456 __hal_channel_dtr_try_complete(xge_hal_channel_h channelh, xge_hal_dtr_h *dtrh); 457 458 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void 459 __hal_channel_dtr_complete(xge_hal_channel_h channelh); 460 461 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void 462 __hal_channel_dtr_free(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh); 463 464 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void 465 __hal_channel_dtr_dealloc(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh); 466 467 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void 468 __hal_channel_dtr_restore(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh, 469 int offset); 470 471 /* ========================== CHANNEL PUBLIC API ========================= */ 472 473 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL int 474 xge_hal_channel_dtr_count(xge_hal_channel_h channelh); 475 476 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void* 477 xge_hal_channel_userdata(xge_hal_channel_h channelh); 478 479 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL int 480 xge_hal_channel_id(xge_hal_channel_h channelh); 481 482 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL int 483 xge_hal_check_alignment(dma_addr_t dma_pointer, int size, int alignment, 484 int copy_size); 485 486 #else /* XGE_FASTPATH_EXTERN */ 487 #define __HAL_STATIC_CHANNEL static 488 #define __HAL_INLINE_CHANNEL inline 489 #include "xgehal-channel-fp.c" 490 #endif /* XGE_FASTPATH_INLINE */ 491 492 xge_hal_status_e 493 xge_hal_channel_open(xge_hal_device_h hldev, xge_hal_channel_attr_t *attr, 494 xge_hal_channel_h *channel, 495 xge_hal_channel_reopen_e reopen); 496 497 void xge_hal_channel_close(xge_hal_channel_h channelh, 498 xge_hal_channel_reopen_e reopen); 499 500 void xge_hal_channel_abort(xge_hal_channel_h channelh, 501 xge_hal_channel_reopen_e reopen); 502 503 __EXTERN_END_DECLS 504 505 #endif /* XGE_HAL_CHANNEL_H */ 506