summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/ice/ice_lag.h
blob: c2e3688dd8fd5898b029c62215e3f13d4698de8f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2018-2021, Intel Corporation. */

#ifndef _ICE_LAG_H_
#define _ICE_LAG_H_

#include <linux/netdevice.h>

/* LAG roles for netdev */
enum ice_lag_role {
	ICE_LAG_NONE,
	ICE_LAG_PRIMARY,
	ICE_LAG_BACKUP,
	ICE_LAG_UNSET
};

struct ice_pf;

/* LAG info struct */
struct ice_lag {
	struct ice_pf *pf; /* backlink to PF struct */
	struct net_device *netdev; /* this PF's netdev */
	struct net_device *peer_netdev;
	struct net_device *upper_netdev; /* upper bonding netdev */
	struct notifier_block notif_block;
	u8 bonded:1; /* currently bonded */
	u8 master:1; /* this is a master */
	u8 handler:1; /* did we register a rx_netdev_handler */
	/* each thing blocking bonding will increment this value by one.
	 * If this value is zero, then bonding is allowed.
	 */
	u16 dis_lag;
	u8 role;
};

int ice_init_lag(struct ice_pf *pf);
void ice_deinit_lag(struct ice_pf *pf);
rx_handler_result_t ice_lag_nop_handler(struct sk_buff **pskb);

/**
 * ice_disable_lag - increment LAG disable count
 * @lag: LAG struct
 */
static inline void ice_disable_lag(struct ice_lag *lag)
{
	/* If LAG this PF is not already disabled, disable it */
	rtnl_lock();
	if (!netdev_is_rx_handler_busy(lag->netdev)) {
		if (!netdev_rx_handler_register(lag->netdev,
						ice_lag_nop_handler,
						NULL))
			lag->handler = true;
	}
	rtnl_unlock();
	lag->dis_lag++;
}

/**
 * ice_enable_lag - decrement disable count for a PF
 * @lag: LAG struct
 *
 * Decrement the disable counter for a port, and if that count reaches
 * zero, then remove the no-op Rx handler from that netdev
 */
static inline void ice_enable_lag(struct ice_lag *lag)
{
	if (lag->dis_lag)
		lag->dis_lag--;
	if (!lag->dis_lag && lag->handler) {
		rtnl_lock();
		netdev_rx_handler_unregister(lag->netdev);
		rtnl_unlock();
		lag->handler = false;
	}
}

/**
 * ice_is_lag_dis - is LAG disabled
 * @lag: LAG struct
 *
 * Return true if bonding is disabled
 */
static inline bool ice_is_lag_dis(struct ice_lag *lag)
{
	return !!(lag->dis_lag);
}
#endif /* _ICE_LAG_H_ */