]>
Commit | Line | Data |
---|---|---|
56ade8fe JP |
1 | /* |
2 | * drivers/net/ethernet/mellanox/mlxsw/spectrum.h | |
3 | * Copyright (c) 2015 Mellanox Technologies. All rights reserved. | |
4 | * Copyright (c) 2015 Jiri Pirko <jiri@mellanox.com> | |
5 | * Copyright (c) 2015 Ido Schimmel <idosch@mellanox.com> | |
6 | * Copyright (c) 2015 Elad Raz <eladr@mellanox.com> | |
7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions are met: | |
10 | * | |
11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | |
15 | * documentation and/or other materials provided with the distribution. | |
16 | * 3. Neither the names of the copyright holders nor the names of its | |
17 | * contributors may be used to endorse or promote products derived from | |
18 | * this software without specific prior written permission. | |
19 | * | |
20 | * Alternatively, this software may be distributed under the terms of the | |
21 | * GNU General Public License ("GPL") version 2 as published by the Free | |
22 | * Software Foundation. | |
23 | * | |
24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
28 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
29 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
30 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
31 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
32 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
33 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
34 | * POSSIBILITY OF SUCH DAMAGE. | |
35 | */ | |
36 | ||
37 | #ifndef _MLXSW_SPECTRUM_H | |
38 | #define _MLXSW_SPECTRUM_H | |
39 | ||
40 | #include <linux/types.h> | |
41 | #include <linux/netdevice.h> | |
6cf3c971 | 42 | #include <linux/rhashtable.h> |
56ade8fe JP |
43 | #include <linux/bitops.h> |
44 | #include <linux/if_vlan.h> | |
7f71eb46 | 45 | #include <linux/list.h> |
8e8dfe9f | 46 | #include <linux/dcbnl.h> |
5e9c16cc | 47 | #include <linux/in6.h> |
56ade8fe JP |
48 | #include <net/switchdev.h> |
49 | ||
3a49b4fd | 50 | #include "port.h" |
56ade8fe JP |
51 | #include "core.h" |
52 | ||
53 | #define MLXSW_SP_VFID_BASE VLAN_N_VID | |
99724c18 IS |
54 | #define MLXSW_SP_VFID_MAX 6656 /* Bridged VLAN interfaces */ |
55 | ||
56 | #define MLXSW_SP_RFID_BASE 15360 | |
57 | #define MLXSW_SP_RIF_MAX 800 | |
7f71eb46 | 58 | |
0d65fc13 JP |
59 | #define MLXSW_SP_LAG_MAX 64 |
60 | #define MLXSW_SP_PORT_PER_LAG_MAX 16 | |
56ade8fe | 61 | |
53ae6283 ER |
62 | #define MLXSW_SP_MID_MAX 7000 |
63 | ||
18f1e70c IS |
64 | #define MLXSW_SP_PORTS_PER_CLUSTER_MAX 4 |
65 | ||
53342023 JP |
66 | #define MLXSW_SP_LPM_TREE_MIN 2 /* trees 0 and 1 are reserved */ |
67 | #define MLXSW_SP_LPM_TREE_MAX 22 | |
68 | #define MLXSW_SP_LPM_TREE_COUNT (MLXSW_SP_LPM_TREE_MAX - MLXSW_SP_LPM_TREE_MIN) | |
69 | ||
6b75c480 JP |
70 | #define MLXSW_SP_VIRTUAL_ROUTER_MAX 256 |
71 | ||
18f1e70c IS |
72 | #define MLXSW_SP_PORT_BASE_SPEED 25000 /* Mb/s */ |
73 | ||
1a198449 IS |
74 | #define MLXSW_SP_BYTES_PER_CELL 96 |
75 | ||
76 | #define MLXSW_SP_BYTES_TO_CELLS(b) DIV_ROUND_UP(b, MLXSW_SP_BYTES_PER_CELL) | |
0f433fa0 | 77 | #define MLXSW_SP_CELLS_TO_BYTES(c) (c * MLXSW_SP_BYTES_PER_CELL) |
1a198449 | 78 | |
c6022427 JP |
79 | #define MLXSW_SP_KVD_LINEAR_SIZE 65536 /* entries */ |
80 | #define MLXSW_SP_KVD_HASH_SINGLE_SIZE 163840 /* entries */ | |
81 | #define MLXSW_SP_KVD_HASH_DOUBLE_SIZE 32768 /* entries */ | |
82 | ||
9f7ec052 IS |
83 | /* Maximum delay buffer needed in case of PAUSE frames, in cells. |
84 | * Assumes 100m cable and maximum MTU. | |
85 | */ | |
86 | #define MLXSW_SP_PAUSE_DELAY 612 | |
87 | ||
d81a6bdb IS |
88 | #define MLXSW_SP_CELL_FACTOR 2 /* 2 * cell_size / (IPG + cell_size + 1) */ |
89 | ||
90 | static inline u16 mlxsw_sp_pfc_delay_get(int mtu, u16 delay) | |
91 | { | |
92 | delay = MLXSW_SP_BYTES_TO_CELLS(DIV_ROUND_UP(delay, BITS_PER_BYTE)); | |
93 | return MLXSW_SP_CELL_FACTOR * delay + MLXSW_SP_BYTES_TO_CELLS(mtu); | |
94 | } | |
95 | ||
56ade8fe JP |
96 | struct mlxsw_sp_port; |
97 | ||
0d65fc13 JP |
98 | struct mlxsw_sp_upper { |
99 | struct net_device *dev; | |
100 | unsigned int ref_count; | |
101 | }; | |
102 | ||
d0ec875a | 103 | struct mlxsw_sp_fid { |
1c800759 | 104 | void (*leave)(struct mlxsw_sp_port *mlxsw_sp_vport); |
7f71eb46 | 105 | struct list_head list; |
d0ec875a IS |
106 | unsigned int ref_count; |
107 | struct net_device *dev; | |
99724c18 | 108 | struct mlxsw_sp_rif *r; |
d0ec875a | 109 | u16 fid; |
7f71eb46 IS |
110 | }; |
111 | ||
fa3054f5 IS |
112 | struct mlxsw_sp_rif { |
113 | struct net_device *dev; | |
99724c18 | 114 | unsigned int ref_count; |
6e095fd4 IS |
115 | struct mlxsw_sp_fid *f; |
116 | unsigned char addr[ETH_ALEN]; | |
117 | int mtu; | |
fa3054f5 IS |
118 | u16 rif; |
119 | }; | |
120 | ||
3a49b4fd ER |
121 | struct mlxsw_sp_mid { |
122 | struct list_head list; | |
123 | unsigned char addr[ETH_ALEN]; | |
124 | u16 vid; | |
125 | u16 mid; | |
126 | unsigned int ref_count; | |
127 | }; | |
128 | ||
7f71eb46 IS |
129 | static inline u16 mlxsw_sp_vfid_to_fid(u16 vfid) |
130 | { | |
131 | return MLXSW_SP_VFID_BASE + vfid; | |
132 | } | |
133 | ||
aac78a44 IS |
134 | static inline u16 mlxsw_sp_fid_to_vfid(u16 fid) |
135 | { | |
136 | return fid - MLXSW_SP_VFID_BASE; | |
137 | } | |
138 | ||
139 | static inline bool mlxsw_sp_fid_is_vfid(u16 fid) | |
140 | { | |
99724c18 IS |
141 | return fid >= MLXSW_SP_VFID_BASE && fid < MLXSW_SP_RFID_BASE; |
142 | } | |
143 | ||
144 | static inline bool mlxsw_sp_fid_is_rfid(u16 fid) | |
145 | { | |
146 | return fid >= MLXSW_SP_RFID_BASE; | |
147 | } | |
148 | ||
149 | static inline u16 mlxsw_sp_rif_sp_to_fid(u16 rif) | |
150 | { | |
151 | return MLXSW_SP_RFID_BASE + rif; | |
aac78a44 IS |
152 | } |
153 | ||
078f9c71 JP |
154 | struct mlxsw_sp_sb_pr { |
155 | enum mlxsw_reg_sbpr_mode mode; | |
156 | u32 size; | |
157 | }; | |
158 | ||
2d0ed39f JP |
159 | struct mlxsw_cp_sb_occ { |
160 | u32 cur; | |
161 | u32 max; | |
162 | }; | |
163 | ||
078f9c71 JP |
164 | struct mlxsw_sp_sb_cm { |
165 | u32 min_buff; | |
166 | u32 max_buff; | |
167 | u8 pool; | |
2d0ed39f | 168 | struct mlxsw_cp_sb_occ occ; |
078f9c71 JP |
169 | }; |
170 | ||
171 | struct mlxsw_sp_sb_pm { | |
172 | u32 min_buff; | |
173 | u32 max_buff; | |
2d0ed39f | 174 | struct mlxsw_cp_sb_occ occ; |
078f9c71 JP |
175 | }; |
176 | ||
177 | #define MLXSW_SP_SB_POOL_COUNT 4 | |
178 | #define MLXSW_SP_SB_TC_COUNT 8 | |
179 | ||
180 | struct mlxsw_sp_sb { | |
181 | struct mlxsw_sp_sb_pr prs[2][MLXSW_SP_SB_POOL_COUNT]; | |
182 | struct { | |
183 | struct mlxsw_sp_sb_cm cms[2][MLXSW_SP_SB_TC_COUNT]; | |
184 | struct mlxsw_sp_sb_pm pms[2][MLXSW_SP_SB_POOL_COUNT]; | |
185 | } ports[MLXSW_PORT_MAX_PORTS]; | |
186 | }; | |
187 | ||
5e9c16cc JP |
188 | #define MLXSW_SP_PREFIX_COUNT (sizeof(struct in6_addr) * BITS_PER_BYTE) |
189 | ||
190 | struct mlxsw_sp_prefix_usage { | |
191 | DECLARE_BITMAP(b, MLXSW_SP_PREFIX_COUNT); | |
192 | }; | |
193 | ||
53342023 JP |
194 | enum mlxsw_sp_l3proto { |
195 | MLXSW_SP_L3_PROTO_IPV4, | |
196 | MLXSW_SP_L3_PROTO_IPV6, | |
197 | }; | |
198 | ||
199 | struct mlxsw_sp_lpm_tree { | |
200 | u8 id; /* tree ID */ | |
201 | unsigned int ref_count; | |
202 | enum mlxsw_sp_l3proto proto; | |
203 | struct mlxsw_sp_prefix_usage prefix_usage; | |
204 | }; | |
205 | ||
6b75c480 JP |
206 | struct mlxsw_sp_fib; |
207 | ||
208 | struct mlxsw_sp_vr { | |
209 | u16 id; /* virtual router ID */ | |
210 | bool used; | |
211 | enum mlxsw_sp_l3proto proto; | |
212 | u32 tb_id; /* kernel fib table id */ | |
213 | struct mlxsw_sp_lpm_tree *lpm_tree; | |
214 | struct mlxsw_sp_fib *fib; | |
215 | }; | |
216 | ||
763b4b70 YG |
217 | enum mlxsw_sp_span_type { |
218 | MLXSW_SP_SPAN_EGRESS, | |
219 | MLXSW_SP_SPAN_INGRESS | |
220 | }; | |
221 | ||
222 | struct mlxsw_sp_span_inspected_port { | |
223 | struct list_head list; | |
224 | enum mlxsw_sp_span_type type; | |
225 | u8 local_port; | |
226 | }; | |
227 | ||
228 | struct mlxsw_sp_span_entry { | |
229 | u8 local_port; | |
230 | bool used; | |
231 | struct list_head bound_ports_list; | |
232 | int ref_count; | |
233 | int id; | |
234 | }; | |
235 | ||
236 | enum mlxsw_sp_port_mall_action_type { | |
237 | MLXSW_SP_PORT_MALL_MIRROR, | |
238 | }; | |
239 | ||
240 | struct mlxsw_sp_port_mall_mirror_tc_entry { | |
241 | u8 to_local_port; | |
242 | bool ingress; | |
243 | }; | |
244 | ||
245 | struct mlxsw_sp_port_mall_tc_entry { | |
246 | struct list_head list; | |
247 | unsigned long cookie; | |
248 | enum mlxsw_sp_port_mall_action_type type; | |
249 | union { | |
250 | struct mlxsw_sp_port_mall_mirror_tc_entry mirror; | |
251 | }; | |
252 | }; | |
253 | ||
53342023 JP |
254 | struct mlxsw_sp_router { |
255 | struct mlxsw_sp_lpm_tree lpm_trees[MLXSW_SP_LPM_TREE_COUNT]; | |
6b75c480 | 256 | struct mlxsw_sp_vr vrs[MLXSW_SP_VIRTUAL_ROUTER_MAX]; |
6cf3c971 | 257 | struct rhashtable neigh_ht; |
c723c735 YG |
258 | struct { |
259 | struct delayed_work dw; | |
260 | unsigned long interval; /* ms */ | |
261 | } neighs_update; | |
0b2361d9 YG |
262 | struct delayed_work nexthop_probe_dw; |
263 | #define MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL 5000 /* ms */ | |
a7ff87ac | 264 | struct list_head nexthop_group_list; |
b2157149 | 265 | struct list_head nexthop_neighs_list; |
53342023 JP |
266 | }; |
267 | ||
56ade8fe | 268 | struct mlxsw_sp { |
7f71eb46 IS |
269 | struct { |
270 | struct list_head list; | |
99724c18 | 271 | DECLARE_BITMAP(mapped, MLXSW_SP_VFID_MAX); |
3ba2ebf4 | 272 | } vfids; |
3a49b4fd ER |
273 | struct { |
274 | struct list_head list; | |
d8651fd8 | 275 | DECLARE_BITMAP(mapped, MLXSW_SP_MID_MAX); |
3a49b4fd | 276 | } br_mids; |
14d39461 | 277 | struct list_head fids; /* VLAN-aware bridge FIDs */ |
fa3054f5 | 278 | struct mlxsw_sp_rif *rifs[MLXSW_SP_RIF_MAX]; |
56ade8fe JP |
279 | struct mlxsw_sp_port **ports; |
280 | struct mlxsw_core *core; | |
281 | const struct mlxsw_bus_info *bus_info; | |
282 | unsigned char base_mac[ETH_ALEN]; | |
283 | struct { | |
284 | struct delayed_work dw; | |
285 | #define MLXSW_SP_DEFAULT_LEARNING_INTERVAL 100 | |
286 | unsigned int interval; /* ms */ | |
287 | } fdb_notify; | |
869f63a4 IS |
288 | #define MLXSW_SP_MIN_AGEING_TIME 10 |
289 | #define MLXSW_SP_MAX_AGEING_TIME 1000000 | |
56ade8fe JP |
290 | #define MLXSW_SP_DEFAULT_AGEING_TIME 300 |
291 | u32 ageing_time; | |
0d65fc13 JP |
292 | struct mlxsw_sp_upper master_bridge; |
293 | struct mlxsw_sp_upper lags[MLXSW_SP_LAG_MAX]; | |
558c2d5e | 294 | u8 port_to_module[MLXSW_PORT_MAX_PORTS]; |
078f9c71 | 295 | struct mlxsw_sp_sb sb; |
53342023 | 296 | struct mlxsw_sp_router router; |
b090ef06 JP |
297 | struct { |
298 | DECLARE_BITMAP(usage, MLXSW_SP_KVD_LINEAR_SIZE); | |
299 | } kvdl; | |
763b4b70 YG |
300 | |
301 | struct { | |
302 | struct mlxsw_sp_span_entry *entries; | |
303 | int entries_count; | |
304 | } span; | |
56ade8fe JP |
305 | }; |
306 | ||
0d65fc13 JP |
307 | static inline struct mlxsw_sp_upper * |
308 | mlxsw_sp_lag_get(struct mlxsw_sp *mlxsw_sp, u16 lag_id) | |
309 | { | |
310 | return &mlxsw_sp->lags[lag_id]; | |
311 | } | |
312 | ||
56ade8fe JP |
313 | struct mlxsw_sp_port_pcpu_stats { |
314 | u64 rx_packets; | |
315 | u64 rx_bytes; | |
316 | u64 tx_packets; | |
317 | u64 tx_bytes; | |
318 | struct u64_stats_sync syncp; | |
319 | u32 tx_dropped; | |
320 | }; | |
321 | ||
322 | struct mlxsw_sp_port { | |
932762b6 | 323 | struct mlxsw_core_port core_port; /* must be first */ |
56ade8fe JP |
324 | struct net_device *dev; |
325 | struct mlxsw_sp_port_pcpu_stats __percpu *pcpu_stats; | |
326 | struct mlxsw_sp *mlxsw_sp; | |
327 | u8 local_port; | |
328 | u8 stp_state; | |
0d9b970c JP |
329 | u8 learning:1, |
330 | learning_sync:1, | |
0293038e | 331 | uc_flood:1, |
0d65fc13 | 332 | bridged:1, |
18f1e70c IS |
333 | lagged:1, |
334 | split:1; | |
56ade8fe | 335 | u16 pvid; |
0d65fc13 | 336 | u16 lag_id; |
7f71eb46 IS |
337 | struct { |
338 | struct list_head list; | |
d0ec875a | 339 | struct mlxsw_sp_fid *f; |
7f71eb46 IS |
340 | u16 vid; |
341 | } vport; | |
9f7ec052 IS |
342 | struct { |
343 | u8 tx_pause:1, | |
344 | rx_pause:1; | |
345 | } link; | |
8e8dfe9f IS |
346 | struct { |
347 | struct ieee_ets *ets; | |
cc7cf517 | 348 | struct ieee_maxrate *maxrate; |
d81a6bdb | 349 | struct ieee_pfc *pfc; |
8e8dfe9f | 350 | } dcb; |
d664b41e IS |
351 | struct { |
352 | u8 module; | |
353 | u8 width; | |
354 | u8 lane; | |
355 | } mapping; | |
56ade8fe | 356 | /* 802.1Q bridge VLANs */ |
bd40e9d6 | 357 | unsigned long *active_vlans; |
fc1273af | 358 | unsigned long *untagged_vlans; |
56ade8fe | 359 | /* VLAN interfaces */ |
7f71eb46 | 360 | struct list_head vports_list; |
763b4b70 YG |
361 | /* TC handles */ |
362 | struct list_head mall_tc_list; | |
56ade8fe JP |
363 | }; |
364 | ||
7ce856aa JP |
365 | struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev); |
366 | void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port); | |
367 | ||
9f7ec052 IS |
368 | static inline bool |
369 | mlxsw_sp_port_is_pause_en(const struct mlxsw_sp_port *mlxsw_sp_port) | |
370 | { | |
371 | return mlxsw_sp_port->link.tx_pause || mlxsw_sp_port->link.rx_pause; | |
372 | } | |
373 | ||
0d65fc13 JP |
374 | static inline struct mlxsw_sp_port * |
375 | mlxsw_sp_port_lagged_get(struct mlxsw_sp *mlxsw_sp, u16 lag_id, u8 port_index) | |
376 | { | |
377 | struct mlxsw_sp_port *mlxsw_sp_port; | |
378 | u8 local_port; | |
379 | ||
380 | local_port = mlxsw_core_lag_mapping_get(mlxsw_sp->core, | |
381 | lag_id, port_index); | |
382 | mlxsw_sp_port = mlxsw_sp->ports[local_port]; | |
383 | return mlxsw_sp_port && mlxsw_sp_port->lagged ? mlxsw_sp_port : NULL; | |
384 | } | |
385 | ||
7f71eb46 IS |
386 | static inline u16 |
387 | mlxsw_sp_vport_vid_get(const struct mlxsw_sp_port *mlxsw_sp_vport) | |
388 | { | |
389 | return mlxsw_sp_vport->vport.vid; | |
390 | } | |
391 | ||
6381b3a8 IS |
392 | static inline bool |
393 | mlxsw_sp_port_is_vport(const struct mlxsw_sp_port *mlxsw_sp_port) | |
394 | { | |
395 | u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_port); | |
396 | ||
397 | return vid != 0; | |
398 | } | |
399 | ||
41b996cc IS |
400 | static inline void mlxsw_sp_vport_fid_set(struct mlxsw_sp_port *mlxsw_sp_vport, |
401 | struct mlxsw_sp_fid *f) | |
402 | { | |
403 | mlxsw_sp_vport->vport.f = f; | |
404 | } | |
405 | ||
406 | static inline struct mlxsw_sp_fid * | |
d0ec875a | 407 | mlxsw_sp_vport_fid_get(const struct mlxsw_sp_port *mlxsw_sp_vport) |
7f71eb46 | 408 | { |
41b996cc IS |
409 | return mlxsw_sp_vport->vport.f; |
410 | } | |
411 | ||
412 | static inline struct net_device * | |
3ba2ebf4 | 413 | mlxsw_sp_vport_dev_get(const struct mlxsw_sp_port *mlxsw_sp_vport) |
41b996cc IS |
414 | { |
415 | struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport); | |
416 | ||
56918b6b | 417 | return f ? f->dev : NULL; |
7f71eb46 IS |
418 | } |
419 | ||
420 | static inline struct mlxsw_sp_port * | |
421 | mlxsw_sp_port_vport_find(const struct mlxsw_sp_port *mlxsw_sp_port, u16 vid) | |
422 | { | |
423 | struct mlxsw_sp_port *mlxsw_sp_vport; | |
424 | ||
425 | list_for_each_entry(mlxsw_sp_vport, &mlxsw_sp_port->vports_list, | |
426 | vport.list) { | |
427 | if (mlxsw_sp_vport_vid_get(mlxsw_sp_vport) == vid) | |
428 | return mlxsw_sp_vport; | |
429 | } | |
430 | ||
431 | return NULL; | |
432 | } | |
433 | ||
aac78a44 | 434 | static inline struct mlxsw_sp_port * |
d0ec875a IS |
435 | mlxsw_sp_port_vport_find_by_fid(const struct mlxsw_sp_port *mlxsw_sp_port, |
436 | u16 fid) | |
aac78a44 IS |
437 | { |
438 | struct mlxsw_sp_port *mlxsw_sp_vport; | |
439 | ||
440 | list_for_each_entry(mlxsw_sp_vport, &mlxsw_sp_port->vports_list, | |
441 | vport.list) { | |
41b996cc IS |
442 | struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport); |
443 | ||
56918b6b | 444 | if (f && f->fid == fid) |
aac78a44 IS |
445 | return mlxsw_sp_vport; |
446 | } | |
447 | ||
448 | return NULL; | |
449 | } | |
450 | ||
701b186e IS |
451 | static inline struct mlxsw_sp_fid *mlxsw_sp_fid_find(struct mlxsw_sp *mlxsw_sp, |
452 | u16 fid) | |
453 | { | |
454 | struct mlxsw_sp_fid *f; | |
455 | ||
456 | list_for_each_entry(f, &mlxsw_sp->fids, list) | |
457 | if (f->fid == fid) | |
458 | return f; | |
459 | ||
460 | return NULL; | |
461 | } | |
462 | ||
463 | static inline struct mlxsw_sp_fid * | |
464 | mlxsw_sp_vfid_find(const struct mlxsw_sp *mlxsw_sp, | |
465 | const struct net_device *br_dev) | |
466 | { | |
467 | struct mlxsw_sp_fid *f; | |
468 | ||
469 | list_for_each_entry(f, &mlxsw_sp->vfids.list, list) | |
470 | if (f->dev == br_dev) | |
471 | return f; | |
472 | ||
473 | return NULL; | |
474 | } | |
475 | ||
fa3054f5 IS |
476 | static inline struct mlxsw_sp_rif * |
477 | mlxsw_sp_rif_find_by_dev(const struct mlxsw_sp *mlxsw_sp, | |
478 | const struct net_device *dev) | |
479 | { | |
480 | int i; | |
481 | ||
482 | for (i = 0; i < MLXSW_SP_RIF_MAX; i++) | |
483 | if (mlxsw_sp->rifs[i] && mlxsw_sp->rifs[i]->dev == dev) | |
484 | return mlxsw_sp->rifs[i]; | |
485 | ||
486 | return NULL; | |
487 | } | |
488 | ||
56ade8fe JP |
489 | enum mlxsw_sp_flood_table { |
490 | MLXSW_SP_FLOOD_TABLE_UC, | |
491 | MLXSW_SP_FLOOD_TABLE_BM, | |
492 | }; | |
493 | ||
494 | int mlxsw_sp_buffers_init(struct mlxsw_sp *mlxsw_sp); | |
0f433fa0 | 495 | void mlxsw_sp_buffers_fini(struct mlxsw_sp *mlxsw_sp); |
56ade8fe | 496 | int mlxsw_sp_port_buffers_init(struct mlxsw_sp_port *mlxsw_sp_port); |
0f433fa0 JP |
497 | int mlxsw_sp_sb_pool_get(struct mlxsw_core *mlxsw_core, |
498 | unsigned int sb_index, u16 pool_index, | |
499 | struct devlink_sb_pool_info *pool_info); | |
500 | int mlxsw_sp_sb_pool_set(struct mlxsw_core *mlxsw_core, | |
501 | unsigned int sb_index, u16 pool_index, u32 size, | |
502 | enum devlink_sb_threshold_type threshold_type); | |
503 | int mlxsw_sp_sb_port_pool_get(struct mlxsw_core_port *mlxsw_core_port, | |
504 | unsigned int sb_index, u16 pool_index, | |
505 | u32 *p_threshold); | |
506 | int mlxsw_sp_sb_port_pool_set(struct mlxsw_core_port *mlxsw_core_port, | |
507 | unsigned int sb_index, u16 pool_index, | |
508 | u32 threshold); | |
509 | int mlxsw_sp_sb_tc_pool_bind_get(struct mlxsw_core_port *mlxsw_core_port, | |
510 | unsigned int sb_index, u16 tc_index, | |
511 | enum devlink_sb_pool_type pool_type, | |
512 | u16 *p_pool_index, u32 *p_threshold); | |
513 | int mlxsw_sp_sb_tc_pool_bind_set(struct mlxsw_core_port *mlxsw_core_port, | |
514 | unsigned int sb_index, u16 tc_index, | |
515 | enum devlink_sb_pool_type pool_type, | |
516 | u16 pool_index, u32 threshold); | |
2d0ed39f JP |
517 | int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core, |
518 | unsigned int sb_index); | |
519 | int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core, | |
520 | unsigned int sb_index); | |
521 | int mlxsw_sp_sb_occ_port_pool_get(struct mlxsw_core_port *mlxsw_core_port, | |
522 | unsigned int sb_index, u16 pool_index, | |
523 | u32 *p_cur, u32 *p_max); | |
524 | int mlxsw_sp_sb_occ_tc_port_bind_get(struct mlxsw_core_port *mlxsw_core_port, | |
525 | unsigned int sb_index, u16 tc_index, | |
526 | enum devlink_sb_pool_type pool_type, | |
527 | u32 *p_cur, u32 *p_max); | |
56ade8fe JP |
528 | |
529 | int mlxsw_sp_switchdev_init(struct mlxsw_sp *mlxsw_sp); | |
530 | void mlxsw_sp_switchdev_fini(struct mlxsw_sp *mlxsw_sp); | |
531 | int mlxsw_sp_port_vlan_init(struct mlxsw_sp_port *mlxsw_sp_port); | |
532 | void mlxsw_sp_port_switchdev_init(struct mlxsw_sp_port *mlxsw_sp_port); | |
533 | void mlxsw_sp_port_switchdev_fini(struct mlxsw_sp_port *mlxsw_sp_port); | |
534 | int mlxsw_sp_port_vid_to_fid_set(struct mlxsw_sp_port *mlxsw_sp_port, | |
535 | enum mlxsw_reg_svfa_mt mt, bool valid, u16 fid, | |
536 | u16 vid); | |
537 | int mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid_begin, | |
538 | u16 vid_end, bool is_member, bool untagged); | |
539 | int mlxsw_sp_port_add_vid(struct net_device *dev, __be16 __always_unused proto, | |
540 | u16 vid); | |
e6060027 | 541 | int mlxsw_sp_vport_flood_set(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid, |
47a0a9e6 | 542 | bool set); |
4dc236c3 | 543 | void mlxsw_sp_port_active_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port); |
28a01d2d | 544 | int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid); |
fe3f6d14 | 545 | int mlxsw_sp_port_fdb_flush(struct mlxsw_sp_port *mlxsw_sp_port, u16 fid); |
6e095fd4 IS |
546 | int mlxsw_sp_rif_fdb_op(struct mlxsw_sp *mlxsw_sp, const char *mac, u16 fid, |
547 | bool adding); | |
701b186e IS |
548 | struct mlxsw_sp_fid *mlxsw_sp_fid_create(struct mlxsw_sp *mlxsw_sp, u16 fid); |
549 | void mlxsw_sp_fid_destroy(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_fid *f); | |
99f44bb3 IS |
550 | void mlxsw_sp_rif_bridge_destroy(struct mlxsw_sp *mlxsw_sp, |
551 | struct mlxsw_sp_rif *r); | |
8e8dfe9f IS |
552 | int mlxsw_sp_port_ets_set(struct mlxsw_sp_port *mlxsw_sp_port, |
553 | enum mlxsw_reg_qeec_hr hr, u8 index, u8 next_index, | |
554 | bool dwrr, u8 dwrr_weight); | |
555 | int mlxsw_sp_port_prio_tc_set(struct mlxsw_sp_port *mlxsw_sp_port, | |
556 | u8 switch_prio, u8 tclass); | |
557 | int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu, | |
d81a6bdb IS |
558 | u8 *prio_tc, bool pause_en, |
559 | struct ieee_pfc *my_pfc); | |
cc7cf517 IS |
560 | int mlxsw_sp_port_ets_maxrate_set(struct mlxsw_sp_port *mlxsw_sp_port, |
561 | enum mlxsw_reg_qeec_hr hr, u8 index, | |
562 | u8 next_index, u32 maxrate); | |
56ade8fe | 563 | |
f00817df IS |
564 | #ifdef CONFIG_MLXSW_SPECTRUM_DCB |
565 | ||
566 | int mlxsw_sp_port_dcb_init(struct mlxsw_sp_port *mlxsw_sp_port); | |
567 | void mlxsw_sp_port_dcb_fini(struct mlxsw_sp_port *mlxsw_sp_port); | |
568 | ||
569 | #else | |
570 | ||
571 | static inline int mlxsw_sp_port_dcb_init(struct mlxsw_sp_port *mlxsw_sp_port) | |
572 | { | |
573 | return 0; | |
574 | } | |
575 | ||
576 | static inline void mlxsw_sp_port_dcb_fini(struct mlxsw_sp_port *mlxsw_sp_port) | |
577 | {} | |
578 | ||
579 | #endif | |
580 | ||
464dce18 IS |
581 | int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp); |
582 | void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp); | |
61c503f9 JP |
583 | int mlxsw_sp_router_fib4_add(struct mlxsw_sp_port *mlxsw_sp_port, |
584 | const struct switchdev_obj_ipv4_fib *fib4, | |
585 | struct switchdev_trans *trans); | |
586 | int mlxsw_sp_router_fib4_del(struct mlxsw_sp_port *mlxsw_sp_port, | |
587 | const struct switchdev_obj_ipv4_fib *fib4); | |
6cf3c971 JP |
588 | int mlxsw_sp_router_neigh_construct(struct net_device *dev, |
589 | struct neighbour *n); | |
590 | void mlxsw_sp_router_neigh_destroy(struct net_device *dev, | |
591 | struct neighbour *n); | |
464dce18 | 592 | |
b090ef06 JP |
593 | int mlxsw_sp_kvdl_alloc(struct mlxsw_sp *mlxsw_sp, unsigned int entry_count); |
594 | void mlxsw_sp_kvdl_free(struct mlxsw_sp *mlxsw_sp, int entry_index); | |
595 | ||
56ade8fe | 596 | #endif |