1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ |
2 | /* Copyright (C) 2018 Netronome Systems, Inc. */ |
3 | |
4 | #ifndef __NFP_ABM_H__ |
5 | #define __NFP_ABM_H__ 1 |
6 | |
7 | #include <linux/bits.h> |
8 | #include <linux/list.h> |
9 | #include <linux/radix-tree.h> |
10 | #include <net/devlink.h> |
11 | #include <net/pkt_cls.h> |
12 | #include <net/pkt_sched.h> |
13 | |
14 | /* Dump of 64 PRIOs and 256 REDs seems to take 850us on Xeon v4 @ 2.20GHz; |
15 | * 2.5ms / 400Hz seems more than sufficient for stats resolution. |
16 | */ |
17 | #define NFP_ABM_STATS_REFRESH_IVAL (2500 * 1000) /* ns */ |
18 | |
19 | #define NFP_ABM_LVL_INFINITY S32_MAX |
20 | |
21 | struct nfp_app; |
22 | struct nfp_net; |
23 | |
24 | #define NFP_ABM_PORTID_TYPE GENMASK(23, 16) |
25 | #define NFP_ABM_PORTID_ID GENMASK(7, 0) |
26 | |
27 | /* The possible actions if thresholds are exceeded */ |
28 | enum nfp_abm_q_action { |
29 | /* mark if ECN capable, otherwise drop */ |
30 | NFP_ABM_ACT_MARK_DROP = 0, |
31 | /* mark if ECN capable, otherwise goto QM */ |
32 | NFP_ABM_ACT_MARK_QUEUE = 1, |
33 | NFP_ABM_ACT_DROP = 2, |
34 | NFP_ABM_ACT_QUEUE = 3, |
35 | NFP_ABM_ACT_NOQUEUE = 4, |
36 | }; |
37 | |
38 | /** |
39 | * struct nfp_abm - ABM NIC app structure |
40 | * @app: back pointer to nfp_app |
41 | * @pf_id: ID of our PF link |
42 | * |
43 | * @red_support: is RED offload supported |
44 | * @num_prios: number of supported DSCP priorities |
45 | * @num_bands: number of supported DSCP priority bands |
46 | * @action_mask: bitmask of supported actions |
47 | * |
48 | * @thresholds: current threshold configuration |
49 | * @threshold_undef: bitmap of thresholds which have not been set |
50 | * @actions: current FW action configuration |
51 | * @num_thresholds: number of @thresholds and bits in @threshold_undef |
52 | * |
53 | * @prio_map_len: computed length of FW priority map (in bytes) |
54 | * @dscp_mask: mask FW will apply on DSCP field |
55 | * |
56 | * @eswitch_mode: devlink eswitch mode, advanced functions only visible |
57 | * in switchdev mode |
58 | * |
59 | * @q_lvls: queue level control area |
60 | * @qm_stats: queue statistics symbol |
61 | * @q_stats: basic queue statistics (only in per-band case) |
62 | */ |
63 | struct nfp_abm { |
64 | struct nfp_app *app; |
65 | unsigned int pf_id; |
66 | |
67 | unsigned int red_support; |
68 | unsigned int num_prios; |
69 | unsigned int num_bands; |
70 | unsigned int action_mask; |
71 | |
72 | u32 *thresholds; |
73 | unsigned long *threshold_undef; |
74 | u8 *actions; |
75 | size_t num_thresholds; |
76 | |
77 | unsigned int prio_map_len; |
78 | u8 dscp_mask; |
79 | |
80 | enum devlink_eswitch_mode eswitch_mode; |
81 | |
82 | const struct nfp_rtsym *q_lvls; |
83 | const struct nfp_rtsym *qm_stats; |
84 | const struct nfp_rtsym *q_stats; |
85 | }; |
86 | |
87 | /** |
88 | * struct nfp_alink_stats - ABM NIC statistics |
89 | * @tx_pkts: number of TXed packets |
90 | * @tx_bytes: number of TXed bytes |
91 | * @backlog_pkts: momentary backlog length (packets) |
92 | * @backlog_bytes: momentary backlog length (bytes) |
93 | * @overlimits: number of ECN marked TXed packets (accumulative) |
94 | * @drops: number of tail-dropped packets (accumulative) |
95 | */ |
96 | struct nfp_alink_stats { |
97 | u64 tx_pkts; |
98 | u64 tx_bytes; |
99 | u64 backlog_pkts; |
100 | u64 backlog_bytes; |
101 | u64 overlimits; |
102 | u64 drops; |
103 | }; |
104 | |
105 | /** |
106 | * struct nfp_alink_xstats - extended ABM NIC statistics |
107 | * @ecn_marked: number of ECN marked TXed packets |
108 | * @pdrop: number of hard drops due to queue limit |
109 | */ |
110 | struct nfp_alink_xstats { |
111 | u64 ecn_marked; |
112 | u64 pdrop; |
113 | }; |
114 | |
115 | enum nfp_qdisc_type { |
116 | NFP_QDISC_NONE = 0, |
117 | NFP_QDISC_MQ, |
118 | NFP_QDISC_RED, |
119 | NFP_QDISC_GRED, |
120 | }; |
121 | |
122 | #define NFP_QDISC_UNTRACKED ((struct nfp_qdisc *)1UL) |
123 | |
124 | /** |
125 | * struct nfp_qdisc - tracked TC Qdisc |
126 | * @netdev: netdev on which Qdisc was created |
127 | * @type: Qdisc type |
128 | * @handle: handle of this Qdisc |
129 | * @parent_handle: handle of the parent (unreliable if Qdisc was grafted) |
130 | * @use_cnt: number of attachment points in the hierarchy |
131 | * @num_children: current size of the @children array |
132 | * @children: pointers to children |
133 | * |
134 | * @params_ok: parameters of this Qdisc are OK for offload |
135 | * @offload_mark: offload refresh state - selected for offload |
136 | * @offloaded: Qdisc is currently offloaded to the HW |
137 | * |
138 | * @mq: MQ Qdisc specific parameters and state |
139 | * @mq.stats: current stats of the MQ Qdisc |
140 | * @mq.prev_stats: previously reported @mq.stats |
141 | * |
142 | * @red: RED Qdisc specific parameters and state |
143 | * @red.num_bands: Number of valid entries in the @red.band table |
144 | * @red.band: Per-band array of RED instances |
145 | * @red.band.ecn: ECN marking is enabled (rather than drop) |
146 | * @red.band.threshold: ECN marking threshold |
147 | * @red.band.stats: current stats of the RED Qdisc |
148 | * @red.band.prev_stats: previously reported @red.stats |
149 | * @red.band.xstats: extended stats for RED - current |
150 | * @red.band.prev_xstats: extended stats for RED - previously reported |
151 | */ |
152 | struct nfp_qdisc { |
153 | struct net_device *netdev; |
154 | enum nfp_qdisc_type type; |
155 | u32 handle; |
156 | u32 parent_handle; |
157 | unsigned int use_cnt; |
158 | unsigned int num_children; |
159 | struct nfp_qdisc **children; |
160 | |
161 | bool params_ok; |
162 | bool offload_mark; |
163 | bool offloaded; |
164 | |
165 | union { |
166 | /* NFP_QDISC_MQ */ |
167 | struct { |
168 | struct nfp_alink_stats stats; |
169 | struct nfp_alink_stats prev_stats; |
170 | } mq; |
171 | /* TC_SETUP_QDISC_RED, TC_SETUP_QDISC_GRED */ |
172 | struct { |
173 | unsigned int num_bands; |
174 | |
175 | struct { |
176 | bool ecn; |
177 | u32 threshold; |
178 | struct nfp_alink_stats stats; |
179 | struct nfp_alink_stats prev_stats; |
180 | struct nfp_alink_xstats xstats; |
181 | struct nfp_alink_xstats prev_xstats; |
182 | } band[MAX_DPs]; |
183 | } red; |
184 | }; |
185 | }; |
186 | |
187 | /** |
188 | * struct nfp_abm_link - port tuple of a ABM NIC |
189 | * @abm: back pointer to nfp_abm |
190 | * @vnic: data vNIC |
191 | * @id: id of the data vNIC |
192 | * @queue_base: id of base to host queue within PCIe (not QC idx) |
193 | * @total_queues: number of PF queues |
194 | * |
195 | * @last_stats_update: ktime of last stats update |
196 | * |
197 | * @prio_map: current map of priorities |
198 | * @has_prio: @prio_map is valid |
199 | * |
200 | * @def_band: default band to use |
201 | * @dscp_map: list of DSCP to band mappings |
202 | * |
203 | * @root_qdisc: pointer to the current root of the Qdisc hierarchy |
204 | * @qdiscs: all qdiscs recorded by major part of the handle |
205 | */ |
206 | struct nfp_abm_link { |
207 | struct nfp_abm *abm; |
208 | struct nfp_net *vnic; |
209 | unsigned int id; |
210 | unsigned int queue_base; |
211 | unsigned int total_queues; |
212 | |
213 | u64 last_stats_update; |
214 | |
215 | u32 *prio_map; |
216 | bool has_prio; |
217 | |
218 | u8 def_band; |
219 | struct list_head dscp_map; |
220 | |
221 | struct nfp_qdisc *root_qdisc; |
222 | struct radix_tree_root qdiscs; |
223 | }; |
224 | |
225 | static inline bool nfp_abm_has_prio(struct nfp_abm *abm) |
226 | { |
227 | return abm->num_bands > 1; |
228 | } |
229 | |
230 | static inline bool nfp_abm_has_drop(struct nfp_abm *abm) |
231 | { |
232 | return abm->action_mask & BIT(NFP_ABM_ACT_DROP); |
233 | } |
234 | |
235 | static inline bool nfp_abm_has_mark(struct nfp_abm *abm) |
236 | { |
237 | return abm->action_mask & BIT(NFP_ABM_ACT_MARK_DROP); |
238 | } |
239 | |
240 | void nfp_abm_qdisc_offload_update(struct nfp_abm_link *alink); |
241 | int nfp_abm_setup_root(struct net_device *netdev, struct nfp_abm_link *alink, |
242 | struct tc_root_qopt_offload *opt); |
243 | int nfp_abm_setup_tc_red(struct net_device *netdev, struct nfp_abm_link *alink, |
244 | struct tc_red_qopt_offload *opt); |
245 | int nfp_abm_setup_tc_mq(struct net_device *netdev, struct nfp_abm_link *alink, |
246 | struct tc_mq_qopt_offload *opt); |
247 | int nfp_abm_setup_tc_gred(struct net_device *netdev, struct nfp_abm_link *alink, |
248 | struct tc_gred_qopt_offload *opt); |
249 | int nfp_abm_setup_cls_block(struct net_device *netdev, struct nfp_repr *repr, |
250 | struct flow_block_offload *opt); |
251 | |
252 | int nfp_abm_ctrl_read_params(struct nfp_abm_link *alink); |
253 | int nfp_abm_ctrl_find_addrs(struct nfp_abm *abm); |
254 | int __nfp_abm_ctrl_set_q_lvl(struct nfp_abm *abm, unsigned int id, u32 val); |
255 | int nfp_abm_ctrl_set_q_lvl(struct nfp_abm_link *alink, unsigned int band, |
256 | unsigned int queue, u32 val); |
257 | int __nfp_abm_ctrl_set_q_act(struct nfp_abm *abm, unsigned int id, |
258 | enum nfp_abm_q_action act); |
259 | int nfp_abm_ctrl_set_q_act(struct nfp_abm_link *alink, unsigned int band, |
260 | unsigned int queue, enum nfp_abm_q_action act); |
261 | int nfp_abm_ctrl_read_q_stats(struct nfp_abm_link *alink, |
262 | unsigned int band, unsigned int queue, |
263 | struct nfp_alink_stats *stats); |
264 | int nfp_abm_ctrl_read_q_xstats(struct nfp_abm_link *alink, |
265 | unsigned int band, unsigned int queue, |
266 | struct nfp_alink_xstats *xstats); |
267 | u64 nfp_abm_ctrl_stat_non_sto(struct nfp_abm_link *alink, unsigned int i); |
268 | u64 nfp_abm_ctrl_stat_sto(struct nfp_abm_link *alink, unsigned int i); |
269 | int nfp_abm_ctrl_qm_enable(struct nfp_abm *abm); |
270 | int nfp_abm_ctrl_qm_disable(struct nfp_abm *abm); |
271 | void nfp_abm_prio_map_update(struct nfp_abm *abm); |
272 | int nfp_abm_ctrl_prio_map_update(struct nfp_abm_link *alink, u32 *packed); |
273 | #endif |
274 | |