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