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
7struct 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
15struct 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
25struct 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
38struct 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 */
55struct 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 */
63struct 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
72struct 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
93struct prestera_fib_key {
94 struct prestera_ip_addr addr;
95 u32 prefix_len;
96 u32 tb_id;
97};
98
99struct 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
116struct 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
122struct prestera_rif_entry *
123prestera_rif_entry_find(const struct prestera_switch *sw,
124 const struct prestera_rif_entry_key *k);
125void prestera_rif_entry_destroy(struct prestera_switch *sw,
126 struct prestera_rif_entry *e);
127struct prestera_rif_entry *
128prestera_rif_entry_create(struct prestera_switch *sw,
129 struct prestera_rif_entry_key *k,
130 u32 tb_id, const unsigned char *addr);
131struct prestera_nh_neigh *
132prestera_nh_neigh_find(struct prestera_switch *sw,
133 struct prestera_nh_neigh_key *key);
134struct prestera_nh_neigh *
135prestera_nh_neigh_get(struct prestera_switch *sw,
136 struct prestera_nh_neigh_key *key);
137void prestera_nh_neigh_put(struct prestera_switch *sw,
138 struct prestera_nh_neigh *neigh);
139int prestera_nh_neigh_set(struct prestera_switch *sw,
140 struct prestera_nh_neigh *neigh);
141bool prestera_nh_neigh_util_hw_state(struct prestera_switch *sw,
142 struct prestera_nh_neigh *nh_neigh);
143struct prestera_fib_node *prestera_fib_node_find(struct prestera_switch *sw,
144 struct prestera_fib_key *key);
145void prestera_fib_node_destroy(struct prestera_switch *sw,
146 struct prestera_fib_node *fib_node);
147struct prestera_fib_node *
148prestera_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);
152int prestera_router_hw_init(struct prestera_switch *sw);
153void prestera_router_hw_fini(struct prestera_switch *sw);
154
155#endif /* _PRESTERA_ROUTER_HW_H_ */
156

source code of linux/drivers/net/ethernet/marvell/prestera/prestera_router_hw.h