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