freebsd-dev/sys/dev/sfxge/sfxge_rx.h
Andrew Rybchenko 2fb1df8fe0 sfxge(4): compact the first hot part of RxQ control
buf_base_id is used on RxQ control operations only and not used on
datapath.

Sponsored by:   Solarflare Communications, Inc.
MFC after:      2 days
2017-01-27 11:59:02 +00:00

194 lines
6.2 KiB
C

/*-
* Copyright (c) 2010-2016 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
#ifndef _SFXGE_RX_H
#define _SFXGE_RX_H
#include "opt_inet.h"
#include "opt_inet6.h"
#if defined(INET) || defined(INET6)
#define SFXGE_LRO 1
#endif
#define SFXGE_RX_SCALE_MAX EFX_MAXRSS
struct sfxge_rx_sw_desc {
struct mbuf *mbuf;
bus_dmamap_t map;
int flags;
int size;
};
#ifdef SFXGE_LRO
/**
* struct sfxge_lro_conn - Connection state for software LRO
* @link: Link for hash table and free list.
* @active_link: Link for active_conns list
* @l2_id: Identifying information from layer 2
* @conn_hash: Hash of connection 4-tuple
* @nh: IP (v4 or v6) header of super-packet
* @source: Source TCP port number
* @dest: Destination TCP port number
* @n_in_order_pkts: Number of in-order packets with payload.
* @next_seq: Next in-order sequence number.
* @last_pkt_ticks: Time we last saw a packet on this connection.
* @mbuf: The mbuf we are currently holding.
* If %NULL, then all following fields are undefined.
* @mbuf_tail: The tail of the frag_list of mbufs we're holding.
* Only valid after at least one merge.
* @th_last: The TCP header of the last packet merged.
* @next_buf: The next RX buffer to process.
* @next_eh: Ethernet header of the next buffer.
* @next_nh: IP header of the next buffer.
* @delivered: True if we've delivered a payload packet up this interrupt.
*/
struct sfxge_lro_conn {
TAILQ_ENTRY(sfxge_lro_conn) link;
LIST_ENTRY(sfxge_lro_conn) active_link;
uint16_t l2_id;
uint32_t conn_hash;
void *nh;
uint16_t source, dest;
int n_in_order_pkts;
unsigned next_seq;
unsigned last_pkt_ticks;
struct mbuf *mbuf;
struct mbuf *mbuf_tail;
struct tcphdr *th_last;
struct sfxge_rx_sw_desc next_buf;
void *next_eh;
void *next_nh;
int delivered;
};
/**
* struct sfxge_lro_state - Port state for software LRO
* @sc: The associated NIC.
* @conns_mask: Number of hash buckets - 1.
* @conns: Hash buckets for tracked connections.
* @conns_n: Length of linked list for each hash bucket.
* @active_conns: Connections that are holding a packet.
* Connections are self-linked when not in this list.
* @free_conns: Free sfxge_lro_conn instances.
* @last_purge_ticks: The value of ticks last time we purged idle
* connections.
* @n_merges: Number of packets absorbed by LRO.
* @n_bursts: Number of bursts spotted by LRO.
* @n_slow_start: Number of packets not merged because connection may be in
* slow-start.
* @n_misorder: Number of out-of-order packets seen in tracked streams.
* @n_too_many: Incremented when we're trying to track too many streams.
* @n_new_stream: Number of distinct streams we've tracked.
* @n_drop_idle: Number of streams discarded because they went idle.
* @n_drop_closed: Number of streams that have seen a FIN or RST.
*/
struct sfxge_lro_state {
struct sfxge_softc *sc;
unsigned conns_mask;
TAILQ_HEAD(sfxge_lro_tailq, sfxge_lro_conn) *conns;
unsigned *conns_n;
LIST_HEAD(, sfxge_lro_conn) active_conns;
TAILQ_HEAD(, sfxge_lro_conn) free_conns;
unsigned last_purge_ticks;
unsigned n_merges;
unsigned n_bursts;
unsigned n_slow_start;
unsigned n_misorder;
unsigned n_too_many;
unsigned n_new_stream;
unsigned n_drop_idle;
unsigned n_drop_closed;
};
#endif /* SFXGE_LRO */
enum sfxge_flush_state {
SFXGE_FLUSH_DONE = 0,
SFXGE_FLUSH_REQUIRED,
SFXGE_FLUSH_PENDING,
SFXGE_FLUSH_FAILED
};
enum sfxge_rxq_state {
SFXGE_RXQ_UNINITIALIZED = 0,
SFXGE_RXQ_INITIALIZED,
SFXGE_RXQ_STARTED
};
#define SFXGE_RX_BATCH 128
struct sfxge_rxq {
struct sfxge_softc *sc __aligned(CACHE_LINE_SIZE);
unsigned int index;
efsys_mem_t mem;
enum sfxge_rxq_state init_state;
unsigned int entries;
unsigned int ptr_mask;
efx_rxq_t *common;
struct sfxge_rx_sw_desc *queue __aligned(CACHE_LINE_SIZE);
unsigned int added;
unsigned int pushed;
unsigned int pending;
unsigned int completed;
unsigned int loopback;
#ifdef SFXGE_LRO
struct sfxge_lro_state lro;
#endif
unsigned int refill_threshold;
struct callout refill_callout;
unsigned int refill_delay;
volatile enum sfxge_flush_state flush_state __aligned(CACHE_LINE_SIZE);
unsigned int buf_base_id;
};
/*
* From sfxge_rx.c.
*/
extern int sfxge_rx_init(struct sfxge_softc *sc);
extern void sfxge_rx_fini(struct sfxge_softc *sc);
extern int sfxge_rx_start(struct sfxge_softc *sc);
extern void sfxge_rx_stop(struct sfxge_softc *sc);
extern void sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop);
extern void sfxge_rx_qrefill(struct sfxge_rxq *rxq);
extern void sfxge_rx_qflush_done(struct sfxge_rxq *rxq);
extern void sfxge_rx_qflush_failed(struct sfxge_rxq *rxq);
extern void sfxge_rx_scale_update(void *arg, int npending);
#endif