1 | /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ |
2 | /* Copyright (c) 2019-2021 Marvell International Ltd. All rights reserved. */ |
3 | |
4 | #ifndef _PRESTERA_ROUTER_HW_H_ |
5 | #define _PRESTERA_ROUTER_HW_H_ |
6 | |
7 | struct prestera_vr { |
8 | struct list_head router_node; |
9 | refcount_t refcount; |
10 | u32 tb_id; /* key (kernel fib table id) */ |
11 | u16 hw_vr_id; /* virtual router ID */ |
12 | u8 __pad[2]; |
13 | }; |
14 | |
15 | struct prestera_rif_entry { |
16 | struct prestera_rif_entry_key { |
17 | struct prestera_iface iface; |
18 | } key; |
19 | struct prestera_vr *vr; |
20 | unsigned char addr[ETH_ALEN]; |
21 | u16 hw_id; /* rif_id */ |
22 | struct list_head router_node; /* ht */ |
23 | }; |
24 | |
25 | struct prestera_ip_addr { |
26 | union { |
27 | __be32 ipv4; |
28 | struct in6_addr ipv6; |
29 | } u; |
30 | enum { |
31 | PRESTERA_IPV4 = 0, |
32 | PRESTERA_IPV6 |
33 | } v; |
34 | #define PRESTERA_IP_ADDR_PLEN(V) ((V) == PRESTERA_IPV4 ? 32 : \ |
35 | /* (V) == PRESTERA_IPV6 ? */ 128 /* : 0 */) |
36 | }; |
37 | |
38 | struct prestera_nh_neigh_key { |
39 | struct prestera_ip_addr addr; |
40 | /* Seems like rif is obsolete, because there is iface in info ? |
41 | * Key can contain functional fields, or fields, which is used to |
42 | * filter duplicate objects on logical level (before you pass it to |
43 | * HW)... also key can be used to cover hardware restrictions. |
44 | * In our case rif - is logical interface (even can be VLAN), which |
45 | * is used in combination with IP address (which is also not related to |
46 | * hardware nexthop) to provide logical compression of created nexthops. |
47 | * You even can imagine, that rif+IPaddr is just cookie. |
48 | */ |
49 | /* struct prestera_rif *rif; */ |
50 | /* Use just as cookie, to divide ARP domains (in order with addr) */ |
51 | void *rif; |
52 | }; |
53 | |
54 | /* Used for hw call */ |
55 | struct prestera_neigh_info { |
56 | struct prestera_iface iface; |
57 | unsigned char ha[ETH_ALEN]; |
58 | u8 connected; /* bool. indicate, if mac/oif valid */ |
59 | u8 __pad[1]; |
60 | }; |
61 | |
62 | /* Used to notify nh about neigh change */ |
63 | struct prestera_nh_neigh { |
64 | struct prestera_nh_neigh_key key; |
65 | struct prestera_neigh_info info; |
66 | struct rhash_head ht_node; /* node of prestera_vr */ |
67 | struct list_head nexthop_group_list; |
68 | }; |
69 | |
70 | #define PRESTERA_NHGR_SIZE_MAX 4 |
71 | |
72 | struct prestera_nexthop_group { |
73 | struct prestera_nexthop_group_key { |
74 | struct prestera_nh_neigh_key neigh[PRESTERA_NHGR_SIZE_MAX]; |
75 | } key; |
76 | /* Store intermediate object here. |
77 | * This prevent overhead kzalloc call. |
78 | */ |
79 | /* nh_neigh is used only to notify nexthop_group */ |
80 | struct prestera_nh_neigh_head { |
81 | struct prestera_nexthop_group *this; |
82 | struct list_head head; |
83 | /* ptr to neigh is not necessary. |
84 | * It used to prevent lookup of nh_neigh by key (n) on destroy |
85 | */ |
86 | struct prestera_nh_neigh *neigh; |
87 | } nh_neigh_head[PRESTERA_NHGR_SIZE_MAX]; |
88 | struct rhash_head ht_node; /* node of prestera_vr */ |
89 | refcount_t refcount; |
90 | u32 grp_id; /* hw */ |
91 | }; |
92 | |
93 | struct prestera_fib_key { |
94 | struct prestera_ip_addr addr; |
95 | u32 prefix_len; |
96 | u32 tb_id; |
97 | }; |
98 | |
99 | struct prestera_fib_info { |
100 | struct prestera_vr *vr; |
101 | struct list_head vr_node; |
102 | enum prestera_fib_type { |
103 | PRESTERA_FIB_TYPE_INVALID = 0, |
104 | /* must be pointer to nh_grp id */ |
105 | PRESTERA_FIB_TYPE_UC_NH, |
106 | /* It can be connected route |
107 | * and will be overlapped with neighbours |
108 | */ |
109 | PRESTERA_FIB_TYPE_TRAP, |
110 | PRESTERA_FIB_TYPE_DROP |
111 | } type; |
112 | /* Valid only if type = UC_NH*/ |
113 | struct prestera_nexthop_group *nh_grp; |
114 | }; |
115 | |
116 | struct prestera_fib_node { |
117 | struct rhash_head ht_node; /* node of prestera_vr */ |
118 | struct prestera_fib_key key; |
119 | struct prestera_fib_info info; /* action related info */ |
120 | }; |
121 | |
122 | struct prestera_rif_entry * |
123 | prestera_rif_entry_find(const struct prestera_switch *sw, |
124 | const struct prestera_rif_entry_key *k); |
125 | void prestera_rif_entry_destroy(struct prestera_switch *sw, |
126 | struct prestera_rif_entry *e); |
127 | struct prestera_rif_entry * |
128 | prestera_rif_entry_create(struct prestera_switch *sw, |
129 | struct prestera_rif_entry_key *k, |
130 | u32 tb_id, const unsigned char *addr); |
131 | struct prestera_nh_neigh * |
132 | prestera_nh_neigh_find(struct prestera_switch *sw, |
133 | struct prestera_nh_neigh_key *key); |
134 | struct prestera_nh_neigh * |
135 | prestera_nh_neigh_get(struct prestera_switch *sw, |
136 | struct prestera_nh_neigh_key *key); |
137 | void prestera_nh_neigh_put(struct prestera_switch *sw, |
138 | struct prestera_nh_neigh *neigh); |
139 | int prestera_nh_neigh_set(struct prestera_switch *sw, |
140 | struct prestera_nh_neigh *neigh); |
141 | bool prestera_nh_neigh_util_hw_state(struct prestera_switch *sw, |
142 | struct prestera_nh_neigh *nh_neigh); |
143 | struct prestera_fib_node *prestera_fib_node_find(struct prestera_switch *sw, |
144 | struct prestera_fib_key *key); |
145 | void prestera_fib_node_destroy(struct prestera_switch *sw, |
146 | struct prestera_fib_node *fib_node); |
147 | struct prestera_fib_node * |
148 | prestera_fib_node_create(struct prestera_switch *sw, |
149 | struct prestera_fib_key *key, |
150 | enum prestera_fib_type fib_type, |
151 | struct prestera_nexthop_group_key *nh_grp_key); |
152 | int prestera_router_hw_init(struct prestera_switch *sw); |
153 | void prestera_router_hw_fini(struct prestera_switch *sw); |
154 | |
155 | #endif /* _PRESTERA_ROUTER_HW_H_ */ |
156 | |