162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef _NET_BOND_ALB_H
762306a36Sopenharmony_ci#define _NET_BOND_ALB_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/if_ether.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cistruct bonding;
1262306a36Sopenharmony_cistruct slave;
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#define BOND_ALB_INFO(bond)   ((bond)->alb_info)
1562306a36Sopenharmony_ci#define SLAVE_TLB_INFO(slave) ((slave)->tlb_info)
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#define ALB_TIMER_TICKS_PER_SEC	    10	/* should be a divisor of HZ */
1862306a36Sopenharmony_ci#define BOND_TLB_REBALANCE_INTERVAL 10	/* In seconds, periodic re-balancing.
1962306a36Sopenharmony_ci					 * Used for division - never set
2062306a36Sopenharmony_ci					 * to zero !!!
2162306a36Sopenharmony_ci					 */
2262306a36Sopenharmony_ci#define BOND_ALB_DEFAULT_LP_INTERVAL 1
2362306a36Sopenharmony_ci#define BOND_ALB_LP_INTERVAL(bond) (bond->params.lp_interval)	/* In seconds, periodic send of
2462306a36Sopenharmony_ci								 * learning packets to the switch
2562306a36Sopenharmony_ci								 */
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
2862306a36Sopenharmony_ci				  * ALB_TIMER_TICKS_PER_SEC)
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#define BOND_ALB_LP_TICKS(bond) (BOND_ALB_LP_INTERVAL(bond) \
3162306a36Sopenharmony_ci			   * ALB_TIMER_TICKS_PER_SEC)
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define TLB_HASH_TABLE_SIZE 256	/* The size of the clients hash table.
3462306a36Sopenharmony_ci				 * Note that this value MUST NOT be smaller
3562306a36Sopenharmony_ci				 * because the key hash table is BYTE wide !
3662306a36Sopenharmony_ci				 */
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#define TLB_NULL_INDEX		0xffffffff
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/* rlb defs */
4262306a36Sopenharmony_ci#define RLB_HASH_TABLE_SIZE	256
4362306a36Sopenharmony_ci#define RLB_NULL_INDEX		0xffffffff
4462306a36Sopenharmony_ci#define RLB_UPDATE_DELAY	(2*ALB_TIMER_TICKS_PER_SEC) /* 2 seconds */
4562306a36Sopenharmony_ci#define RLB_ARP_BURST_SIZE	2
4662306a36Sopenharmony_ci#define RLB_UPDATE_RETRY	3 /* 3-ticks - must be smaller than the rlb
4762306a36Sopenharmony_ci				   * rebalance interval (5 min).
4862306a36Sopenharmony_ci				   */
4962306a36Sopenharmony_ci/* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is
5062306a36Sopenharmony_ci * promiscuous after failover
5162306a36Sopenharmony_ci */
5262306a36Sopenharmony_ci#define RLB_PROMISC_TIMEOUT	(10*ALB_TIMER_TICKS_PER_SEC)
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistruct tlb_client_info {
5662306a36Sopenharmony_ci	struct slave *tx_slave;	/* A pointer to slave used for transmiting
5762306a36Sopenharmony_ci				 * packets to a Client that the Hash function
5862306a36Sopenharmony_ci				 * gave this entry index.
5962306a36Sopenharmony_ci				 */
6062306a36Sopenharmony_ci	u32 tx_bytes;		/* Each Client accumulates the BytesTx that
6162306a36Sopenharmony_ci				 * were transmitted to it, and after each
6262306a36Sopenharmony_ci				 * CallBack the LoadHistory is divided
6362306a36Sopenharmony_ci				 * by the balance interval
6462306a36Sopenharmony_ci				 */
6562306a36Sopenharmony_ci	u32 load_history;	/* This field contains the amount of Bytes
6662306a36Sopenharmony_ci				 * that were transmitted to this client by
6762306a36Sopenharmony_ci				 * the server on the previous balance
6862306a36Sopenharmony_ci				 * interval in Bps.
6962306a36Sopenharmony_ci				 */
7062306a36Sopenharmony_ci	u32 next;		/* The next Hash table entry index, assigned
7162306a36Sopenharmony_ci				 * to use the same adapter for transmit.
7262306a36Sopenharmony_ci				 */
7362306a36Sopenharmony_ci	u32 prev;		/* The previous Hash table entry index,
7462306a36Sopenharmony_ci				 * assigned to use the same
7562306a36Sopenharmony_ci				 */
7662306a36Sopenharmony_ci};
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci/* -------------------------------------------------------------------------
7962306a36Sopenharmony_ci * struct rlb_client_info contains all info related to a specific rx client
8062306a36Sopenharmony_ci * connection. This is the Clients Hash Table entry struct.
8162306a36Sopenharmony_ci * Note that this is not a proper hash table; if a new client's IP address
8262306a36Sopenharmony_ci * hash collides with an existing client entry, the old entry is replaced.
8362306a36Sopenharmony_ci *
8462306a36Sopenharmony_ci * There is a linked list (linked by the used_next and used_prev members)
8562306a36Sopenharmony_ci * linking all the used entries of the hash table. This allows updating
8662306a36Sopenharmony_ci * all the clients without walking over all the unused elements of the table.
8762306a36Sopenharmony_ci *
8862306a36Sopenharmony_ci * There are also linked lists of entries with identical hash(ip_src). These
8962306a36Sopenharmony_ci * allow cleaning up the table from ip_src<->mac_src associations that have
9062306a36Sopenharmony_ci * become outdated and would cause sending out invalid ARP updates to the
9162306a36Sopenharmony_ci * network. These are linked by the (src_next and src_prev members).
9262306a36Sopenharmony_ci * -------------------------------------------------------------------------
9362306a36Sopenharmony_ci */
9462306a36Sopenharmony_cistruct rlb_client_info {
9562306a36Sopenharmony_ci	__be32 ip_src;		/* the server IP address */
9662306a36Sopenharmony_ci	__be32 ip_dst;		/* the client IP address */
9762306a36Sopenharmony_ci	u8  mac_src[ETH_ALEN];	/* the server MAC address */
9862306a36Sopenharmony_ci	u8  mac_dst[ETH_ALEN];	/* the client MAC address */
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	/* list of used hash table entries, starting at rx_hashtbl_used_head */
10162306a36Sopenharmony_ci	u32 used_next;
10262306a36Sopenharmony_ci	u32 used_prev;
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	/* ip_src based hashing */
10562306a36Sopenharmony_ci	u32 src_next;	/* next entry with same hash(ip_src) */
10662306a36Sopenharmony_ci	u32 src_prev;	/* prev entry with same hash(ip_src) */
10762306a36Sopenharmony_ci	u32 src_first;	/* first entry with hash(ip_src) == this entry's index */
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	u8  assigned;		/* checking whether this entry is assigned */
11062306a36Sopenharmony_ci	u8  ntt;		/* flag - need to transmit client info */
11162306a36Sopenharmony_ci	struct slave *slave;	/* the slave assigned to this client */
11262306a36Sopenharmony_ci	unsigned short vlan_id;	/* VLAN tag associated with IP address */
11362306a36Sopenharmony_ci};
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_cistruct tlb_slave_info {
11662306a36Sopenharmony_ci	u32 head;	/* Index to the head of the bi-directional clients
11762306a36Sopenharmony_ci			 * hash table entries list. The entries in the list
11862306a36Sopenharmony_ci			 * are the entries that were assigned to use this
11962306a36Sopenharmony_ci			 * slave for transmit.
12062306a36Sopenharmony_ci			 */
12162306a36Sopenharmony_ci	u32 load;	/* Each slave sums the loadHistory of all clients
12262306a36Sopenharmony_ci			 * assigned to it
12362306a36Sopenharmony_ci			 */
12462306a36Sopenharmony_ci};
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_cistruct alb_bond_info {
12762306a36Sopenharmony_ci	struct tlb_client_info	*tx_hashtbl; /* Dynamically allocated */
12862306a36Sopenharmony_ci	u32			unbalanced_load;
12962306a36Sopenharmony_ci	atomic_t		tx_rebalance_counter;
13062306a36Sopenharmony_ci	int			lp_counter;
13162306a36Sopenharmony_ci	/* -------- rlb parameters -------- */
13262306a36Sopenharmony_ci	int rlb_enabled;
13362306a36Sopenharmony_ci	struct rlb_client_info	*rx_hashtbl;	/* Receive hash table */
13462306a36Sopenharmony_ci	u32			rx_hashtbl_used_head;
13562306a36Sopenharmony_ci	u8			rx_ntt;	/* flag - need to transmit
13662306a36Sopenharmony_ci					 * to all rx clients
13762306a36Sopenharmony_ci					 */
13862306a36Sopenharmony_ci	struct slave		*rx_slave;/* last slave to xmit from */
13962306a36Sopenharmony_ci	u8			primary_is_promisc;	   /* boolean */
14062306a36Sopenharmony_ci	u32			rlb_promisc_timeout_counter;/* counts primary
14162306a36Sopenharmony_ci							     * promiscuity time
14262306a36Sopenharmony_ci							     */
14362306a36Sopenharmony_ci	u32			rlb_update_delay_counter;
14462306a36Sopenharmony_ci	u32			rlb_update_retry_counter;/* counter of retries
14562306a36Sopenharmony_ci							  * of client update
14662306a36Sopenharmony_ci							  */
14762306a36Sopenharmony_ci	u8			rlb_rebalance;	/* flag - indicates that the
14862306a36Sopenharmony_ci						 * rx traffic should be
14962306a36Sopenharmony_ci						 * rebalanced
15062306a36Sopenharmony_ci						 */
15162306a36Sopenharmony_ci};
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ciint bond_alb_initialize(struct bonding *bond, int rlb_enabled);
15462306a36Sopenharmony_civoid bond_alb_deinitialize(struct bonding *bond);
15562306a36Sopenharmony_ciint bond_alb_init_slave(struct bonding *bond, struct slave *slave);
15662306a36Sopenharmony_civoid bond_alb_deinit_slave(struct bonding *bond, struct slave *slave);
15762306a36Sopenharmony_civoid bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link);
15862306a36Sopenharmony_civoid bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave);
15962306a36Sopenharmony_cinetdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
16062306a36Sopenharmony_cinetdev_tx_t bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
16162306a36Sopenharmony_cistruct slave *bond_xmit_alb_slave_get(struct bonding *bond,
16262306a36Sopenharmony_ci				      struct sk_buff *skb);
16362306a36Sopenharmony_cistruct slave *bond_xmit_tlb_slave_get(struct bonding *bond,
16462306a36Sopenharmony_ci				      struct sk_buff *skb);
16562306a36Sopenharmony_civoid bond_alb_monitor(struct work_struct *);
16662306a36Sopenharmony_ciint bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
16762306a36Sopenharmony_civoid bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id);
16862306a36Sopenharmony_ci#endif /* _NET_BOND_ALB_H */
16962306a36Sopenharmony_ci
170