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