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