1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/* Copyright 2020 NXP */
3
4#ifndef __NET_TC_GATE_H
5#define __NET_TC_GATE_H
6
7#include <net/act_api.h>
8#include <linux/tc_act/tc_gate.h>
9
10struct action_gate_entry {
11	u8			gate_state;
12	u32			interval;
13	s32			ipv;
14	s32			maxoctets;
15};
16
17struct tcfg_gate_entry {
18	int			index;
19	u8			gate_state;
20	u32			interval;
21	s32			ipv;
22	s32			maxoctets;
23	struct list_head	list;
24};
25
26struct tcf_gate_params {
27	s32			tcfg_priority;
28	u64			tcfg_basetime;
29	u64			tcfg_cycletime;
30	u64			tcfg_cycletime_ext;
31	u32			tcfg_flags;
32	s32			tcfg_clockid;
33	size_t			num_entries;
34	struct list_head	entries;
35};
36
37#define GATE_ACT_GATE_OPEN	BIT(0)
38#define GATE_ACT_PENDING	BIT(1)
39
40struct tcf_gate {
41	struct tc_action	common;
42	struct tcf_gate_params	param;
43	u8			current_gate_status;
44	ktime_t			current_close_time;
45	u32			current_entry_octets;
46	s32			current_max_octets;
47	struct tcfg_gate_entry	*next_entry;
48	struct hrtimer		hitimer;
49	enum tk_offsets		tk_offset;
50};
51
52#define to_gate(a) ((struct tcf_gate *)a)
53
54static inline bool is_tcf_gate(const struct tc_action *a)
55{
56#ifdef CONFIG_NET_CLS_ACT
57	if (a->ops && a->ops->id == TCA_ID_GATE)
58		return true;
59#endif
60	return false;
61}
62
63static inline u32 tcf_gate_index(const struct tc_action *a)
64{
65	return a->tcfa_index;
66}
67
68static inline s32 tcf_gate_prio(const struct tc_action *a)
69{
70	s32 tcfg_prio;
71
72	tcfg_prio = to_gate(a)->param.tcfg_priority;
73
74	return tcfg_prio;
75}
76
77static inline u64 tcf_gate_basetime(const struct tc_action *a)
78{
79	u64 tcfg_basetime;
80
81	tcfg_basetime = to_gate(a)->param.tcfg_basetime;
82
83	return tcfg_basetime;
84}
85
86static inline u64 tcf_gate_cycletime(const struct tc_action *a)
87{
88	u64 tcfg_cycletime;
89
90	tcfg_cycletime = to_gate(a)->param.tcfg_cycletime;
91
92	return tcfg_cycletime;
93}
94
95static inline u64 tcf_gate_cycletimeext(const struct tc_action *a)
96{
97	u64 tcfg_cycletimeext;
98
99	tcfg_cycletimeext = to_gate(a)->param.tcfg_cycletime_ext;
100
101	return tcfg_cycletimeext;
102}
103
104static inline u32 tcf_gate_num_entries(const struct tc_action *a)
105{
106	u32 num_entries;
107
108	num_entries = to_gate(a)->param.num_entries;
109
110	return num_entries;
111}
112
113static inline struct action_gate_entry
114			*tcf_gate_get_list(const struct tc_action *a)
115{
116	struct action_gate_entry *oe;
117	struct tcf_gate_params *p;
118	struct tcfg_gate_entry *entry;
119	u32 num_entries;
120	int i = 0;
121
122	p = &to_gate(a)->param;
123	num_entries = p->num_entries;
124
125	list_for_each_entry(entry, &p->entries, list)
126		i++;
127
128	if (i != num_entries)
129		return NULL;
130
131	oe = kcalloc(num_entries, sizeof(*oe), GFP_ATOMIC);
132	if (!oe)
133		return NULL;
134
135	i = 0;
136	list_for_each_entry(entry, &p->entries, list) {
137		oe[i].gate_state = entry->gate_state;
138		oe[i].interval = entry->interval;
139		oe[i].ipv = entry->ipv;
140		oe[i].maxoctets = entry->maxoctets;
141		i++;
142	}
143
144	return oe;
145}
146#endif
147