tcp_ctl.h revision 2c33ba7b
1/*
2 * Copyright (c) 2016  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	rwl_down(&s->rx.use);
34	rwl_down(&s->tx.use);
35}
36
37static inline void
38tcp_stream_up(struct tle_tcp_stream *s)
39{
40	rwl_up(&s->rx.use);
41	rwl_up(&s->tx.use);
42}
43
44/* calculate RCV.WND value based on size of stream receive buffer */
45static inline uint32_t
46calc_rx_wnd(const struct tle_tcp_stream *s, uint32_t scale)
47{
48	uint32_t wnd;
49
50	/* peer doesn't support WSCALE option, wnd size is limited to 64K */
51	if (scale == TCP_WSCALE_NONE) {
52		wnd = _rte_ring_get_mask(s->rx.q) << TCP_WSCALE_DEFAULT;
53		return RTE_MIN(wnd, (uint32_t)UINT16_MAX);
54	} else
55		return  _rte_ring_get_mask(s->rx.q) << scale;
56}
57
58/* empty stream's send queue */
59static inline void
60empty_tq(struct tle_tcp_stream *s)
61{
62	s->tx.q->cons.head = s->tx.q->cons.tail;
63	empty_mbuf_ring(s->tx.q);
64}
65
66/* empty stream's receive queue */
67static inline void
68empty_rq(struct tle_tcp_stream *s)
69{
70	empty_mbuf_ring(s->rx.q);
71	tcp_ofo_reset(s->rx.ofo);
72}
73
74/* empty stream's listen queue */
75static inline void
76empty_lq(struct tle_tcp_stream *s, struct stbl *st)
77{
78	uint32_t i, n;
79	struct rte_mbuf *mb;
80	union pkt_info pi;
81	union seg_info si;
82	struct stbl_entry *se[MAX_PKT_BURST];
83
84	do {
85		n = _rte_ring_dequeue_burst(s->rx.q, (void **)se, RTE_DIM(se));
86		for (i = 0; i != n; i++) {
87			mb = stbl_get_pkt(se[i]);
88			get_pkt_info(mb, &pi, &si);
89			stbl_del_pkt_lock(st, se[i], &pi);
90			rte_pktmbuf_free(mb);
91		}
92	} while (n != 0);
93}
94
95static inline void
96tcp_stream_reset(struct tle_ctx *ctx, struct tle_tcp_stream *s)
97{
98	struct stbl *st;
99	uint16_t uop;
100
101	st = CTX_TCP_STLB(ctx);
102
103	/* reset TX armed */
104	rte_atomic32_set(&s->tx.arm, 0);
105
106	/* reset TCB */
107	uop = s->tcb.uop & ~TCP_OP_CLOSE;
108	memset(&s->tcb, 0, sizeof(s->tcb));
109
110	/* reset cached destination */
111	memset(&s->tx.dst, 0, sizeof(s->tx.dst));
112
113	if (uop != TCP_OP_ACCEPT) {
114		/* free stream's destination port */
115		stream_clear_ctx(ctx, &s->s);
116		if (uop == TCP_OP_LISTEN)
117			empty_lq(s, st);
118	}
119
120	if (s->ste != NULL) {
121		/* remove entry from RX streams table */
122		stbl_del_stream_lock(st, s->ste, s);
123		s->ste = NULL;
124		empty_rq(s);
125	}
126
127	/* empty TX queue */
128	empty_tq(s);
129
130	/*
131	 * mark the stream as free again.
132	 * if there still are pkts queued for TX,
133	 * then put this stream to the tail of free list.
134	 */
135	put_stream(ctx, &s->s, TCP_STREAM_TX_FINISHED(s));
136}
137
138#ifdef __cplusplus
139}
140#endif
141
142#endif /* _TCP_CTL_H_ */
143