Revert "l4p/tcp: introduce tle_tcp_stream_establish() API"
[tldk.git] / lib / libtle_l4p / tcp_ctl.h
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
27 extern "C" {
28 #endif
29
30 static inline void
31 tcp_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
39 static inline void
40 tcp_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
52 static inline int
53 tcp_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
65 static inline void
66 tcp_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
78 static inline int
79 tcp_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 */
93 static inline uint32_t
94 calc_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 */
107 static inline void
108 empty_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 */
115 static inline void
116 empty_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 */
131 static inline void
132 empty_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
143 static inline void
144 tcp_stream_reset(struct tle_ctx *ctx, struct tle_tcp_stream *s)
145 {
146         uint16_t uop;
147         struct tcp_streams *ts;
148
149         ts = CTX_TCP_STREAMS(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(&ts->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         if (TCP_STREAM_TX_PENDING(s)) 
185                 put_stream(ctx, &s->s, 0);
186         else {
187                 s->s.type = TLE_VNUM;
188                 tle_memtank_free(ts->mts, (void **)&s, 1, 0);
189         }
190 }
191
192 static inline struct tle_tcp_stream *
193 tcp_stream_get(struct tle_ctx *ctx, uint32_t flag)
194 {
195         struct tle_stream *s;
196         struct tle_tcp_stream *cs;
197         struct tcp_streams *ts;
198
199         ts = CTX_TCP_STREAMS(ctx);
200         
201         /* check TX pending list */
202         s = get_stream(ctx);
203         cs = TCP_STREAM(s);
204         if (s != NULL) {
205                 if (TCP_STREAM_TX_FINISHED(cs))
206                         return cs;
207                 put_stream(ctx, &cs->s, 0);
208         }
209
210         if (tle_memtank_alloc(ts->mts, (void **)&cs, 1, flag) != 1)
211                 return NULL;
212
213         return cs;
214 }
215
216 #ifdef __cplusplus
217 }
218 #endif
219
220 #endif /* _TCP_CTL_H_ */