summaryrefslogtreecommitdiff
path: root/include/linux/phylink.h
blob: 9543f847d05894b01243a0260a87f869e5c8d858 (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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#ifndef NETDEV_PCS_H
#define NETDEV_PCS_H

#include <linux/phy.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>

struct device_node;
struct ethtool_cmd;
struct net_device;

enum {
	MLO_PAUSE_NONE,
	MLO_PAUSE_ASYM = BIT(0),
	MLO_PAUSE_SYM = BIT(1),
	MLO_PAUSE_RX = BIT(2),
	MLO_PAUSE_TX = BIT(3),
	MLO_PAUSE_TXRX_MASK = MLO_PAUSE_TX | MLO_PAUSE_RX,
	MLO_PAUSE_AN = BIT(4),

	MLO_AN_PHY = 0,
	MLO_AN_FIXED,
	MLO_AN_SGMII,
	MLO_AN_8023Z,
};

struct phylink_link_state {
	__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
	__ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising);
	int speed;
	int duplex;
	int pause;
	unsigned int link:1;
	unsigned int an_enabled:1;
	unsigned int an_complete:1;
};

struct phylink_mac_ops {
	/**
	 * @validate_support:
	 *
	 * Validate and update the support mask provided by a PHY or
	 * module.  Unsupported link modes should be cleared by the
	 * MAC.
	 *
	 * Note: the PHY may be able to transform from one connection
	 * technology to another, so, eg, don't clear 1000base-X just
	 * because the MAC is unable to support it.  This is more about
	 * clearing unsupported speeds and duplex settings.
	 */
	void (*validate_support)(struct net_device *, unsigned int mode,
				 unsigned long *support);

	/**
	 * @validate_advert:
	 *
	 * Validate and update the advertisment mask, clearing bits that
	 * can not be advertised in the chosen mode or with each other.
	 */
	void (*validate_advert)(struct net_device *, unsigned int mode,
				const unsigned long *support,
				unsigned long *advert);

	/* Read the current link state from the hardware */
	int (*mac_link_state)(struct net_device *, struct phylink_link_state *);

	/* Configure the MAC */
	void (*mac_config)(struct net_device *, unsigned int mode,
			   const struct phylink_link_state *);
	void (*mac_an_restart)(struct net_device *, unsigned int mode);

	void (*mac_link_down)(struct net_device *, unsigned int mode);
	void (*mac_link_up)(struct net_device *, unsigned int mode);
};

struct phylink *phylink_create(struct net_device *, struct device_node *,
	phy_interface_t iface, const struct phylink_mac_ops *ops);
void phylink_destroy(struct phylink *);

int phylink_connect_phy(struct phylink *, struct phy_device *);
int phylink_of_phy_connect(struct phylink *, struct device_node *);
void phylink_disconnect_phy(struct phylink *);

void phylink_mac_change(struct phylink *, bool up);

void phylink_start(struct phylink *);
void phylink_stop(struct phylink *);

int phylink_ethtool_ksettings_get(struct phylink *,
				  struct ethtool_link_ksettings *);
int phylink_ethtool_ksettings_set(struct phylink *,
				  const struct ethtool_link_ksettings *);
int phylink_ethtool_nway_reset(struct phylink *);
void phylink_ethtool_get_pauseparam(struct phylink *,
				    struct ethtool_pauseparam *);
int phylink_ethtool_set_pauseparam(struct phylink *,
				   struct ethtool_pauseparam *);
int phylink_mii_ioctl(struct phylink *, struct ifreq *, int);

int phylink_set_link(struct phylink *pl, unsigned int mode, u8 port,
		     const unsigned long *support);
void phylink_disable(struct phylink *pl);
void phylink_enable(struct phylink *pl);
struct phylink *phylink_lookup_by_netdev(struct net_device *ndev);

#define phylink_zero(bm) \
	bitmap_zero(bm, __ETHTOOL_LINK_MODE_MASK_NBITS)
#define __phylink_do_bit(op, bm, mode) \
	op(ETHTOOL_LINK_MODE_ ## mode ## _BIT, bm)

#define phylink_set(bm, mode)	__phylink_do_bit(__set_bit, bm, mode)
#define phylink_clear(bm, mode)	__phylink_do_bit(__clear_bit, bm, mode)
#define phylink_test(bm, mode)	__phylink_do_bit(test_bit, bm, mode)

#endif