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