/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Copyright (c) 2002-2005 Neterion, Inc. * All right Reserved. * * FileName : xgell.h * * Description: Link Layer driver declaration * */ #ifndef _SYS_XGELL_H #define _SYS_XGELL_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif #define XGELL_DESC "Xframe I/II 10Gb Ethernet" #define XGELL_IFNAME "xge" #include /* * The definition of XGELL_RX_BUFFER_RECYCLE_CACHE is an experimental value. * With this value, the lock contention between xgell_rx_buffer_recycle() * and xgell_rx_1b_compl() is reduced to great extent. And multiple rx rings * alleviate the lock contention further since each rx ring has its own mutex. */ #define XGELL_RX_BUFFER_RECYCLE_CACHE XGE_HAL_RING_RXDS_PER_BLOCK(1) * 2 #define MSG_SIZE 64 /* * These default values can be overridden by vaules in xge.conf. * In xge.conf user has to specify actual (not percentages) values. */ #define XGELL_RX_BUFFER_TOTAL XGE_HAL_RING_RXDS_PER_BLOCK(1) * 6 #define XGELL_RX_BUFFER_POST_HIWAT XGE_HAL_RING_RXDS_PER_BLOCK(1) * 5 /* * Multiple rings configuration */ #define XGELL_RX_RING_MAIN 0 #define XGELL_TX_RING_MAIN 0 #define XGELL_RX_RING_NUM_MIN 1 #define XGELL_TX_RING_NUM_MIN 1 #define XGELL_RX_RING_NUM_MAX 8 #define XGELL_TX_RING_NUM_MAX 1 /* TODO */ #define XGELL_RX_RING_NUM_DEFAULT XGELL_RX_RING_NUM_MAX #define XGELL_TX_RING_NUM_DEFAULT XGELL_TX_RING_NUM_MAX #define XGELL_MINTR_NUM_MIN 1 #define XGELL_MINTR_NUM_MAX \ (XGELL_RX_RING_NUM_MAX + XGELL_TX_RING_NUM_MAX + 1) #define XGELL_MINTR_NUM_DEFAULT XGELL_MINTR_NUM_MAX #define XGELL_CONF_GROUP_POLICY_BASIC 0 #define XGELL_CONF_GROUP_POLICY_VIRT 1 #define XGELL_CONF_GROUP_POLICY_PERF 2 #if 0 #if defined(__sparc) #define XGELL_CONF_GROUP_POLICY_DEFAULT XGELL_CONF_GROUP_POLICY_PERF #else #define XGELL_CONF_GROUP_POLICY_DEFAULT XGELL_CONF_GROUP_POLICY_VIRT #endif #else /* * The _PERF configuration enable a fat group of all rx rings, as approachs * better fanout performance of the primary interface. */ #define XGELL_CONF_GROUP_POLICY_DEFAULT XGELL_CONF_GROUP_POLICY_PERF #endif #define XGELL_TX_LEVEL_LOW 8 #define XGELL_TX_LEVEL_HIGH 32 #define XGELL_TX_LEVEL_CHECK 3 #define XGELL_MAX_RING_DEFAULT 8 #define XGELL_MAX_FIFO_DEFAULT 1 /* Control driver to copy or DMA inbound/outbound packets */ #if defined(__sparc) #define XGELL_RX_DMA_LOWAT 256 #define XGELL_TX_DMA_LOWAT 512 #else #define XGELL_RX_DMA_LOWAT 256 #define XGELL_TX_DMA_LOWAT 128 #endif /* * Try to collapse up to XGELL_RX_PKT_BURST packets into single mblk * sequence before mac_rx() is called. */ #define XGELL_RX_PKT_BURST 32 /* About 1s */ #define XGE_DEV_POLL_TICKS drv_usectohz(1000000) #define XGELL_LSO_MAXLEN 65535 #define XGELL_CONF_ENABLE_BY_DEFAULT 1 #define XGELL_CONF_DISABLE_BY_DEFAULT 0 /* LRO configuration */ #define XGE_HAL_DEFAULT_LRO_SG_SIZE 2 /* <=2 LRO fix not required */ #define XGE_HAL_DEFAULT_LRO_FRM_LEN 65535 /* * Default values for tunables used in HAL. Please refer to xgehal-config.h * for more details. */ #define XGE_HAL_DEFAULT_USE_HARDCODE -1 /* Bimodal adaptive schema defaults - ENABLED */ #define XGE_HAL_DEFAULT_BIMODAL_INTERRUPTS -1 #define XGE_HAL_DEFAULT_BIMODAL_TIMER_LO_US 24 #define XGE_HAL_DEFAULT_BIMODAL_TIMER_HI_US 256 /* Interrupt moderation/utilization defaults */ #define XGE_HAL_DEFAULT_TX_URANGE_A 5 #define XGE_HAL_DEFAULT_TX_URANGE_B 15 #define XGE_HAL_DEFAULT_TX_URANGE_C 30 #define XGE_HAL_DEFAULT_TX_UFC_A 15 #define XGE_HAL_DEFAULT_TX_UFC_B 30 #define XGE_HAL_DEFAULT_TX_UFC_C 45 #define XGE_HAL_DEFAULT_TX_UFC_D 60 #define XGE_HAL_DEFAULT_TX_TIMER_CI_EN 1 #define XGE_HAL_DEFAULT_TX_TIMER_AC_EN 1 #define XGE_HAL_DEFAULT_TX_TIMER_VAL 10000 #define XGE_HAL_DEFAULT_INDICATE_MAX_PKTS_B 512 /* bimodal */ #define XGE_HAL_DEFAULT_INDICATE_MAX_PKTS_N 256 /* normal UFC */ #define XGE_HAL_DEFAULT_RX_URANGE_A 10 #define XGE_HAL_DEFAULT_RX_URANGE_B 30 #define XGE_HAL_DEFAULT_RX_URANGE_C 50 #define XGE_HAL_DEFAULT_RX_UFC_A 1 #define XGE_HAL_DEFAULT_RX_UFC_B_J 2 #define XGE_HAL_DEFAULT_RX_UFC_B_N 8 #define XGE_HAL_DEFAULT_RX_UFC_C_J 4 #define XGE_HAL_DEFAULT_RX_UFC_C_N 16 #define XGE_HAL_DEFAULT_RX_UFC_D 32 #define XGE_HAL_DEFAULT_RX_TIMER_AC_EN 1 #define XGE_HAL_DEFAULT_RX_TIMER_VAL 384 #define XGE_HAL_DEFAULT_FIFO_QUEUE_LENGTH_A 1024 #define XGE_HAL_DEFAULT_FIFO_QUEUE_LENGTH_J 2048 #define XGE_HAL_DEFAULT_FIFO_QUEUE_LENGTH_N 4096 #define XGE_HAL_DEFAULT_FIFO_QUEUE_INTR 0 #define XGE_HAL_DEFAULT_FIFO_RESERVE_THRESHOLD 0 #define XGE_HAL_DEFAULT_FIFO_MEMBLOCK_SIZE PAGESIZE /* * This will force HAL to allocate extra copied buffer per TXDL which * size calculated by formula: * * (ALIGNMENT_SIZE * ALIGNED_FRAGS) */ #define XGE_HAL_DEFAULT_FIFO_ALIGNMENT_SIZE 4096 #define XGE_HAL_DEFAULT_FIFO_MAX_ALIGNED_FRAGS 1 #if defined(__sparc) #define XGE_HAL_DEFAULT_FIFO_FRAGS 64 #else #define XGE_HAL_DEFAULT_FIFO_FRAGS 128 #endif #define XGE_HAL_DEFAULT_FIFO_FRAGS_THRESHOLD 18 #define XGE_HAL_DEFAULT_RING_QUEUE_BLOCKS 2 #define XGE_HAL_RING_QUEUE_BUFFER_MODE_DEFAULT 1 #define XGE_HAL_DEFAULT_BACKOFF_INTERVAL_US 64 #define XGE_HAL_DEFAULT_RING_PRIORITY 0 #define XGE_HAL_DEFAULT_RING_MEMBLOCK_SIZE PAGESIZE #define XGE_HAL_DEFAULT_RING_NUM 8 #define XGE_HAL_DEFAULT_TMAC_UTIL_PERIOD 5 #define XGE_HAL_DEFAULT_RMAC_UTIL_PERIOD 5 #define XGE_HAL_DEFAULT_RMAC_HIGH_PTIME 65535 #define XGE_HAL_DEFAULT_MC_PAUSE_THRESHOLD_Q0Q3 187 #define XGE_HAL_DEFAULT_MC_PAUSE_THRESHOLD_Q4Q7 187 #define XGE_HAL_DEFAULT_RMAC_PAUSE_GEN_EN 1 #define XGE_HAL_DEFAULT_RMAC_PAUSE_GEN_DIS 0 #define XGE_HAL_DEFAULT_RMAC_PAUSE_RCV_EN 1 #define XGE_HAL_DEFAULT_RMAC_PAUSE_RCV_DIS 0 #define XGE_HAL_DEFAULT_INITIAL_MTU XGE_HAL_DEFAULT_MTU /* 1500 */ #define XGE_HAL_DEFAULT_ISR_POLLING_CNT 0 #define XGE_HAL_DEFAULT_LATENCY_TIMER 255 #define XGE_HAL_DEFAULT_SHARED_SPLITS 0 #define XGE_HAL_DEFAULT_STATS_REFRESH_TIME 1 #if defined(__sparc) #define XGE_HAL_DEFAULT_MMRB_COUNT XGE_HAL_MAX_MMRB_COUNT #define XGE_HAL_DEFAULT_SPLIT_TRANSACTION XGE_HAL_EIGHT_SPLIT_TRANSACTION #else #define XGE_HAL_DEFAULT_MMRB_COUNT 1 /* 1k */ #define XGE_HAL_DEFAULT_SPLIT_TRANSACTION XGE_HAL_TWO_SPLIT_TRANSACTION #endif /* * Default the size of buffers allocated for ndd interface functions */ #define XGELL_STATS_BUFSIZE 8192 #define XGELL_PCICONF_BUFSIZE 2048 #define XGELL_ABOUT_BUFSIZE 512 #define XGELL_IOCTL_BUFSIZE 64 #define XGELL_DEVCONF_BUFSIZE 8192 /* * Multiple mac address definitions * * We'll use whole MAC Addresses Configuration Memory for unicast addresses, * since current multicast implementation in HAL is by enabling promise mode. */ #define XGE_RX_MULTI_MAC_ADDRESSES_MAX 8 /* per ring group */ typedef struct { int rx_pkt_burst; int rx_buffer_total; int rx_buffer_post_hiwat; int rx_dma_lowat; int tx_dma_lowat; int lso_enable; int msix_enable; int grouping; } xgell_config_t; typedef struct xgell_multi_mac xgell_multi_mac_t; typedef struct xgell_rx_ring xgell_rx_ring_t; typedef struct xgell_tx_ring xgell_tx_ring_t; typedef struct xgelldev xgelldev_t; typedef struct xgell_rx_buffer_t { struct xgell_rx_buffer_t *next; void *vaddr; dma_addr_t dma_addr; ddi_dma_handle_t dma_handle; ddi_acc_handle_t dma_acch; xgell_rx_ring_t *ring; frtn_t frtn; } xgell_rx_buffer_t; /* Buffer pool for one rx ring */ typedef struct xgell_rx_buffer_pool_t { uint_t total; /* total buffers */ uint_t size; /* buffer size */ xgell_rx_buffer_t *head; /* header pointer */ uint_t free; /* free buffers */ uint_t post; /* posted buffers */ uint_t post_hiwat; /* hiwat to stop post */ spinlock_t pool_lock; /* buffer pool lock */ boolean_t live; /* pool status */ xgell_rx_buffer_t *recycle_head; /* recycle list's head */ xgell_rx_buffer_t *recycle_tail; /* recycle list's tail */ uint_t recycle; /* # of rx buffers recycled */ spinlock_t recycle_lock; /* buffer recycle lock */ } xgell_rx_buffer_pool_t; struct xgell_multi_mac { int naddr; /* total supported addresses */ int naddrfree; /* free addresses slots */ ether_addr_t mac_addr[XGE_RX_MULTI_MAC_ADDRESSES_MAX]; boolean_t mac_addr_set[XGE_RX_MULTI_MAC_ADDRESSES_MAX]; }; typedef uint_t (*intr_func_t)(caddr_t, caddr_t); typedef struct xgell_intr { uint_t index; ddi_intr_handle_t *handle; /* DDI interrupt handle */ intr_func_t *function; /* interrupt function */ caddr_t arg; /* interrupt source */ } xgell_intr_t; struct xgell_rx_ring { int index; boolean_t live; /* ring active status */ xge_hal_channel_h channelh; /* hardware channel */ xgelldev_t *lldev; /* driver device */ mac_ring_handle_t ring_handle; /* call back ring handle */ mac_group_handle_t group_handle; /* call back group handle */ uint64_t ring_gen_num; xgell_multi_mac_t mmac; /* per group multiple addrs */ xgell_rx_buffer_pool_t bf_pool; /* per ring buffer pool */ uint64_t rx_pkts; /* total received packets */ uint64_t rx_bytes; /* total received bytes */ int poll_bytes; /* bytes to be polled up */ int polled_bytes; /* total polled bytes */ mblk_t *poll_mp; /* polled messages */ spinlock_t ring_lock; /* per ring lock */ }; struct xgell_tx_ring { int index; boolean_t live; /* ring active status */ xge_hal_channel_h channelh; /* hardware channel */ xgelldev_t *lldev; /* driver device */ mac_ring_handle_t ring_handle; /* call back ring handle */ uint64_t tx_pkts; /* packets sent */ uint64_t tx_bytes; /* bytes sent though the ring */ boolean_t need_resched; }; struct xgelldev { volatile int is_initialized; volatile int in_reset; kmutex_t genlock; mac_handle_t mh; int instance; dev_info_t *dev_info; xge_hal_device_h devh; caddr_t ndp; timeout_id_t timeout_id; int init_rx_rings; int init_tx_rings; int init_rx_groups; int live_rx_rings; int live_tx_rings; xgell_rx_ring_t rx_ring[XGELL_RX_RING_NUM_DEFAULT]; xgell_tx_ring_t tx_ring[XGELL_TX_RING_NUM_DEFAULT]; int tx_copied_max; xgell_intr_t intrs[XGELL_MINTR_NUM_DEFAULT]; ddi_intr_handle_t *intr_table; uint_t intr_table_size; int intr_type; int intr_cnt; uint_t intr_pri; int intr_cap; xgell_config_t config; }; typedef struct { mblk_t *mblk; ddi_dma_handle_t dma_handles[XGE_HAL_DEFAULT_FIFO_FRAGS]; int handle_cnt; } xgell_txd_priv_t; typedef struct { xgell_rx_buffer_t *rx_buffer; } xgell_rxd_priv_t; int xgell_device_alloc(xge_hal_device_h devh, dev_info_t *dev_info, xgelldev_t **lldev_out); void xgell_device_free(xgelldev_t *lldev); int xgell_device_register(xgelldev_t *lldev, xgell_config_t *config); int xgell_device_unregister(xgelldev_t *lldev); void xgell_callback_link_up(void *userdata); void xgell_callback_link_down(void *userdata); int xgell_onerr_reset(xgelldev_t *lldev); void xge_device_poll_now(void *data); int xge_add_intrs(xgelldev_t *lldev); int xge_enable_intrs(xgelldev_t *lldev); void xge_disable_intrs(xgelldev_t *lldev); void xge_rem_intrs(xgelldev_t *lldev); int xgell_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val); int xgell_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val); #ifdef __cplusplus } #endif #endif /* _SYS_XGELL_H */