tcp_ctl.h revision 7e18fa1b
1/*
2 * Copyright (c) 2016-2017  Intel Corporation.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16/*
17 * Some helper stream control functions definitions.
18 */
19
20#ifndef _TCP_CTL_H_
21#define _TCP_CTL_H_
22
23#include "tcp_stream.h"
24#include "tcp_ofo.h"
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30static inline void
31tcp_stream_down(struct tle_tcp_stream *s)
32{
33	if ((s->flags & TLE_CTX_FLAG_ST) == 0)
34		rwl_down(&s->use);
35	else
36		rte_atomic32_set(&s->use, INT32_MIN);
37}
38
39static inline void
40tcp_stream_up(struct tle_tcp_stream *s)
41{
42	int32_t v;
43
44	if ((s->flags & TLE_CTX_FLAG_ST) == 0)
45		rwl_up(&s->use);
46	else {
47		v = rte_atomic32_read(&s->use) - INT32_MIN;
48		rte_atomic32_set(&s->use, v);
49	}
50}
51
52static inline int
53tcp_stream_try_acquire(struct tle_tcp_stream *s)
54{
55	int32_t v;
56
57	if ((s->flags & TLE_CTX_FLAG_ST) == 0)
58		return rwl_try_acquire(&s->use);
59
60	v = rte_atomic32_read(&s->use) + 1;
61	rte_atomic32_set(&s->use, v);
62	return v;
63}
64
65static inline void
66tcp_stream_release(struct tle_tcp_stream *s)
67{
68	int32_t v;
69
70	if ((s->flags & TLE_CTX_FLAG_ST) == 0)
71		rwl_release(&s->use);
72	else {
73		v = rte_atomic32_read(&s->use) - 1;
74		rte_atomic32_set(&s->use, v);
75	}
76}
77
78static inline int
79tcp_stream_acquire(struct tle_tcp_stream *s)
80{
81	int32_t v;
82
83	if ((s->flags & TLE_CTX_FLAG_ST) == 0)
84		return rwl_acquire(&s->use);
85
86	v = rte_atomic32_read(&s->use) + 1;
87	if (v > 0)
88		rte_atomic32_set(&s->use, v);
89	return v;
90}
91
92/* calculate RCV.WND value based on size of stream receive buffer */
93static inline uint32_t
94calc_rx_wnd(const struct tle_tcp_stream *s, uint32_t scale)
95{
96	uint32_t wnd;
97
98	/* peer doesn't support WSCALE option, wnd size is limited to 64K */
99	if (scale == TCP_WSCALE_NONE) {
100		wnd = _rte_ring_get_mask(s->rx.q) << TCP_WSCALE_DEFAULT;
101		return RTE_MIN(wnd, (uint32_t)UINT16_MAX);
102	} else
103		return  _rte_ring_get_mask(s->rx.q) << scale;
104}
105
106/* empty stream's send queue */
107static inline void
108empty_tq(struct tle_tcp_stream *s)
109{
110	s->tx.q->cons.head = s->tx.q->cons.tail;
111	empty_mbuf_ring(s->tx.q);
112}
113
114/* empty stream's receive queue */
115static inline void
116empty_rq(struct tle_tcp_stream *s)
117{
118	uint32_t n;
119	struct rte_mbuf *mb[MAX_PKT_BURST];
120
121	do {
122		n = _rte_ring_mcs_dequeue_burst(s->rx.q, (void **)mb,
123			RTE_DIM(mb));
124		free_mbufs(mb, n);
125	} while (n != 0);
126
127	tcp_ofo_reset(s->rx.ofo);
128}
129
130/* empty stream's listen queue */
131static inline void
132empty_lq(struct tle_tcp_stream *s)
133{
134	uint32_t n;
135	struct tle_stream *ts[MAX_PKT_BURST];
136
137	do {
138		n = _rte_ring_dequeue_burst(s->rx.q, (void **)ts, RTE_DIM(ts));
139		tle_tcp_stream_close_bulk(ts, n);
140	} while (n != 0);
141}
142
143static inline void
144tcp_stream_reset(struct tle_ctx *ctx, struct tle_tcp_stream *s)
145{
146	struct stbl *st;
147	uint16_t uop;
148
149	st = CTX_TCP_STLB(ctx);
150
151	/* reset TX armed */
152	rte_atomic32_set(&s->tx.arm, 0);
153
154	/* reset TCB */
155	uop = s->tcb.uop & ~TCP_OP_CLOSE;
156	memset(&s->tcb, 0, sizeof(s->tcb));
157
158	/* reset cached destination */
159	memset(&s->tx.dst, 0, sizeof(s->tx.dst));
160
161	if (uop != TCP_OP_ACCEPT) {
162		/* free stream's destination port */
163		stream_clear_ctx(ctx, &s->s);
164		if (uop == TCP_OP_LISTEN)
165			empty_lq(s);
166	}
167
168	if (s->ste != NULL) {
169		/* remove entry from RX streams table */
170		stbl_del_stream(st, s->ste, s,
171			(s->flags & TLE_CTX_FLAG_ST) == 0);
172		s->ste = NULL;
173		empty_rq(s);
174	}
175
176	/* empty TX queue */
177	empty_tq(s);
178
179	/*
180	 * mark the stream as free again.
181	 * if there still are pkts queued for TX,
182	 * then put this stream to the tail of free list.
183	 */
184	put_stream(ctx, &s->s, TCP_STREAM_TX_FINISHED(s));
185}
186
187#ifdef __cplusplus
188}
189#endif
190
191#endif /* _TCP_CTL_H_ */
192