1aa97dd1cSKonstantin Ananyev/*
27e18fa1bSKonstantin Ananyev * Copyright (c) 2016-2017  Intel Corporation.
3aa97dd1cSKonstantin Ananyev * Licensed under the Apache License, Version 2.0 (the "License");
4aa97dd1cSKonstantin Ananyev * you may not use this file except in compliance with the License.
5aa97dd1cSKonstantin Ananyev * You may obtain a copy of the License at:
6aa97dd1cSKonstantin Ananyev *
7aa97dd1cSKonstantin Ananyev *     http://www.apache.org/licenses/LICENSE-2.0
8aa97dd1cSKonstantin Ananyev *
9aa97dd1cSKonstantin Ananyev * Unless required by applicable law or agreed to in writing, software
10aa97dd1cSKonstantin Ananyev * distributed under the License is distributed on an "AS IS" BASIS,
11aa97dd1cSKonstantin Ananyev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12aa97dd1cSKonstantin Ananyev * See the License for the specific language governing permissions and
13aa97dd1cSKonstantin Ananyev * limitations under the License.
14aa97dd1cSKonstantin Ananyev */
15aa97dd1cSKonstantin Ananyev
16aa97dd1cSKonstantin Ananyev#ifndef _TCP_STREAM_H_
17aa97dd1cSKonstantin Ananyev#define _TCP_STREAM_H_
18aa97dd1cSKonstantin Ananyev
19aa97dd1cSKonstantin Ananyev#include <rte_vect.h>
20aa97dd1cSKonstantin Ananyev#include <tle_dring.h>
21b8f1ef2bSKonstantin Ananyev#include <tle_memtank.h>
22aa97dd1cSKonstantin Ananyev#include <tle_tcp.h>
23aa97dd1cSKonstantin Ananyev#include <tle_event.h>
24aa97dd1cSKonstantin Ananyev
25aa97dd1cSKonstantin Ananyev#include "stream.h"
26aa97dd1cSKonstantin Ananyev#include "misc.h"
27aa97dd1cSKonstantin Ananyev#include "tcp_misc.h"
28aa97dd1cSKonstantin Ananyev
29aa97dd1cSKonstantin Ananyev#ifdef __cplusplus
30aa97dd1cSKonstantin Ananyevextern "C" {
31aa97dd1cSKonstantin Ananyev#endif
32aa97dd1cSKonstantin Ananyev
33aa97dd1cSKonstantin Ananyevenum {
34aa97dd1cSKonstantin Ananyev	TCP_ST_CLOSED,
35aa97dd1cSKonstantin Ananyev	TCP_ST_LISTEN,
36aa97dd1cSKonstantin Ananyev	TCP_ST_SYN_SENT,
37aa97dd1cSKonstantin Ananyev	TCP_ST_SYN_RCVD,
38aa97dd1cSKonstantin Ananyev	TCP_ST_ESTABLISHED,
39aa97dd1cSKonstantin Ananyev	TCP_ST_FIN_WAIT_1,
40aa97dd1cSKonstantin Ananyev	TCP_ST_FIN_WAIT_2,
41aa97dd1cSKonstantin Ananyev	TCP_ST_CLOSE_WAIT,
42aa97dd1cSKonstantin Ananyev	TCP_ST_CLOSING,
43aa97dd1cSKonstantin Ananyev	TCP_ST_LAST_ACK,
44aa97dd1cSKonstantin Ananyev	TCP_ST_TIME_WAIT,
45aa97dd1cSKonstantin Ananyev	TCP_ST_NUM
46aa97dd1cSKonstantin Ananyev};
47aa97dd1cSKonstantin Ananyev
48aa97dd1cSKonstantin Ananyevenum {
49aa97dd1cSKonstantin Ananyev	TCP_OP_LISTEN =  0x1,
50aa97dd1cSKonstantin Ananyev	TCP_OP_ACCEPT =  0x2,
51aa97dd1cSKonstantin Ananyev	TCP_OP_CONNECT = 0x4,
52aa97dd1cSKonstantin Ananyev	TCP_OP_CLOSE =   0x8,
53aa97dd1cSKonstantin Ananyev};
54aa97dd1cSKonstantin Ananyev
55aa97dd1cSKonstantin Ananyevstruct tcb {
56aa97dd1cSKonstantin Ananyev	volatile uint16_t state;
57aa97dd1cSKonstantin Ananyev	volatile uint16_t uop; /* operations by user performed */
58aa97dd1cSKonstantin Ananyev	struct {
59aa97dd1cSKonstantin Ananyev		uint32_t nxt;
60aa97dd1cSKonstantin Ananyev		uint32_t irs; /* initial received sequence */
61aa97dd1cSKonstantin Ananyev		uint32_t wnd;
62aa97dd1cSKonstantin Ananyev		uint32_t ts;
63aa97dd1cSKonstantin Ananyev		struct {
64aa97dd1cSKonstantin Ananyev			uint32_t seq;
65aa97dd1cSKonstantin Ananyev			uint32_t on;
66aa97dd1cSKonstantin Ananyev		} frs;
67aa97dd1cSKonstantin Ananyev		uint32_t srtt;   /* smoothed round trip time (scaled by >> 3) */
68aa97dd1cSKonstantin Ananyev		uint32_t rttvar; /* rtt variance */
69aa97dd1cSKonstantin Ananyev		uint16_t mss;
70aa97dd1cSKonstantin Ananyev		uint8_t  wscale;
71aa97dd1cSKonstantin Ananyev		uint8_t  dupack;
72aa97dd1cSKonstantin Ananyev	} rcv;
73aa97dd1cSKonstantin Ananyev	struct {
74aa97dd1cSKonstantin Ananyev		uint64_t nxt;
75aa97dd1cSKonstantin Ananyev		uint64_t una;
76aa97dd1cSKonstantin Ananyev		uint64_t rcvr; /* recover RFC 6582 */
77aa97dd1cSKonstantin Ananyev		uint64_t fss;  /* FIN sequence # */
78aa97dd1cSKonstantin Ananyev		uint32_t fastack; /* # of partial acks in fast retransmit */
79aa97dd1cSKonstantin Ananyev		uint32_t wnd;
80aa97dd1cSKonstantin Ananyev		union wui wu; /* window update */
81aa97dd1cSKonstantin Ananyev		uint32_t ack; /* last sent ack */
82aa97dd1cSKonstantin Ananyev		uint32_t ts;
83aa97dd1cSKonstantin Ananyev		uint32_t cwnd;     /* congestion window */
84aa97dd1cSKonstantin Ananyev		uint32_t ssthresh; /* slow start threshold */
85aa97dd1cSKonstantin Ananyev		uint32_t rto;      /* retransmission timeout */
867e18fa1bSKonstantin Ananyev		uint32_t rto_tw;   /* TIME_WAIT retransmission timeout */
87aa97dd1cSKonstantin Ananyev		uint32_t iss;      /* initial send sequence */
88aa97dd1cSKonstantin Ananyev		uint16_t mss;
89aa97dd1cSKonstantin Ananyev		uint8_t  wscale;
90aa97dd1cSKonstantin Ananyev		uint8_t nb_retx; /* number of retransmission */
91aa97dd1cSKonstantin Ananyev		uint8_t nb_retm; /**< max number of retx attempts. */
92aa97dd1cSKonstantin Ananyev	} snd;
93aa97dd1cSKonstantin Ananyev	struct syn_opts so; /* initial syn options. */
94aa97dd1cSKonstantin Ananyev};
95aa97dd1cSKonstantin Ananyev
96aa97dd1cSKonstantin Ananyevstruct tle_tcp_stream {
97aa97dd1cSKonstantin Ananyev
98aa97dd1cSKonstantin Ananyev	struct tle_stream s;
99aa97dd1cSKonstantin Ananyev
1007e18fa1bSKonstantin Ananyev	uint32_t flags;
1017e18fa1bSKonstantin Ananyev	rte_atomic32_t use;
1027e18fa1bSKonstantin Ananyev
103aa97dd1cSKonstantin Ananyev	struct stbl_entry *ste;     /* entry in streams table. */
104aa97dd1cSKonstantin Ananyev	struct tcb tcb;
105aa97dd1cSKonstantin Ananyev
106aa97dd1cSKonstantin Ananyev	struct {
107aa97dd1cSKonstantin Ananyev		void *handle;
108aa97dd1cSKonstantin Ananyev	} timer;
109aa97dd1cSKonstantin Ananyev
110aa97dd1cSKonstantin Ananyev	struct {
111aa97dd1cSKonstantin Ananyev		struct tle_event *ev;
112aa97dd1cSKonstantin Ananyev		struct tle_stream_cb cb;
113aa97dd1cSKonstantin Ananyev	} err;
114aa97dd1cSKonstantin Ananyev
115aa97dd1cSKonstantin Ananyev	struct {
116aa97dd1cSKonstantin Ananyev		struct rte_ring *q;     /* listen (syn) queue */
117aa97dd1cSKonstantin Ananyev		struct ofo *ofo;
118aa97dd1cSKonstantin Ananyev		struct tle_event *ev;    /* user provided recv event. */
119aa97dd1cSKonstantin Ananyev		struct tle_stream_cb cb; /* user provided recv callback. */
120aa97dd1cSKonstantin Ananyev	} rx __rte_cache_aligned;
121aa97dd1cSKonstantin Ananyev
122aa97dd1cSKonstantin Ananyev	struct {
123aa97dd1cSKonstantin Ananyev		rte_atomic32_t arm;  /* when > 0 stream is in to-send queue */
124aa97dd1cSKonstantin Ananyev		struct {
125aa97dd1cSKonstantin Ananyev			uint32_t nb_elem;  /* number of objects per drb. */
126aa97dd1cSKonstantin Ananyev			uint32_t nb_max;   /* number of drbs per stream. */
127aa97dd1cSKonstantin Ananyev			struct rte_ring *r;
128aa97dd1cSKonstantin Ananyev		} drb;
129aa97dd1cSKonstantin Ananyev		struct rte_ring *q;  /* (re)tx queue */
130aa97dd1cSKonstantin Ananyev		struct tle_event *ev;
131aa97dd1cSKonstantin Ananyev		struct tle_stream_cb cb;
132aa97dd1cSKonstantin Ananyev		struct tle_dest dst;
133aa97dd1cSKonstantin Ananyev	} tx __rte_cache_aligned;
134aa97dd1cSKonstantin Ananyev
135aa97dd1cSKonstantin Ananyev} __rte_cache_aligned;
136aa97dd1cSKonstantin Ananyev
137aa97dd1cSKonstantin Ananyev#define TCP_STREAM(p)	\
138aa97dd1cSKonstantin Ananyev((struct tle_tcp_stream *)((uintptr_t)(p) - offsetof(struct tle_tcp_stream, s)))
139aa97dd1cSKonstantin Ananyev
140aa97dd1cSKonstantin Ananyev#define TCP_STREAM_TX_PENDING(s)	\
141aa97dd1cSKonstantin Ananyev	((s)->tx.drb.nb_max != rte_ring_count((s)->tx.drb.r))
142aa97dd1cSKonstantin Ananyev
143aa97dd1cSKonstantin Ananyev#define TCP_STREAM_TX_FINISHED(s)	\
144aa97dd1cSKonstantin Ananyev	((s)->tx.drb.nb_max == rte_ring_count((s)->tx.drb.r))
145aa97dd1cSKonstantin Ananyev
146aa97dd1cSKonstantin Ananyev#include "stream_table.h"
147aa97dd1cSKonstantin Ananyev
148aa97dd1cSKonstantin Ananyevstruct sdr {
149aa97dd1cSKonstantin Ananyev	rte_spinlock_t lock;
150aa97dd1cSKonstantin Ananyev	STAILQ_HEAD(, tle_stream) fe;
151aa97dd1cSKonstantin Ananyev	STAILQ_HEAD(, tle_stream) be;
152aa97dd1cSKonstantin Ananyev};
153aa97dd1cSKonstantin Ananyev
15447eb00f2SKonstantin Ananyev/* tempalte sizes/offsets/etc. for tcp stream */
15547eb00f2SKonstantin Ananyevstruct stream_szofs {
15647eb00f2SKonstantin Ananyev	uint32_t size;
15747eb00f2SKonstantin Ananyev	struct {
15847eb00f2SKonstantin Ananyev		uint32_t ofs;
15947eb00f2SKonstantin Ananyev		uint32_t nb_obj;
16047eb00f2SKonstantin Ananyev		uint32_t nb_max;
16147eb00f2SKonstantin Ananyev	} ofo;
16247eb00f2SKonstantin Ananyev	struct {
16347eb00f2SKonstantin Ananyev		uint32_t ofs;
16447eb00f2SKonstantin Ananyev		uint32_t nb_obj;
16547eb00f2SKonstantin Ananyev	} rxq, txq;
16647eb00f2SKonstantin Ananyev	struct {
16747eb00f2SKonstantin Ananyev		uint32_t ofs;
16847eb00f2SKonstantin Ananyev		uint32_t blk_sz;
16947eb00f2SKonstantin Ananyev		uint32_t rng_sz;
17047eb00f2SKonstantin Ananyev		uint32_t nb_rng;
17147eb00f2SKonstantin Ananyev		uint32_t nb_obj;
17247eb00f2SKonstantin Ananyev		uint32_t nb_max;
17347eb00f2SKonstantin Ananyev	} drb;
17447eb00f2SKonstantin Ananyev};
17547eb00f2SKonstantin Ananyev
176aa97dd1cSKonstantin Ananyevstruct tcp_streams {
177aa97dd1cSKonstantin Ananyev	struct stbl st;
178aa97dd1cSKonstantin Ananyev	struct tle_timer_wheel *tmr; /* timer wheel */
179aa97dd1cSKonstantin Ananyev	struct rte_ring *tsq;        /* to-send streams queue */
180b8f1ef2bSKonstantin Ananyev	struct tle_memtank *mts;     /* memtank to allocate streams from */
181aa97dd1cSKonstantin Ananyev	struct sdr dr;               /* death row for zombie streams */
18247eb00f2SKonstantin Ananyev	struct stream_szofs szofs;   /* size and offsets for stream data */
183aa97dd1cSKonstantin Ananyev};
184aa97dd1cSKonstantin Ananyev
185aa97dd1cSKonstantin Ananyev#define CTX_TCP_STREAMS(ctx)	((struct tcp_streams *)(ctx)->streams.buf)
186aa97dd1cSKonstantin Ananyev#define CTX_TCP_STLB(ctx)	(&CTX_TCP_STREAMS(ctx)->st)
187aa97dd1cSKonstantin Ananyev#define CTX_TCP_TMWHL(ctx)	(CTX_TCP_STREAMS(ctx)->tmr)
188aa97dd1cSKonstantin Ananyev#define CTX_TCP_TSQ(ctx)	(CTX_TCP_STREAMS(ctx)->tsq)
189aa97dd1cSKonstantin Ananyev#define CTX_TCP_SDR(ctx)	(&CTX_TCP_STREAMS(ctx)->dr)
190b8f1ef2bSKonstantin Ananyev#define CTX_TCP_MTS(ctx)	(CTX_TCP_STREAMS(ctx)->mts)
191aa97dd1cSKonstantin Ananyev
192aa97dd1cSKonstantin Ananyev#ifdef __cplusplus
193aa97dd1cSKonstantin Ananyev}
194aa97dd1cSKonstantin Ananyev#endif
195aa97dd1cSKonstantin Ananyev
196aa97dd1cSKonstantin Ananyev#endif /* _TCP_STREAM_H_ */