16f45ec7bSml29623 /* 26f45ec7bSml29623 * CDDL HEADER START 36f45ec7bSml29623 * 46f45ec7bSml29623 * The contents of this file are subject to the terms of the 56f45ec7bSml29623 * Common Development and Distribution License (the "License"). 66f45ec7bSml29623 * You may not use this file except in compliance with the License. 76f45ec7bSml29623 * 86f45ec7bSml29623 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96f45ec7bSml29623 * or http://www.opensolaris.org/os/licensing. 106f45ec7bSml29623 * See the License for the specific language governing permissions 116f45ec7bSml29623 * and limitations under the License. 126f45ec7bSml29623 * 136f45ec7bSml29623 * When distributing Covered Code, include this CDDL HEADER in each 146f45ec7bSml29623 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156f45ec7bSml29623 * If applicable, add the following below this CDDL HEADER, with the 166f45ec7bSml29623 * fields enclosed by brackets "[]" replaced with your own identifying 176f45ec7bSml29623 * information: Portions Copyright [yyyy] [name of copyright owner] 186f45ec7bSml29623 * 196f45ec7bSml29623 * CDDL HEADER END 206f45ec7bSml29623 */ 216f45ec7bSml29623 /* 22678453a8Sspeer * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 236f45ec7bSml29623 * Use is subject to license terms. 246f45ec7bSml29623 */ 256f45ec7bSml29623 266f45ec7bSml29623 #ifndef _SYS_NXGE_NXGE_TXDMA_H 276f45ec7bSml29623 #define _SYS_NXGE_NXGE_TXDMA_H 286f45ec7bSml29623 296f45ec7bSml29623 #ifdef __cplusplus 306f45ec7bSml29623 extern "C" { 316f45ec7bSml29623 #endif 326f45ec7bSml29623 33*da14cebeSEric Cheng #include <sys/taskq.h> 346f45ec7bSml29623 #include <sys/nxge/nxge_txdma_hw.h> 356f45ec7bSml29623 #include <npi_txdma.h> 366f45ec7bSml29623 376f45ec7bSml29623 #define TXDMA_PORT_BITMAP(nxgep) (nxgep->pt_config.tx_dma_map) 386f45ec7bSml29623 396f45ec7bSml29623 #define TXDMA_RECLAIM_PENDING_DEFAULT 64 406f45ec7bSml29623 #define TX_FULL_MARK 3 416f45ec7bSml29623 426f45ec7bSml29623 /* 436f45ec7bSml29623 * Transmit load balancing definitions. 446f45ec7bSml29623 */ 456f45ec7bSml29623 #define NXGE_TX_LB_TCPUDP 0 /* default policy */ 466f45ec7bSml29623 #define NXGE_TX_LB_HASH 1 /* from the hint data */ 476f45ec7bSml29623 #define NXGE_TX_LB_DEST_MAC 2 /* Dest. MAC */ 486f45ec7bSml29623 496f45ec7bSml29623 /* 506f45ec7bSml29623 * Descriptor ring empty: 516f45ec7bSml29623 * (1) head index is equal to tail index. 526f45ec7bSml29623 * (2) wrapped around bits are the same. 536f45ec7bSml29623 * Descriptor ring full: 546f45ec7bSml29623 * (1) head index is equal to tail index. 556f45ec7bSml29623 * (2) wrapped around bits are different. 566f45ec7bSml29623 * 576f45ec7bSml29623 */ 586f45ec7bSml29623 #define TXDMA_RING_EMPTY(head, head_wrap, tail, tail_wrap) \ 596f45ec7bSml29623 ((head == tail && head_wrap == tail_wrap) ? B_TRUE : B_FALSE) 606f45ec7bSml29623 616f45ec7bSml29623 #define TXDMA_RING_FULL(head, head_wrap, tail, tail_wrap) \ 626f45ec7bSml29623 ((head == tail && head_wrap != tail_wrap) ? B_TRUE : B_FALSE) 636f45ec7bSml29623 646f45ec7bSml29623 #define TXDMA_DESC_NEXT_INDEX(index, entries, wrap_mask) \ 656f45ec7bSml29623 ((index + entries) & wrap_mask) 666f45ec7bSml29623 676f45ec7bSml29623 #define TXDMA_DRR_WEIGHT_DEFAULT 0x001f 686f45ec7bSml29623 691f8914d5Sml29623 typedef enum { 701f8914d5Sml29623 NXGE_USE_SERIAL = 0, 711f8914d5Sml29623 NXGE_USE_START, 721f8914d5Sml29623 } nxge_tx_mode_t; 731f8914d5Sml29623 746f45ec7bSml29623 typedef struct _tx_msg_t { 756f45ec7bSml29623 nxge_os_block_mv_t flags; /* DMA, BCOPY, DVMA (?) */ 766f45ec7bSml29623 nxge_os_dma_common_t buf_dma; /* premapped buffer blocks */ 776f45ec7bSml29623 nxge_os_dma_handle_t buf_dma_handle; /* premapped buffer handle */ 786f45ec7bSml29623 nxge_os_dma_handle_t dma_handle; /* DMA handle for normal send */ 796f45ec7bSml29623 nxge_os_dma_handle_t dvma_handle; /* Fast DVMA handle */ 802d99c5d4SMichael Speer struct _tx_msg_t *nextp; 816f45ec7bSml29623 826f45ec7bSml29623 p_mblk_t tx_message; 836f45ec7bSml29623 uint32_t tx_msg_size; 846f45ec7bSml29623 size_t bytes_used; 856f45ec7bSml29623 int head; 866f45ec7bSml29623 int tail; 876f45ec7bSml29623 } tx_msg_t, *p_tx_msg_t; 886f45ec7bSml29623 896f45ec7bSml29623 /* 906f45ec7bSml29623 * TX Statistics. 916f45ec7bSml29623 */ 926f45ec7bSml29623 typedef struct _nxge_tx_ring_stats_t { 936f45ec7bSml29623 uint64_t opackets; 946f45ec7bSml29623 uint64_t obytes; 956f45ec7bSml29623 uint64_t oerrors; 966f45ec7bSml29623 976f45ec7bSml29623 uint32_t tx_inits; 986f45ec7bSml29623 uint32_t tx_no_buf; 996f45ec7bSml29623 1006f45ec7bSml29623 uint32_t mbox_err; 1016f45ec7bSml29623 uint32_t pkt_size_err; 1026f45ec7bSml29623 uint32_t tx_ring_oflow; 1036f45ec7bSml29623 uint32_t pre_buf_par_err; 1046f45ec7bSml29623 uint32_t nack_pref; 1056f45ec7bSml29623 uint32_t nack_pkt_rd; 1066f45ec7bSml29623 uint32_t conf_part_err; 1076f45ec7bSml29623 uint32_t pkt_part_err; 1086f45ec7bSml29623 uint32_t tx_starts; 1096f45ec7bSml29623 uint32_t tx_nocanput; 1106f45ec7bSml29623 uint32_t tx_msgdup_fail; 1116f45ec7bSml29623 uint32_t tx_allocb_fail; 1126f45ec7bSml29623 uint32_t tx_no_desc; 1136f45ec7bSml29623 uint32_t tx_dma_bind_fail; 1146f45ec7bSml29623 uint32_t tx_uflo; 1156f45ec7bSml29623 1166f45ec7bSml29623 uint32_t tx_hdr_pkts; 1176f45ec7bSml29623 uint32_t tx_ddi_pkts; 1186f45ec7bSml29623 uint32_t tx_dvma_pkts; 1196f45ec7bSml29623 1206f45ec7bSml29623 uint32_t tx_max_pend; 1216f45ec7bSml29623 uint32_t tx_jumbo_pkts; 1226f45ec7bSml29623 1236f45ec7bSml29623 txdma_ring_errlog_t errlog; 1246f45ec7bSml29623 } nxge_tx_ring_stats_t, *p_nxge_tx_ring_stats_t; 1256f45ec7bSml29623 1266f45ec7bSml29623 typedef struct _tx_ring_t { 1276f45ec7bSml29623 nxge_os_dma_common_t tdc_desc; 1286f45ec7bSml29623 struct _nxge_t *nxgep; 1296f45ec7bSml29623 p_tx_msg_t tx_msg_ring; 1306f45ec7bSml29623 uint32_t tnblocks; 1316f45ec7bSml29623 tx_rng_cfig_t tx_ring_cfig; 1326f45ec7bSml29623 tx_ring_hdl_t tx_ring_hdl; 1336f45ec7bSml29623 tx_ring_kick_t tx_ring_kick; 1346f45ec7bSml29623 tx_cs_t tx_cs; 1356f45ec7bSml29623 tx_dma_ent_msk_t tx_evmask; 1366f45ec7bSml29623 txdma_mbh_t tx_mbox_mbh; 1376f45ec7bSml29623 txdma_mbl_t tx_mbox_mbl; 1386f45ec7bSml29623 log_page_vld_t page_valid; 1396f45ec7bSml29623 log_page_mask_t page_mask_1; 1406f45ec7bSml29623 log_page_mask_t page_mask_2; 1416f45ec7bSml29623 log_page_value_t page_value_1; 1426f45ec7bSml29623 log_page_value_t page_value_2; 1436f45ec7bSml29623 log_page_relo_t page_reloc_1; 1446f45ec7bSml29623 log_page_relo_t page_reloc_2; 1456f45ec7bSml29623 log_page_hdl_t page_hdl; 1466f45ec7bSml29623 txc_dma_max_burst_t max_burst; 1476f45ec7bSml29623 boolean_t cfg_set; 14822c0d73aSspeer #define NXGE_TX_RING_ONLINE 0x00 14922c0d73aSspeer #define NXGE_TX_RING_OFFLINING 0x01 15022c0d73aSspeer #define NXGE_TX_RING_OFFLINED 0x02 15122c0d73aSspeer uint32_t tx_ring_offline; 1526895688eSspeer boolean_t tx_ring_busy; 1536f45ec7bSml29623 1546f45ec7bSml29623 nxge_os_mutex_t lock; 155*da14cebeSEric Cheng mac_ring_handle_t tx_ring_handle; 156*da14cebeSEric Cheng ddi_taskq_t *taskq; 1576f45ec7bSml29623 uint16_t index; 1586f45ec7bSml29623 uint16_t tdc; 1596f45ec7bSml29623 struct nxge_tdc_cfg *tdc_p; 160*da14cebeSEric Cheng int tx_ring_size; 1616f45ec7bSml29623 uint32_t num_chunks; 1626f45ec7bSml29623 1636f45ec7bSml29623 uint_t tx_wrap_mask; 1646f45ec7bSml29623 uint_t rd_index; 1656f45ec7bSml29623 uint_t wr_index; 1666f45ec7bSml29623 boolean_t wr_index_wrap; 1676f45ec7bSml29623 tx_ring_hdl_t ring_head; 1686f45ec7bSml29623 tx_ring_kick_t ring_kick_tail; 1696f45ec7bSml29623 txdma_mailbox_t tx_mbox; 1706f45ec7bSml29623 171*da14cebeSEric Cheng int descs_pending; 1726f45ec7bSml29623 boolean_t queueing; 1736f45ec7bSml29623 1746f45ec7bSml29623 nxge_os_mutex_t sq_lock; 1756f45ec7bSml29623 p_mblk_t head; 1766f45ec7bSml29623 p_mblk_t tail; 1776f45ec7bSml29623 1786f45ec7bSml29623 uint16_t ldg_group_id; 1796f45ec7bSml29623 p_nxge_tx_ring_stats_t tdc_stats; 1806f45ec7bSml29623 1816f45ec7bSml29623 nxge_os_mutex_t dvma_lock; 1826f45ec7bSml29623 uint_t dvma_wr_index; 1836f45ec7bSml29623 uint_t dvma_rd_index; 1846f45ec7bSml29623 uint_t dvma_pending; 1856f45ec7bSml29623 uint_t dvma_available; 1866f45ec7bSml29623 uint_t dvma_wrap_mask; 1876f45ec7bSml29623 1886f45ec7bSml29623 nxge_os_dma_handle_t *dvma_ring; 1896f45ec7bSml29623 1906f45ec7bSml29623 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 1916f45ec7bSml29623 uint64_t hv_tx_buf_base_ioaddr_pp; 1926f45ec7bSml29623 uint64_t hv_tx_buf_ioaddr_size; 1936f45ec7bSml29623 uint64_t hv_tx_cntl_base_ioaddr_pp; 1946f45ec7bSml29623 uint64_t hv_tx_cntl_ioaddr_size; 1956f45ec7bSml29623 boolean_t hv_set; 1966f45ec7bSml29623 #endif 1976f45ec7bSml29623 } tx_ring_t, *p_tx_ring_t; 1986f45ec7bSml29623 1996f45ec7bSml29623 2006f45ec7bSml29623 /* Transmit Mailbox */ 2016f45ec7bSml29623 typedef struct _tx_mbox_t { 2026f45ec7bSml29623 nxge_os_mutex_t lock; 2036f45ec7bSml29623 uint16_t index; 2046f45ec7bSml29623 struct _nxge_t *nxgep; 2056f45ec7bSml29623 uint16_t tdc; 2066f45ec7bSml29623 nxge_os_dma_common_t tx_mbox; 2076f45ec7bSml29623 txdma_mbl_t tx_mbox_l; 2086f45ec7bSml29623 txdma_mbh_t tx_mbox_h; 2096f45ec7bSml29623 } tx_mbox_t, *p_tx_mbox_t; 2106f45ec7bSml29623 2116f45ec7bSml29623 typedef struct _tx_rings_t { 2126f45ec7bSml29623 p_tx_ring_t *rings; 2136f45ec7bSml29623 boolean_t txdesc_allocated; 2146f45ec7bSml29623 uint32_t ndmas; 2156f45ec7bSml29623 nxge_os_dma_common_t tdc_dma; 2166f45ec7bSml29623 nxge_os_dma_common_t tdc_mbox; 2176f45ec7bSml29623 } tx_rings_t, *p_tx_rings_t; 2186f45ec7bSml29623 2196f45ec7bSml29623 2206f45ec7bSml29623 typedef struct _tx_mbox_areas_t { 2216f45ec7bSml29623 p_tx_mbox_t *txmbox_areas_p; 2226f45ec7bSml29623 boolean_t txmbox_allocated; 2236f45ec7bSml29623 } tx_mbox_areas_t, *p_tx_mbox_areas_t; 2246f45ec7bSml29623 2256f45ec7bSml29623 /* 2266f45ec7bSml29623 * Transmit prototypes. 2276f45ec7bSml29623 */ 2286f45ec7bSml29623 nxge_status_t nxge_init_txdma_channels(p_nxge_t); 2296f45ec7bSml29623 void nxge_uninit_txdma_channels(p_nxge_t); 230678453a8Sspeer 231678453a8Sspeer nxge_status_t nxge_init_txdma_channel(p_nxge_t, int); 232678453a8Sspeer void nxge_uninit_txdma_channel(p_nxge_t, int); 233678453a8Sspeer 2346f45ec7bSml29623 void nxge_setup_dma_common(p_nxge_dma_common_t, p_nxge_dma_common_t, 2356f45ec7bSml29623 uint32_t, uint32_t); 2366f45ec7bSml29623 nxge_status_t nxge_reset_txdma_channel(p_nxge_t, uint16_t, 2376f45ec7bSml29623 uint64_t); 2386f45ec7bSml29623 nxge_status_t nxge_init_txdma_channel_event_mask(p_nxge_t, 2396f45ec7bSml29623 uint16_t, p_tx_dma_ent_msk_t); 2406f45ec7bSml29623 nxge_status_t nxge_init_txdma_channel_cntl_stat(p_nxge_t, 2416f45ec7bSml29623 uint16_t, uint64_t); 2426f45ec7bSml29623 nxge_status_t nxge_enable_txdma_channel(p_nxge_t, uint16_t, 2436f45ec7bSml29623 p_tx_ring_t, p_tx_mbox_t); 2446f45ec7bSml29623 2456f45ec7bSml29623 p_mblk_t nxge_tx_pkt_header_reserve(p_mblk_t, uint8_t *); 2466f45ec7bSml29623 int nxge_tx_pkt_nmblocks(p_mblk_t, int *); 2476f45ec7bSml29623 boolean_t nxge_txdma_reclaim(p_nxge_t, p_tx_ring_t, int); 2486f45ec7bSml29623 2496f45ec7bSml29623 void nxge_fill_tx_hdr(p_mblk_t, boolean_t, boolean_t, 250b4d05839Sml29623 int, uint8_t, p_tx_pkt_hdr_all_t, t_uscalar_t, t_uscalar_t); 2516f45ec7bSml29623 2526f45ec7bSml29623 nxge_status_t nxge_txdma_hw_mode(p_nxge_t, boolean_t); 2536f45ec7bSml29623 void nxge_hw_start_tx(p_nxge_t); 2546f45ec7bSml29623 void nxge_txdma_stop(p_nxge_t); 2556f45ec7bSml29623 void nxge_txdma_stop_start(p_nxge_t); 2566f45ec7bSml29623 void nxge_fixup_txdma_rings(p_nxge_t); 2576f45ec7bSml29623 void nxge_txdma_hw_kick(p_nxge_t); 2586f45ec7bSml29623 void nxge_txdma_fix_channel(p_nxge_t, uint16_t); 2596f45ec7bSml29623 void nxge_txdma_fixup_channel(p_nxge_t, p_tx_ring_t, 2606f45ec7bSml29623 uint16_t); 2616f45ec7bSml29623 void nxge_txdma_hw_kick_channel(p_nxge_t, p_tx_ring_t, 2626f45ec7bSml29623 uint16_t); 2636f45ec7bSml29623 2646f45ec7bSml29623 void nxge_txdma_regs_dump(p_nxge_t, int); 2656f45ec7bSml29623 void nxge_txdma_regs_dump_channels(p_nxge_t); 2666f45ec7bSml29623 2676f45ec7bSml29623 void nxge_check_tx_hang(p_nxge_t); 2686f45ec7bSml29623 void nxge_fixup_hung_txdma_rings(p_nxge_t); 2696f45ec7bSml29623 2706f45ec7bSml29623 void nxge_reclaim_rings(p_nxge_t); 2716f45ec7bSml29623 int nxge_txdma_channel_hung(p_nxge_t, 2726f45ec7bSml29623 p_tx_ring_t tx_ring_p, uint16_t); 2736f45ec7bSml29623 int nxge_txdma_hung(p_nxge_t); 2746f45ec7bSml29623 int nxge_txdma_stop_inj_err(p_nxge_t, int); 2756f45ec7bSml29623 void nxge_txdma_inject_err(p_nxge_t, uint32_t, uint8_t); 2766f45ec7bSml29623 277678453a8Sspeer extern nxge_status_t nxge_alloc_tx_mem_pool(p_nxge_t); 278678453a8Sspeer extern nxge_status_t nxge_alloc_txb(p_nxge_t nxgep, int channel); 279678453a8Sspeer extern void nxge_free_txb(p_nxge_t nxgep, int channel); 280678453a8Sspeer 2816f45ec7bSml29623 #ifdef __cplusplus 2826f45ec7bSml29623 } 2836f45ec7bSml29623 #endif 2846f45ec7bSml29623 2856f45ec7bSml29623 #endif /* _SYS_NXGE_NXGE_TXDMA_H */ 286