1b4da4235SEdward Cree /* SPDX-License-Identifier: GPL-2.0-only */
2b4da4235SEdward Cree /****************************************************************************
3b4da4235SEdward Cree  * Driver for Solarflare network controllers and boards
4b4da4235SEdward Cree  * Copyright 2023, Advanced Micro Devices, Inc.
5b4da4235SEdward Cree  *
6b4da4235SEdward Cree  * This program is free software; you can redistribute it and/or modify it
7b4da4235SEdward Cree  * under the terms of the GNU General Public License version 2 as published
8b4da4235SEdward Cree  * by the Free Software Foundation, incorporated herein by reference.
9b4da4235SEdward Cree  */
10b4da4235SEdward Cree 
11b4da4235SEdward Cree #ifndef EFX_TC_ENCAP_ACTIONS_H
12b4da4235SEdward Cree #define EFX_TC_ENCAP_ACTIONS_H
13b4da4235SEdward Cree #include "net_driver.h"
14b4da4235SEdward Cree 
15*c08afcdcSEdward Cree #if IS_ENABLED(CONFIG_SFC_SRIOV)
16b4da4235SEdward Cree #include <linux/refcount.h>
17b4da4235SEdward Cree #include <net/tc_act/tc_tunnel_key.h>
18b4da4235SEdward Cree 
197e5e7d80SEdward Cree /**
207e5e7d80SEdward Cree  * struct efx_neigh_binder - driver state for a neighbour entry
217e5e7d80SEdward Cree  * @net: the network namespace in which this neigh resides
227e5e7d80SEdward Cree  * @dst_ip: the IPv4 destination address resolved by this neigh
237e5e7d80SEdward Cree  * @dst_ip6: the IPv6 destination address resolved by this neigh
247e5e7d80SEdward Cree  * @ha: the hardware (Ethernet) address of the neighbour
257e5e7d80SEdward Cree  * @n_valid: true if the neighbour is in NUD_VALID state
267e5e7d80SEdward Cree  * @lock: protects @ha and @n_valid
277e5e7d80SEdward Cree  * @ttl: Time To Live associated with the route used
287e5e7d80SEdward Cree  * @dying: set when egdev is going away, to skip further updates
297e5e7d80SEdward Cree  * @egdev: egress device from the route lookup.  Holds a reference
307e5e7d80SEdward Cree  * @dev_tracker: reference tracker entry for @egdev
317e5e7d80SEdward Cree  * @ns_tracker: reference tracker entry for @ns
327e5e7d80SEdward Cree  * @ref: counts encap actions referencing this entry
337e5e7d80SEdward Cree  * @used: jiffies of last time traffic hit any encap action using this.
347e5e7d80SEdward Cree  *      When counter reads update this, a new neighbour event is sent to
357e5e7d80SEdward Cree  *      indicate that the neighbour entry is still in use.
367e5e7d80SEdward Cree  * @users: list of &struct efx_tc_encap_action
377e5e7d80SEdward Cree  * @linkage: entry in efx->neigh_ht (keys are @net, @dst_ip, @dst_ip6).
387e5e7d80SEdward Cree  * @work: processes neighbour state changes, updates the encap actions
397e5e7d80SEdward Cree  * @efx: owning NIC instance.
407e5e7d80SEdward Cree  *
417e5e7d80SEdward Cree  * Associates a neighbour entry with the encap actions that are
427e5e7d80SEdward Cree  * interested in it, allowing the latter to be updated when the
437e5e7d80SEdward Cree  * neighbour details change.
447e5e7d80SEdward Cree  * Whichever of @dst_ip and @dst_ip6 is not in use will be all-zeroes,
457e5e7d80SEdward Cree  * this distinguishes IPv4 from IPv6 entries.
467e5e7d80SEdward Cree  */
477e5e7d80SEdward Cree struct efx_neigh_binder {
487e5e7d80SEdward Cree 	struct net *net;
497e5e7d80SEdward Cree 	__be32 dst_ip;
507e5e7d80SEdward Cree 	struct in6_addr dst_ip6;
517e5e7d80SEdward Cree 	char ha[ETH_ALEN];
527e5e7d80SEdward Cree 	bool n_valid;
537e5e7d80SEdward Cree 	rwlock_t lock;
547e5e7d80SEdward Cree 	u8 ttl;
557e5e7d80SEdward Cree 	bool dying;
567e5e7d80SEdward Cree 	struct net_device *egdev;
577e5e7d80SEdward Cree 	netdevice_tracker dev_tracker;
587e5e7d80SEdward Cree 	netns_tracker ns_tracker;
597e5e7d80SEdward Cree 	refcount_t ref;
607e5e7d80SEdward Cree 	unsigned long used;
617e5e7d80SEdward Cree 	struct list_head users;
627e5e7d80SEdward Cree 	struct rhash_head linkage;
637e5e7d80SEdward Cree 	struct work_struct work;
647e5e7d80SEdward Cree 	struct efx_nic *efx;
657e5e7d80SEdward Cree };
667e5e7d80SEdward Cree 
67b4da4235SEdward Cree /* This limit is arbitrary; current hardware (SN1022) handles encap headers
68b4da4235SEdward Cree  * of up to 126 bytes, but that limit is not enshrined in the MCDI protocol.
69b4da4235SEdward Cree  */
70b4da4235SEdward Cree #define EFX_TC_MAX_ENCAP_HDR	126
71b4da4235SEdward Cree struct efx_tc_encap_action {
72b4da4235SEdward Cree 	enum efx_encap_type type;
73b4da4235SEdward Cree 	struct ip_tunnel_key key; /* 52 bytes */
74b4da4235SEdward Cree 	u32 dest_mport; /* is copied into struct efx_tc_action_set */
75b4da4235SEdward Cree 	u8 encap_hdr_len;
767e5e7d80SEdward Cree 	bool n_valid;
77b4da4235SEdward Cree 	u8 encap_hdr[EFX_TC_MAX_ENCAP_HDR];
787e5e7d80SEdward Cree 	struct efx_neigh_binder *neigh;
797e5e7d80SEdward Cree 	struct list_head list; /* entry on neigh->users list */
807e5e7d80SEdward Cree 	struct list_head users; /* action sets using this encap_md */
81b4da4235SEdward Cree 	struct rhash_head linkage; /* efx->tc_encap_ht */
82b4da4235SEdward Cree 	refcount_t ref;
83b4da4235SEdward Cree 	u32 fw_id; /* index of this entry in firmware encap table */
84b4da4235SEdward Cree };
85b4da4235SEdward Cree 
86b4da4235SEdward Cree /* create/uncreate/teardown hashtables */
87b4da4235SEdward Cree int efx_tc_init_encap_actions(struct efx_nic *efx);
88b4da4235SEdward Cree void efx_tc_destroy_encap_actions(struct efx_nic *efx);
89b4da4235SEdward Cree void efx_tc_fini_encap_actions(struct efx_nic *efx);
90b4da4235SEdward Cree 
91b4da4235SEdward Cree struct efx_tc_flow_rule;
92b4da4235SEdward Cree bool efx_tc_check_ready(struct efx_nic *efx, struct efx_tc_flow_rule *rule);
93b4da4235SEdward Cree 
94b4da4235SEdward Cree struct efx_tc_encap_action *efx_tc_flower_create_encap_md(
95b4da4235SEdward Cree 			struct efx_nic *efx, const struct ip_tunnel_info *info,
96b4da4235SEdward Cree 			struct net_device *egdev, struct netlink_ext_ack *extack);
97b4da4235SEdward Cree void efx_tc_flower_release_encap_md(struct efx_nic *efx,
98b4da4235SEdward Cree 				    struct efx_tc_encap_action *encap);
99b4da4235SEdward Cree 
1007e5e7d80SEdward Cree void efx_tc_unregister_egdev(struct efx_nic *efx, struct net_device *net_dev);
1017e5e7d80SEdward Cree int efx_tc_netevent_event(struct efx_nic *efx, unsigned long event,
1027e5e7d80SEdward Cree 			  void *ptr);
1037e5e7d80SEdward Cree 
104*c08afcdcSEdward Cree #else /* CONFIG_SFC_SRIOV */
105*c08afcdcSEdward Cree 
efx_tc_netevent_event(struct efx_nic * efx,unsigned long event,void * ptr)106*c08afcdcSEdward Cree static inline int efx_tc_netevent_event(struct efx_nic *efx,
107*c08afcdcSEdward Cree 					unsigned long event, void *ptr)
108*c08afcdcSEdward Cree {
109*c08afcdcSEdward Cree 	return NOTIFY_DONE;
110*c08afcdcSEdward Cree }
111*c08afcdcSEdward Cree 
112*c08afcdcSEdward Cree #endif /* CONFIG_SFC_SRIOV */
113*c08afcdcSEdward Cree 
114b4da4235SEdward Cree #endif /* EFX_TC_ENCAP_ACTIONS_H */
115