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#ifndef _TCP_TXQ_H_
17#define _TCP_TXQ_H_
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23static inline struct rte_mbuf **
24tcp_txq_get_nxt_objs(const struct tle_tcp_stream *s, uint32_t *num)
25{
26	uint32_t cnt, head, mask, sz, tail;
27	struct rte_ring *r;
28
29	r = s->tx.q;
30	sz = _rte_ring_get_size(r);
31	mask = _rte_ring_get_mask(r);
32	head = r->cons.head & mask;
33	tail = r->prod.tail & mask;
34
35	cnt = (tail >= head) ? tail - head : sz - head;
36
37	*num = cnt;
38	return (struct rte_mbuf **)(_rte_ring_get_data(r) + head);
39}
40
41static inline struct rte_mbuf **
42tcp_txq_get_una_objs(const struct tle_tcp_stream *s, uint32_t *num)
43{
44	uint32_t cnt, head, mask, sz, tail;
45	struct rte_ring *r;
46
47	r = s->tx.q;
48	sz = _rte_ring_get_size(r);
49	mask = _rte_ring_get_mask(r);
50	head = r->prod.tail & mask;
51	tail = r->cons.tail & mask;
52
53	cnt = (head >= tail) ? head - tail : sz - tail;
54
55	*num = cnt;
56	return (struct rte_mbuf **)(_rte_ring_get_data(r) + tail);
57}
58
59static inline void
60tcp_txq_set_nxt_head(struct tle_tcp_stream *s, uint32_t num)
61{
62	struct rte_ring *r;
63
64	r = s->tx.q;
65	r->cons.head += num;
66}
67
68static inline void
69tcp_txq_rst_nxt_head(struct tle_tcp_stream *s)
70{
71	struct rte_ring *r;
72
73	r = s->tx.q;
74	r->cons.head = r->cons.tail;
75}
76
77static inline void
78tcp_txq_set_una_tail(struct tle_tcp_stream *s, uint32_t num)
79{
80	struct rte_ring *r;
81
82	r = s->tx.q;
83	rte_smp_rmb();
84	r->cons.tail += num;
85}
86
87static inline uint32_t
88tcp_txq_nxt_cnt(struct tle_tcp_stream *s)
89{
90	struct rte_ring *r;
91
92	r = s->tx.q;
93	return (r->prod.tail - r->cons.head) & _rte_ring_get_mask(r);
94}
95
96static inline void
97txs_enqueue(struct tle_ctx *ctx, struct tle_tcp_stream *s)
98{
99	struct rte_ring *r;
100	uint32_t n;
101
102	if (rte_atomic32_add_return(&s->tx.arm, 1) == 1) {
103		r = CTX_TCP_TSQ(ctx);
104		n = _rte_ring_enqueue_burst(r, (void * const *)&s, 1);
105		RTE_VERIFY(n == 1);
106	}
107}
108
109static inline uint32_t
110txs_dequeue_bulk(struct tle_ctx *ctx, struct tle_tcp_stream *s[], uint32_t num)
111{
112	struct rte_ring *r;
113
114	r = CTX_TCP_TSQ(ctx);
115	return _rte_ring_dequeue_burst(r, (void **)s, num);
116}
117
118#ifdef __cplusplus
119}
120#endif
121
122#endif /* _TCP_TXQ_H_ */
123