GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / net / ethernet / marvell / prestera / prestera_router_hw.h
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_ */