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 
10 struct action_gate_entry {
11 	u8			gate_state;
12 	u32			interval;
13 	s32			ipv;
14 	s32			maxoctets;
15 };
16 
17 struct 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 
26 struct 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 
40 struct 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 
is_tcf_gate(const struct tc_action * a)54 static 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 
tcf_gate_prio(const struct tc_action * a)63 static inline s32 tcf_gate_prio(const struct tc_action *a)
64 {
65 	s32 tcfg_prio;
66 
67 	tcfg_prio = to_gate(a)->param.tcfg_priority;
68 
69 	return tcfg_prio;
70 }
71 
tcf_gate_basetime(const struct tc_action * a)72 static inline u64 tcf_gate_basetime(const struct tc_action *a)
73 {
74 	u64 tcfg_basetime;
75 
76 	tcfg_basetime = to_gate(a)->param.tcfg_basetime;
77 
78 	return tcfg_basetime;
79 }
80 
tcf_gate_cycletime(const struct tc_action * a)81 static inline u64 tcf_gate_cycletime(const struct tc_action *a)
82 {
83 	u64 tcfg_cycletime;
84 
85 	tcfg_cycletime = to_gate(a)->param.tcfg_cycletime;
86 
87 	return tcfg_cycletime;
88 }
89 
tcf_gate_cycletimeext(const struct tc_action * a)90 static inline u64 tcf_gate_cycletimeext(const struct tc_action *a)
91 {
92 	u64 tcfg_cycletimeext;
93 
94 	tcfg_cycletimeext = to_gate(a)->param.tcfg_cycletime_ext;
95 
96 	return tcfg_cycletimeext;
97 }
98 
tcf_gate_num_entries(const struct tc_action * a)99 static inline u32 tcf_gate_num_entries(const struct tc_action *a)
100 {
101 	u32 num_entries;
102 
103 	num_entries = to_gate(a)->param.num_entries;
104 
105 	return num_entries;
106 }
107 
108 static inline struct action_gate_entry
tcf_gate_get_list(const struct tc_action * a)109 			*tcf_gate_get_list(const struct tc_action *a)
110 {
111 	struct action_gate_entry *oe;
112 	struct tcf_gate_params *p;
113 	struct tcfg_gate_entry *entry;
114 	u32 num_entries;
115 	int i = 0;
116 
117 	p = &to_gate(a)->param;
118 	num_entries = p->num_entries;
119 
120 	list_for_each_entry(entry, &p->entries, list)
121 		i++;
122 
123 	if (i != num_entries)
124 		return NULL;
125 
126 	oe = kcalloc(num_entries, sizeof(*oe), GFP_ATOMIC);
127 	if (!oe)
128 		return NULL;
129 
130 	i = 0;
131 	list_for_each_entry(entry, &p->entries, list) {
132 		oe[i].gate_state = entry->gate_state;
133 		oe[i].interval = entry->interval;
134 		oe[i].ipv = entry->ipv;
135 		oe[i].maxoctets = entry->maxoctets;
136 		i++;
137 	}
138 
139 	return oe;
140 }
141 #endif
142