162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _SUNVNETCOMMON_H
362306a36Sopenharmony_ci#define _SUNVNETCOMMON_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/interrupt.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci/* length of time (or less) we expect pending descriptors to be marked
862306a36Sopenharmony_ci * as VIO_DESC_DONE and skbs ready to be freed
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci#define	VNET_CLEAN_TIMEOUT		((HZ / 100) + 1)
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#define VNET_MAXPACKET			(65535ULL + ETH_HLEN + VLAN_HLEN)
1362306a36Sopenharmony_ci#define VNET_TX_RING_SIZE		512
1462306a36Sopenharmony_ci#define VNET_TX_WAKEUP_THRESH(dr)	((dr)->pending / 4)
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define	VNET_MINTSO	 2048	/* VIO protocol's minimum TSO len */
1762306a36Sopenharmony_ci#define	VNET_MAXTSO	65535	/* VIO protocol's maximum TSO len */
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#define VNET_MAX_MTU	65535
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/* VNET packets are sent in buffers with the first 6 bytes skipped
2262306a36Sopenharmony_ci * so that after the ethernet header the IPv4/IPv6 headers are aligned
2362306a36Sopenharmony_ci * properly.
2462306a36Sopenharmony_ci */
2562306a36Sopenharmony_ci#define VNET_PACKET_SKIP		6
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#define	VNET_MAXCOOKIES			(VNET_MAXPACKET / PAGE_SIZE + 1)
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#define	VNET_MAX_TXQS		16
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cistruct vnet_tx_entry {
3262306a36Sopenharmony_ci	struct sk_buff		*skb;
3362306a36Sopenharmony_ci	unsigned int		ncookies;
3462306a36Sopenharmony_ci	struct ldc_trans_cookie	cookies[VNET_MAXCOOKIES];
3562306a36Sopenharmony_ci};
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_cistruct vnet;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_cistruct vnet_port_stats {
4062306a36Sopenharmony_ci	/* keep them all the same size */
4162306a36Sopenharmony_ci	u32 rx_bytes;
4262306a36Sopenharmony_ci	u32 tx_bytes;
4362306a36Sopenharmony_ci	u32 rx_packets;
4462306a36Sopenharmony_ci	u32 tx_packets;
4562306a36Sopenharmony_ci	u32 event_up;
4662306a36Sopenharmony_ci	u32 event_reset;
4762306a36Sopenharmony_ci	u32 q_placeholder;
4862306a36Sopenharmony_ci};
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#define NUM_VNET_PORT_STATS  (sizeof(struct vnet_port_stats) / sizeof(u32))
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/* Structure to describe a vnet-port or vsw-port in the MD.
5362306a36Sopenharmony_ci * If the vsw bit is set, this structure represents a vswitch
5462306a36Sopenharmony_ci * port, and the net_device can be found from ->dev. If the
5562306a36Sopenharmony_ci * vsw bit is not set, the net_device is available from ->vp->dev.
5662306a36Sopenharmony_ci * See the VNET_PORT_TO_NET_DEVICE macro below.
5762306a36Sopenharmony_ci */
5862306a36Sopenharmony_cistruct vnet_port {
5962306a36Sopenharmony_ci	struct vio_driver_state	vio;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	struct vnet_port_stats stats;
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	struct hlist_node	hash;
6462306a36Sopenharmony_ci	u8			raddr[ETH_ALEN];
6562306a36Sopenharmony_ci	unsigned		switch_port:1;
6662306a36Sopenharmony_ci	unsigned		tso:1;
6762306a36Sopenharmony_ci	unsigned		vsw:1;
6862306a36Sopenharmony_ci	unsigned		__pad:13;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	struct vnet		*vp;
7162306a36Sopenharmony_ci	struct net_device	*dev;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	struct vnet_tx_entry	tx_bufs[VNET_TX_RING_SIZE];
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	struct list_head	list;
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	u32			stop_rx_idx;
7862306a36Sopenharmony_ci	bool			stop_rx;
7962306a36Sopenharmony_ci	bool			start_cons;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	struct timer_list	clean_timer;
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	u64			rmtu;
8462306a36Sopenharmony_ci	u16			tsolen;
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	struct napi_struct	napi;
8762306a36Sopenharmony_ci	u32			napi_stop_idx;
8862306a36Sopenharmony_ci	bool			napi_resume;
8962306a36Sopenharmony_ci	int			rx_event;
9062306a36Sopenharmony_ci	u16			q_index;
9162306a36Sopenharmony_ci};
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cistatic inline struct vnet_port *to_vnet_port(struct vio_driver_state *vio)
9462306a36Sopenharmony_ci{
9562306a36Sopenharmony_ci	return container_of(vio, struct vnet_port, vio);
9662306a36Sopenharmony_ci}
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci#define VNET_PORT_HASH_SIZE	16
9962306a36Sopenharmony_ci#define VNET_PORT_HASH_MASK	(VNET_PORT_HASH_SIZE - 1)
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_cistatic inline unsigned int vnet_hashfn(u8 *mac)
10262306a36Sopenharmony_ci{
10362306a36Sopenharmony_ci	unsigned int val = mac[4] ^ mac[5];
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	return val & (VNET_PORT_HASH_MASK);
10662306a36Sopenharmony_ci}
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_cistruct vnet_mcast_entry {
10962306a36Sopenharmony_ci	u8			addr[ETH_ALEN];
11062306a36Sopenharmony_ci	u8			sent;
11162306a36Sopenharmony_ci	u8			hit;
11262306a36Sopenharmony_ci	struct vnet_mcast_entry	*next;
11362306a36Sopenharmony_ci};
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_cistruct vnet {
11662306a36Sopenharmony_ci	spinlock_t		lock; /* Protects port_list and port_hash.  */
11762306a36Sopenharmony_ci	struct net_device	*dev;
11862306a36Sopenharmony_ci	u32			msg_enable;
11962306a36Sopenharmony_ci	u8			q_used[VNET_MAX_TXQS];
12062306a36Sopenharmony_ci	struct list_head	port_list;
12162306a36Sopenharmony_ci	struct hlist_head	port_hash[VNET_PORT_HASH_SIZE];
12262306a36Sopenharmony_ci	struct vnet_mcast_entry	*mcast_list;
12362306a36Sopenharmony_ci	struct list_head	list;
12462306a36Sopenharmony_ci	u64			local_mac;
12562306a36Sopenharmony_ci	int			nports;
12662306a36Sopenharmony_ci};
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci/* Def used by common code to get the net_device from the proper location */
12962306a36Sopenharmony_ci#define VNET_PORT_TO_NET_DEVICE(__port) \
13062306a36Sopenharmony_ci	((__port)->vsw ? (__port)->dev : (__port)->vp->dev)
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci/* Common funcs */
13362306a36Sopenharmony_civoid sunvnet_clean_timer_expire_common(struct timer_list *t);
13462306a36Sopenharmony_ciint sunvnet_open_common(struct net_device *dev);
13562306a36Sopenharmony_ciint sunvnet_close_common(struct net_device *dev);
13662306a36Sopenharmony_civoid sunvnet_set_rx_mode_common(struct net_device *dev, struct vnet *vp);
13762306a36Sopenharmony_ciint sunvnet_set_mac_addr_common(struct net_device *dev, void *p);
13862306a36Sopenharmony_civoid sunvnet_tx_timeout_common(struct net_device *dev, unsigned int txqueue);
13962306a36Sopenharmony_cinetdev_tx_t
14062306a36Sopenharmony_cisunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
14162306a36Sopenharmony_ci			  struct vnet_port *(*vnet_tx_port)
14262306a36Sopenharmony_ci			  (struct sk_buff *, struct net_device *));
14362306a36Sopenharmony_ci#ifdef CONFIG_NET_POLL_CONTROLLER
14462306a36Sopenharmony_civoid sunvnet_poll_controller_common(struct net_device *dev, struct vnet *vp);
14562306a36Sopenharmony_ci#endif
14662306a36Sopenharmony_civoid sunvnet_event_common(void *arg, int event);
14762306a36Sopenharmony_ciint sunvnet_send_attr_common(struct vio_driver_state *vio);
14862306a36Sopenharmony_ciint sunvnet_handle_attr_common(struct vio_driver_state *vio, void *arg);
14962306a36Sopenharmony_civoid sunvnet_handshake_complete_common(struct vio_driver_state *vio);
15062306a36Sopenharmony_ciint sunvnet_poll_common(struct napi_struct *napi, int budget);
15162306a36Sopenharmony_civoid sunvnet_port_free_tx_bufs_common(struct vnet_port *port);
15262306a36Sopenharmony_civoid vnet_port_reset(struct vnet_port *port);
15362306a36Sopenharmony_cibool sunvnet_port_is_up_common(struct vnet_port *vnet);
15462306a36Sopenharmony_civoid sunvnet_port_add_txq_common(struct vnet_port *port);
15562306a36Sopenharmony_civoid sunvnet_port_rm_txq_common(struct vnet_port *port);
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci#endif /* _SUNVNETCOMMON_H */
158