1227569Sphilip/*- 2227569Sphilip * Copyright (c) 2010-2011 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 9227569Sphilip * modification, are permitted provided that the following conditions 10227569Sphilip * are met: 11227569Sphilip * 1. Redistributions of source code must retain the above copyright 12227569Sphilip * notice, this list of conditions and the following disclaimer. 13227569Sphilip * 2. Redistributions in binary form must reproduce the above copyright 14227569Sphilip * notice, this list of conditions and the following disclaimer in the 15227569Sphilip * documentation and/or other materials provided with the distribution. 16227569Sphilip * 17227569Sphilip * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18227569Sphilip * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19227569Sphilip * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20227569Sphilip * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21227569Sphilip * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22227569Sphilip * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23227569Sphilip * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24227569Sphilip * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25227569Sphilip * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26227569Sphilip * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27227569Sphilip * SUCH DAMAGE. 28227569Sphilip * 29227569Sphilip * $FreeBSD$ 30227569Sphilip */ 31227569Sphilip 32227569Sphilip#ifndef _SFXGE_RX_H 33227569Sphilip#define _SFXGE_RX_H 34227569Sphilip 35227569Sphilip#define SFXGE_MAGIC_RESERVED 0x8000 36227569Sphilip 37227569Sphilip#define SFXGE_MAGIC_DMAQ_LABEL_WIDTH 6 38227569Sphilip#define SFXGE_MAGIC_DMAQ_LABEL_MASK \ 39227569Sphilip ((1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH) - 1) 40227569Sphilip 41227569Sphilip#define SFXGE_MAGIC_RX_QFLUSH_DONE \ 42227569Sphilip (SFXGE_MAGIC_RESERVED | (1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 43227569Sphilip 44227569Sphilip#define SFXGE_MAGIC_RX_QFLUSH_FAILED \ 45227569Sphilip (SFXGE_MAGIC_RESERVED | (2 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 46227569Sphilip 47227569Sphilip#define SFXGE_MAGIC_RX_QREFILL \ 48227569Sphilip (SFXGE_MAGIC_RESERVED | (3 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 49227569Sphilip 50227569Sphilip#define SFXGE_MAGIC_TX_QFLUSH_DONE \ 51227569Sphilip (SFXGE_MAGIC_RESERVED | (4 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 52227569Sphilip 53227569Sphilip#define SFXGE_RX_SCALE_MAX EFX_MAXRSS 54227569Sphilip 55227569Sphilipstruct sfxge_rx_sw_desc { 56227569Sphilip struct mbuf *mbuf; 57227569Sphilip bus_dmamap_t map; 58227569Sphilip int flags; 59227569Sphilip int size; 60227569Sphilip}; 61227569Sphilip 62227569Sphilip/** 63227569Sphilip * struct sfxge_lro_conn - Connection state for software LRO 64227569Sphilip * @link: Link for hash table and free list. 65227569Sphilip * @active_link: Link for active_conns list 66227569Sphilip * @l2_id: Identifying information from layer 2 67227569Sphilip * @conn_hash: Hash of connection 4-tuple 68227569Sphilip * @nh: IP (v4 or v6) header of super-packet 69227569Sphilip * @source: Source TCP port number 70227569Sphilip * @dest: Destination TCP port number 71227569Sphilip * @n_in_order_pkts: Number of in-order packets with payload. 72227569Sphilip * @next_seq: Next in-order sequence number. 73227569Sphilip * @last_pkt_ticks: Time we last saw a packet on this connection. 74227569Sphilip * @mbuf: The mbuf we are currently holding. 75227569Sphilip * If %NULL, then all following fields are undefined. 76227569Sphilip * @mbuf_tail: The tail of the frag_list of mbufs we're holding. 77227569Sphilip * Only valid after at least one merge. 78227569Sphilip * @th_last: The TCP header of the last packet merged. 79227569Sphilip * @next_buf: The next RX buffer to process. 80227569Sphilip * @next_eh: Ethernet header of the next buffer. 81227569Sphilip * @next_nh: IP header of the next buffer. 82227569Sphilip * @delivered: True if we've delivered a payload packet up this interrupt. 83227569Sphilip */ 84227569Sphilipstruct sfxge_lro_conn { 85227569Sphilip TAILQ_ENTRY(sfxge_lro_conn) link; 86227569Sphilip LIST_ENTRY(sfxge_lro_conn) active_link; 87227569Sphilip uint16_t l2_id; 88227569Sphilip uint32_t conn_hash; 89227569Sphilip void *nh; 90227569Sphilip uint16_t source, dest; 91227569Sphilip int n_in_order_pkts; 92227569Sphilip unsigned next_seq; 93227569Sphilip unsigned last_pkt_ticks; 94227569Sphilip struct mbuf *mbuf; 95227569Sphilip struct mbuf *mbuf_tail; 96227569Sphilip struct tcphdr *th_last; 97227569Sphilip struct sfxge_rx_sw_desc next_buf; 98227569Sphilip void *next_eh; 99227569Sphilip void *next_nh; 100227569Sphilip int delivered; 101227569Sphilip}; 102227569Sphilip 103227569Sphilip/** 104227569Sphilip * struct sfxge_lro_state - Port state for software LRO 105227569Sphilip * @sc: The associated NIC. 106227569Sphilip * @conns_mask: Number of hash buckets - 1. 107227569Sphilip * @conns: Hash buckets for tracked connections. 108227569Sphilip * @conns_n: Length of linked list for each hash bucket. 109227569Sphilip * @active_conns: Connections that are holding a packet. 110227569Sphilip * Connections are self-linked when not in this list. 111227569Sphilip * @free_conns: Free sfxge_lro_conn instances. 112227569Sphilip * @last_purge_ticks: The value of ticks last time we purged idle 113227569Sphilip * connections. 114227569Sphilip * @n_merges: Number of packets absorbed by LRO. 115227569Sphilip * @n_bursts: Number of bursts spotted by LRO. 116227569Sphilip * @n_slow_start: Number of packets not merged because connection may be in 117227569Sphilip * slow-start. 118227569Sphilip * @n_misorder: Number of out-of-order packets seen in tracked streams. 119227569Sphilip * @n_too_many: Incremented when we're trying to track too many streams. 120227569Sphilip * @n_new_stream: Number of distinct streams we've tracked. 121227569Sphilip * @n_drop_idle: Number of streams discarded because they went idle. 122227569Sphilip * @n_drop_closed: Number of streams that have seen a FIN or RST. 123227569Sphilip */ 124227569Sphilipstruct sfxge_lro_state { 125227569Sphilip struct sfxge_softc *sc; 126227569Sphilip unsigned conns_mask; 127227569Sphilip TAILQ_HEAD(sfxge_lro_tailq, sfxge_lro_conn) *conns; 128227569Sphilip unsigned *conns_n; 129227569Sphilip LIST_HEAD(, sfxge_lro_conn) active_conns; 130227569Sphilip TAILQ_HEAD(, sfxge_lro_conn) free_conns; 131227569Sphilip unsigned last_purge_ticks; 132227569Sphilip unsigned n_merges; 133227569Sphilip unsigned n_bursts; 134227569Sphilip unsigned n_slow_start; 135227569Sphilip unsigned n_misorder; 136227569Sphilip unsigned n_too_many; 137227569Sphilip unsigned n_new_stream; 138227569Sphilip unsigned n_drop_idle; 139227569Sphilip unsigned n_drop_closed; 140227569Sphilip}; 141227569Sphilip 142227569Sphilipenum sfxge_flush_state { 143227569Sphilip SFXGE_FLUSH_DONE = 0, 144227569Sphilip SFXGE_FLUSH_PENDING, 145227569Sphilip SFXGE_FLUSH_FAILED 146227569Sphilip}; 147227569Sphilip 148227569Sphilipenum sfxge_rxq_state { 149227569Sphilip SFXGE_RXQ_UNINITIALIZED = 0, 150227569Sphilip SFXGE_RXQ_INITIALIZED, 151227569Sphilip SFXGE_RXQ_STARTED 152227569Sphilip}; 153227569Sphilip 154227569Sphilip#define SFXGE_RX_BATCH 128 155227569Sphilip 156227569Sphilipstruct sfxge_rxq { 157227569Sphilip struct sfxge_softc *sc __aligned(CACHE_LINE_SIZE); 158227569Sphilip unsigned int index; 159227569Sphilip efsys_mem_t mem; 160227569Sphilip unsigned int buf_base_id; 161227569Sphilip enum sfxge_rxq_state init_state; 162227569Sphilip 163227569Sphilip struct sfxge_rx_sw_desc *queue __aligned(CACHE_LINE_SIZE); 164227569Sphilip unsigned int added; 165227569Sphilip unsigned int pending; 166227569Sphilip unsigned int completed; 167227569Sphilip unsigned int loopback; 168227569Sphilip struct sfxge_lro_state lro; 169227569Sphilip struct callout refill_callout; 170227569Sphilip unsigned int refill_delay; 171227569Sphilip 172227569Sphilip efx_rxq_t *common __aligned(CACHE_LINE_SIZE); 173227569Sphilip volatile enum sfxge_flush_state flush_state; 174227569Sphilip}; 175227569Sphilip 176227569Sphilip/* 177227569Sphilip * From sfxge_rx.c. 178227569Sphilip */ 179227569Sphilipextern int sfxge_rx_init(struct sfxge_softc *sc); 180227569Sphilipextern void sfxge_rx_fini(struct sfxge_softc *sc); 181227569Sphilipextern int sfxge_rx_start(struct sfxge_softc *sc); 182227569Sphilipextern void sfxge_rx_stop(struct sfxge_softc *sc); 183227569Sphilipextern void sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop); 184227569Sphilipextern void sfxge_rx_qrefill(struct sfxge_rxq *rxq); 185227569Sphilipextern void sfxge_rx_qflush_done(struct sfxge_rxq *rxq); 186227569Sphilipextern void sfxge_rx_qflush_failed(struct sfxge_rxq *rxq); 187227569Sphilipextern void sfxge_rx_scale_update(void *arg, int npending); 188227569Sphilip 189227569Sphilip#endif 190