1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (C) 2018-2021, Intel Corporation. */
3 
4 #ifndef _ICE_LAG_H_
5 #define _ICE_LAG_H_
6 
7 #include <linux/netdevice.h>
8 
9 /* LAG roles for netdev */
10 enum ice_lag_role {
11 	ICE_LAG_NONE,
12 	ICE_LAG_PRIMARY,
13 	ICE_LAG_BACKUP,
14 	ICE_LAG_UNSET
15 };
16 
17 struct ice_pf;
18 
19 /* LAG info struct */
20 struct ice_lag {
21 	struct ice_pf *pf; /* backlink to PF struct */
22 	struct net_device *netdev; /* this PF's netdev */
23 	struct net_device *peer_netdev;
24 	struct net_device *upper_netdev; /* upper bonding netdev */
25 	struct notifier_block notif_block;
26 	u8 bonded:1; /* currently bonded */
27 	u8 primary:1; /* this is primary */
28 	u8 handler:1; /* did we register a rx_netdev_handler */
29 	/* each thing blocking bonding will increment this value by one.
30 	 * If this value is zero, then bonding is allowed.
31 	 */
32 	u16 dis_lag;
33 	u8 role;
34 };
35 
36 int ice_init_lag(struct ice_pf *pf);
37 void ice_deinit_lag(struct ice_pf *pf);
38 rx_handler_result_t ice_lag_nop_handler(struct sk_buff **pskb);
39 
40 /**
41  * ice_disable_lag - increment LAG disable count
42  * @lag: LAG struct
43  */
ice_disable_lag(struct ice_lag * lag)44 static inline void ice_disable_lag(struct ice_lag *lag)
45 {
46 	/* If LAG this PF is not already disabled, disable it */
47 	rtnl_lock();
48 	if (!netdev_is_rx_handler_busy(lag->netdev)) {
49 		if (!netdev_rx_handler_register(lag->netdev,
50 						ice_lag_nop_handler,
51 						NULL))
52 			lag->handler = true;
53 	}
54 	rtnl_unlock();
55 	lag->dis_lag++;
56 }
57 
58 /**
59  * ice_enable_lag - decrement disable count for a PF
60  * @lag: LAG struct
61  *
62  * Decrement the disable counter for a port, and if that count reaches
63  * zero, then remove the no-op Rx handler from that netdev
64  */
ice_enable_lag(struct ice_lag * lag)65 static inline void ice_enable_lag(struct ice_lag *lag)
66 {
67 	if (lag->dis_lag)
68 		lag->dis_lag--;
69 	if (!lag->dis_lag && lag->handler) {
70 		rtnl_lock();
71 		netdev_rx_handler_unregister(lag->netdev);
72 		rtnl_unlock();
73 		lag->handler = false;
74 	}
75 }
76 
77 /**
78  * ice_is_lag_dis - is LAG disabled
79  * @lag: LAG struct
80  *
81  * Return true if bonding is disabled
82  */
ice_is_lag_dis(struct ice_lag * lag)83 static inline bool ice_is_lag_dis(struct ice_lag *lag)
84 {
85 	return !!(lag->dis_lag);
86 }
87 #endif /* _ICE_LAG_H_ */
88