1227569Sphilip/*- 2300607Sarybchik * Copyright (c) 2010-2016 Solarflare Communications Inc. 3227569Sphilip * All rights reserved. 4227569Sphilip * 5227569Sphilip * This software was developed in part by Philip Paeps under contract for 6227569Sphilip * Solarflare Communications, Inc. 7227569Sphilip * 8227569Sphilip * Redistribution and use in source and binary forms, with or without 9283514Sarybchik * modification, are permitted provided that the following conditions are met: 10227569Sphilip * 11283514Sarybchik * 1. Redistributions of source code must retain the above copyright notice, 12283514Sarybchik * this list of conditions and the following disclaimer. 13283514Sarybchik * 2. Redistributions in binary form must reproduce the above copyright notice, 14283514Sarybchik * this list of conditions and the following disclaimer in the documentation 15283514Sarybchik * and/or other materials provided with the distribution. 16227569Sphilip * 17283514Sarybchik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18283514Sarybchik * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 19283514Sarybchik * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20283514Sarybchik * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21283514Sarybchik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22283514Sarybchik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23283514Sarybchik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 24283514Sarybchik * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25283514Sarybchik * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26283514Sarybchik * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27283514Sarybchik * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28283514Sarybchik * 29283514Sarybchik * The views and conclusions contained in the software and documentation are 30283514Sarybchik * those of the authors and should not be interpreted as representing official 31283514Sarybchik * policies, either expressed or implied, of the FreeBSD Project. 32283514Sarybchik * 33227569Sphilip * $FreeBSD: stable/11/sys/dev/sfxge/sfxge_tx.h 342455 2018-12-25 07:39:34Z arybchik $ 34227569Sphilip */ 35227569Sphilip 36227569Sphilip#ifndef _SFXGE_TX_H 37272325Sgnn#define _SFXGE_TX_H 38227569Sphilip 39227569Sphilip#include <netinet/in.h> 40227569Sphilip#include <netinet/ip.h> 41227569Sphilip#include <netinet/tcp.h> 42227569Sphilip 43291584Sarybchik/* If defined, parse TX packets directly in if_transmit 44291584Sarybchik * for better cache locality and reduced time under TX lock 45291584Sarybchik */ 46291584Sarybchik#define SFXGE_TX_PARSE_EARLY 1 47291584Sarybchik 48279094Sarybchik/* Maximum size of TSO packet */ 49279094Sarybchik#define SFXGE_TSO_MAX_SIZE (65535) 50279094Sarybchik 51279094Sarybchik/* 52279094Sarybchik * Maximum number of segments to be created for a TSO packet. 53279094Sarybchik * Allow for a reasonable minimum MSS of 512. 54279094Sarybchik */ 55279094Sarybchik#define SFXGE_TSO_MAX_SEGS howmany(SFXGE_TSO_MAX_SIZE, 512) 56279094Sarybchik 57227569Sphilip/* Maximum number of DMA segments needed to map an mbuf chain. With 58227569Sphilip * TSO, the mbuf length may be just over 64K, divided into 2K mbuf 59291488Sarybchik * clusters taking into account that the first may be not 2K cluster 60291488Sarybchik * boundary aligned. 61291569Sarybchik * Packet header may be split into two segments because of, for example, 62291569Sarybchik * VLAN header insertion. 63291488Sarybchik * The chain could be longer than this initially, but can be shortened 64291488Sarybchik * with m_collapse(). 65227569Sphilip */ 66279094Sarybchik#define SFXGE_TX_MAPPING_MAX_SEG \ 67291569Sarybchik (2 + howmany(SFXGE_TSO_MAX_SIZE, MCLBYTES) + 1) 68227569Sphilip 69227569Sphilip/* 70227569Sphilip * Buffer mapping flags. 71227569Sphilip * 72227569Sphilip * Buffers and DMA mappings must be freed when the last descriptor 73227569Sphilip * referring to them is completed. Set the TX_BUF_UNMAP and 74227569Sphilip * TX_BUF_MBUF flags on the last descriptor generated for an mbuf 75227569Sphilip * chain. Set only the TX_BUF_UNMAP flag on a descriptor referring to 76227569Sphilip * a heap buffer. 77227569Sphilip */ 78227569Sphilipenum sfxge_tx_buf_flags { 79227569Sphilip TX_BUF_UNMAP = 1, 80227569Sphilip TX_BUF_MBUF = 2, 81227569Sphilip}; 82227569Sphilip 83227569Sphilip/* 84227569Sphilip * Buffer mapping information for descriptors in flight. 85227569Sphilip */ 86227569Sphilipstruct sfxge_tx_mapping { 87227569Sphilip union { 88227569Sphilip struct mbuf *mbuf; 89227569Sphilip caddr_t heap_buf; 90227569Sphilip } u; 91227569Sphilip bus_dmamap_t map; 92227569Sphilip enum sfxge_tx_buf_flags flags; 93227569Sphilip}; 94227569Sphilip 95277895Sarybchik#define SFXGE_TX_DPL_GET_PKT_LIMIT_DEFAULT (64 * 1024) 96277895Sarybchik#define SFXGE_TX_DPL_GET_NON_TCP_PKT_LIMIT_DEFAULT 1024 97280164Sarybchik#define SFXGE_TX_DPL_PUT_PKT_LIMIT_DEFAULT 1024 98227569Sphilip 99227569Sphilip/* 100227569Sphilip * Deferred packet list. 101227569Sphilip */ 102227569Sphilipstruct sfxge_tx_dpl { 103277895Sarybchik unsigned int std_get_max; /* Maximum number of packets 104272331Sgnn * in get list */ 105277895Sarybchik unsigned int std_get_non_tcp_max; /* Maximum number 106277895Sarybchik * of non-TCP packets 107277895Sarybchik * in get list */ 108277895Sarybchik unsigned int std_put_max; /* Maximum number of packets 109272331Sgnn * in put list */ 110277895Sarybchik uintptr_t std_put; /* Head of put list. */ 111277895Sarybchik struct mbuf *std_get; /* Head of get list. */ 112277895Sarybchik struct mbuf **std_getp; /* Tail of get list. */ 113277895Sarybchik unsigned int std_get_count; /* Packets in get list. */ 114277895Sarybchik unsigned int std_get_non_tcp_count; /* Non-TCP packets 115277895Sarybchik * in get list */ 116277895Sarybchik unsigned int std_get_hiwat; /* Packets in get list 117277895Sarybchik * high watermark */ 118279231Sarybchik unsigned int std_put_hiwat; /* Packets in put list 119279231Sarybchik * high watermark */ 120227569Sphilip}; 121227569Sphilip 122227569Sphilip 123227569Sphilip#define SFXGE_TX_BUFFER_SIZE 0x400 124227569Sphilip#define SFXGE_TX_HEADER_SIZE 0x100 125227569Sphilip#define SFXGE_TX_COPY_THRESHOLD 0x200 126227569Sphilip 127227569Sphilipenum sfxge_txq_state { 128227569Sphilip SFXGE_TXQ_UNINITIALIZED = 0, 129227569Sphilip SFXGE_TXQ_INITIALIZED, 130227569Sphilip SFXGE_TXQ_STARTED 131227569Sphilip}; 132227569Sphilip 133227569Sphilipenum sfxge_txq_type { 134227569Sphilip SFXGE_TXQ_NON_CKSUM = 0, 135227569Sphilip SFXGE_TXQ_IP_CKSUM, 136227569Sphilip SFXGE_TXQ_IP_TCP_UDP_CKSUM, 137227569Sphilip SFXGE_TXQ_NTYPES 138227569Sphilip}; 139227569Sphilip 140342455Sarybchik#define SFXGE_EVQ0_N_TXQ(_sc) \ 141342455Sarybchik ((_sc)->txq_dynamic_cksum_toggle_supported ? \ 142342455Sarybchik 1 : SFXGE_TXQ_NTYPES) 143342454Sarybchik 144272328Sgnn#define SFXGE_TXQ_UNBLOCK_LEVEL(_entries) (EFX_TXQ_LIMIT(_entries) / 4) 145227569Sphilip 146227569Sphilip#define SFXGE_TX_BATCH 64 147227569Sphilip 148278250Sarybchik#define SFXGE_TXQ_LOCK_INIT(_txq, _ifname, _txq_index) \ 149278250Sarybchik do { \ 150278250Sarybchik struct sfxge_txq *__txq = (_txq); \ 151278250Sarybchik \ 152278250Sarybchik snprintf((__txq)->lock_name, \ 153278250Sarybchik sizeof((__txq)->lock_name), \ 154278250Sarybchik "%s:txq%u", (_ifname), (_txq_index)); \ 155278250Sarybchik mtx_init(&(__txq)->lock, (__txq)->lock_name, \ 156278250Sarybchik NULL, MTX_DEF); \ 157278250Sarybchik } while (B_FALSE) 158278221Sarybchik#define SFXGE_TXQ_LOCK_DESTROY(_txq) \ 159278221Sarybchik mtx_destroy(&(_txq)->lock) 160278221Sarybchik#define SFXGE_TXQ_LOCK(_txq) \ 161280376Sarybchik mtx_lock(&(_txq)->lock) 162278221Sarybchik#define SFXGE_TXQ_TRYLOCK(_txq) \ 163280376Sarybchik mtx_trylock(&(_txq)->lock) 164278221Sarybchik#define SFXGE_TXQ_UNLOCK(_txq) \ 165280376Sarybchik mtx_unlock(&(_txq)->lock) 166278221Sarybchik#define SFXGE_TXQ_LOCK_ASSERT_OWNED(_txq) \ 167280376Sarybchik mtx_assert(&(_txq)->lock, MA_OWNED) 168282942Sarybchik#define SFXGE_TXQ_LOCK_ASSERT_NOTOWNED(_txq) \ 169282942Sarybchik mtx_assert(&(_txq)->lock, MA_NOTOWNED) 170278221Sarybchik 171278221Sarybchik 172227569Sphilipstruct sfxge_txq { 173227569Sphilip /* The following fields should be written very rarely */ 174227569Sphilip struct sfxge_softc *sc; 175227569Sphilip enum sfxge_txq_state init_state; 176227569Sphilip enum sfxge_flush_state flush_state; 177294077Sarybchik unsigned int tso_fw_assisted; 178227569Sphilip enum sfxge_txq_type type; 179227569Sphilip unsigned int evq_index; 180227569Sphilip efsys_mem_t mem; 181227569Sphilip unsigned int buf_base_id; 182272328Sgnn unsigned int entries; 183272328Sgnn unsigned int ptr_mask; 184283514Sarybchik unsigned int max_pkt_desc; 185227569Sphilip 186227569Sphilip struct sfxge_tx_mapping *stmp; /* Packets in flight. */ 187227569Sphilip bus_dma_tag_t packet_dma_tag; 188283514Sarybchik efx_desc_t *pend_desc; 189227569Sphilip efx_txq_t *common; 190227569Sphilip 191227569Sphilip efsys_mem_t *tsoh_buffer; 192227569Sphilip 193278250Sarybchik char lock_name[SFXGE_LOCK_NAME_MAX]; 194278250Sarybchik 195227569Sphilip /* This field changes more often and is read regularly on both 196227569Sphilip * the initiation and completion paths 197227569Sphilip */ 198227569Sphilip int blocked __aligned(CACHE_LINE_SIZE); 199227569Sphilip 200227569Sphilip /* The following fields change more often, and are used mostly 201227569Sphilip * on the initiation path 202227569Sphilip */ 203227569Sphilip struct mtx lock __aligned(CACHE_LINE_SIZE); 204227569Sphilip struct sfxge_tx_dpl dpl; /* Deferred packet list. */ 205227569Sphilip unsigned int n_pend_desc; 206227569Sphilip unsigned int added; 207227569Sphilip unsigned int reaped; 208283514Sarybchik 209342455Sarybchik /* The last (or constant) set of HW offloads requested on the queue */ 210342455Sarybchik uint16_t hw_cksum_flags; 211342455Sarybchik 212283514Sarybchik /* The last VLAN TCI seen on the queue if FW-assisted tagging is 213283514Sarybchik used */ 214283514Sarybchik uint16_t hw_vlan_tci; 215283514Sarybchik 216227569Sphilip /* Statistics */ 217227569Sphilip unsigned long tso_bursts; 218227569Sphilip unsigned long tso_packets; 219227569Sphilip unsigned long tso_long_headers; 220227569Sphilip unsigned long collapses; 221227569Sphilip unsigned long drops; 222277895Sarybchik unsigned long get_overflow; 223277895Sarybchik unsigned long get_non_tcp_overflow; 224277895Sarybchik unsigned long put_overflow; 225277895Sarybchik unsigned long netdown_drops; 226278255Sarybchik unsigned long tso_pdrop_too_many; 227278255Sarybchik unsigned long tso_pdrop_no_rsrc; 228227569Sphilip 229227569Sphilip /* The following fields change more often, and are used mostly 230227569Sphilip * on the completion path 231227569Sphilip */ 232227569Sphilip unsigned int pending __aligned(CACHE_LINE_SIZE); 233227569Sphilip unsigned int completed; 234277885Sarybchik struct sfxge_txq *next; 235227569Sphilip}; 236227569Sphilip 237277889Sarybchikstruct sfxge_evq; 238277889Sarybchik 239279184Sarybchikextern uint64_t sfxge_tx_get_drops(struct sfxge_softc *sc); 240227569Sphilip 241227569Sphilipextern int sfxge_tx_init(struct sfxge_softc *sc); 242227569Sphilipextern void sfxge_tx_fini(struct sfxge_softc *sc); 243227569Sphilipextern int sfxge_tx_start(struct sfxge_softc *sc); 244227569Sphilipextern void sfxge_tx_stop(struct sfxge_softc *sc); 245277889Sarybchikextern void sfxge_tx_qcomplete(struct sfxge_txq *txq, struct sfxge_evq *evq); 246227569Sphilipextern void sfxge_tx_qflush_done(struct sfxge_txq *txq); 247227569Sphilipextern void sfxge_if_qflush(struct ifnet *ifp); 248227569Sphilipextern int sfxge_if_transmit(struct ifnet *ifp, struct mbuf *m); 249227569Sphilip 250227569Sphilip#endif 251