Linux Audio

Check our new training course

Loading...
  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_ */