aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2017-07-25 10:03:13 -0400
committerDavid S. Miller <davem@davemloft.net>2017-08-06 23:55:29 -0400
commit9525ae83959b60c6061fe2f2caabdc8f69a48bc6 (patch)
tree18e08c65534c554c758d2d73ee5422654b650f0c /include/linux
parent453d00defba502a48e3f9a218a519b233ff83d16 (diff)
phylink: add phylink infrastructure
The link between the ethernet MAC and its PHY has become more complex as the interface evolves. This is especially true with serdes links, where the part of the PHY is effectively integrated into the MAC. Serdes links can be connected to a variety of devices, including SFF modules soldered down onto the board with the MAC, a SFP cage with a hotpluggable SFP module which may contain a PHY or directly modulate the serdes signals onto optical media with or without a PHY, or even a classical PHY connection. Moreover, the negotiation information on serdes links comes in two varieties - SGMII mode, where the PHY provides its speed/duplex/flow control information to the MAC, and 1000base-X mode where both ends exchange their abilities and each resolve the link capabilities. This means we need a more flexible means to support these arrangements, particularly with the hotpluggable nature of SFP, where the PHY can be attached or detached after the network device has been brought up. Ethtool information can come from multiple sources: - we may have a PHY operating in either SGMII or 1000base-X mode, in which case we take ethtool/mii data directly from the PHY. - we may have a optical SFP module without a PHY, with the MAC operating in 1000base-X mode - the ethtool/mii data needs to come from the MAC. - we may have a copper SFP module with a PHY whic can't be accessed, which means we need to take ethtool/mii data from the MAC. Phylink aims to solve this by providing an intermediary between the MAC and PHY, providing a safe way for PHYs to be hotplugged, and allowing a SFP driver to reconfigure the serdes connection. Phylink also takes over support of fixed link connections, where the speed/duplex/flow control are fixed, but link status may be controlled by a GPIO signal. By avoiding the fixed-phy implementation, phylink can provide a faster response to link events: fixed-phy has to wait for phylib to operate its state machine, which can take several seconds. In comparison, phylink takes milliseconds. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> - remove sync status - rework supported and advertisment handling - add 1000base-x speed for fixed links - use functionality exported from phy-core, reworking __phylink_ethtool_ksettings_set for it Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/phy.h2
-rw-r--r--include/linux/phylink.h145
2 files changed, 147 insertions, 0 deletions
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 0a5e8e62c9e0..d78cd01ea513 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -182,6 +182,7 @@ static inline const char *phy_modes(phy_interface_t interface)
182#define MII_ADDR_C45 (1<<30) 182#define MII_ADDR_C45 (1<<30)
183 183
184struct device; 184struct device;
185struct phylink;
185struct sk_buff; 186struct sk_buff;
186 187
187/* 188/*
@@ -469,6 +470,7 @@ struct phy_device {
469 470
470 struct mutex lock; 471 struct mutex lock;
471 472
473 struct phylink *phylink;
472 struct net_device *attached_dev; 474 struct net_device *attached_dev;
473 475
474 u8 mdix; 476 u8 mdix;
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
new file mode 100644
index 000000000000..76f054f39684
--- /dev/null
+++ b/include/linux/phylink.h
@@ -0,0 +1,145 @@
1#ifndef NETDEV_PCS_H
2#define NETDEV_PCS_H
3
4#include <linux/phy.h>
5#include <linux/spinlock.h>
6#include <linux/workqueue.h>
7
8struct device_node;
9struct ethtool_cmd;
10struct net_device;
11
12enum {
13 MLO_PAUSE_NONE,
14 MLO_PAUSE_ASYM = BIT(0),
15 MLO_PAUSE_SYM = BIT(1),
16 MLO_PAUSE_RX = BIT(2),
17 MLO_PAUSE_TX = BIT(3),
18 MLO_PAUSE_TXRX_MASK = MLO_PAUSE_TX | MLO_PAUSE_RX,
19 MLO_PAUSE_AN = BIT(4),
20
21 MLO_AN_PHY = 0, /* Conventional PHY */
22 MLO_AN_FIXED, /* Fixed-link mode */
23 MLO_AN_SGMII, /* Cisco SGMII protocol */
24 MLO_AN_8023Z, /* 1000base-X protocol */
25};
26
27static inline bool phylink_autoneg_inband(unsigned int mode)
28{
29 return mode == MLO_AN_SGMII || mode == MLO_AN_8023Z;
30}
31
32struct phylink_link_state {
33 __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
34 __ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising);
35 phy_interface_t interface; /* PHY_INTERFACE_xxx */
36 int speed;
37 int duplex;
38 int pause;
39 unsigned int link:1;
40 unsigned int an_enabled:1;
41 unsigned int an_complete:1;
42};
43
44struct phylink_mac_ops {
45 /**
46 * validate: validate and update the link configuration
47 * @ndev: net_device structure associated with MAC
48 * @config: configuration to validate
49 *
50 * Update the %config->supported and %config->advertised masks
51 * clearing bits that can not be supported.
52 *
53 * Note: the PHY may be able to transform from one connection
54 * technology to another, so, eg, don't clear 1000BaseX just
55 * because the MAC is unable to support it. This is more about
56 * clearing unsupported speeds and duplex settings.
57 *
58 * If the %config->interface mode is %PHY_INTERFACE_MODE_1000BASEX
59 * or %PHY_INTERFACE_MODE_2500BASEX, select the appropriate mode
60 * based on %config->advertised and/or %config->speed.
61 */
62 void (*validate)(struct net_device *ndev, unsigned long *supported,
63 struct phylink_link_state *state);
64
65 /* Read the current link state from the hardware */
66 int (*mac_link_state)(struct net_device *, struct phylink_link_state *);
67
68 /* Configure the MAC */
69 /**
70 * mac_config: configure the MAC for the selected mode and state
71 * @ndev: net_device structure for the MAC
72 * @mode: one of MLO_AN_FIXED, MLO_AN_PHY, MLO_AN_8023Z, MLO_AN_SGMII
73 * @state: state structure
74 *
75 * The action performed depends on the currently selected mode:
76 *
77 * %MLO_AN_FIXED, %MLO_AN_PHY:
78 * set the specified speed, duplex, pause mode, and phy interface
79 * mode in the provided @state.
80 * %MLO_AN_8023Z:
81 * place the link in 1000base-X mode, advertising the parameters
82 * given in advertising in @state.
83 * %MLO_AN_SGMII:
84 * place the link in Cisco SGMII mode - there is no advertisment
85 * to make as the PHY communicates the speed and duplex to the
86 * MAC over the in-band control word. Configuration of the pause
87 * mode is as per MLO_AN_PHY since this is not included.
88 */
89 void (*mac_config)(struct net_device *ndev, unsigned int mode,
90 const struct phylink_link_state *state);
91
92 /**
93 * mac_an_restart: restart 802.3z BaseX autonegotiation
94 * @ndev: net_device structure for the MAC
95 */
96 void (*mac_an_restart)(struct net_device *ndev);
97
98 void (*mac_link_down)(struct net_device *, unsigned int mode);
99 void (*mac_link_up)(struct net_device *, unsigned int mode,
100 struct phy_device *);
101};
102
103struct phylink *phylink_create(struct net_device *, struct device_node *,
104 phy_interface_t iface, const struct phylink_mac_ops *ops);
105void phylink_destroy(struct phylink *);
106
107int phylink_connect_phy(struct phylink *, struct phy_device *);
108int phylink_of_phy_connect(struct phylink *, struct device_node *);
109void phylink_disconnect_phy(struct phylink *);
110
111void phylink_mac_change(struct phylink *, bool up);
112
113void phylink_start(struct phylink *);
114void phylink_stop(struct phylink *);
115
116void phylink_ethtool_get_wol(struct phylink *, struct ethtool_wolinfo *);
117int phylink_ethtool_set_wol(struct phylink *, struct ethtool_wolinfo *);
118
119int phylink_ethtool_ksettings_get(struct phylink *,
120 struct ethtool_link_ksettings *);
121int phylink_ethtool_ksettings_set(struct phylink *,
122 const struct ethtool_link_ksettings *);
123int phylink_ethtool_nway_reset(struct phylink *);
124void phylink_ethtool_get_pauseparam(struct phylink *,
125 struct ethtool_pauseparam *);
126int phylink_ethtool_set_pauseparam(struct phylink *,
127 struct ethtool_pauseparam *);
128int phylink_init_eee(struct phylink *, bool);
129int phylink_get_eee_err(struct phylink *);
130int phylink_ethtool_get_eee(struct phylink *, struct ethtool_eee *);
131int phylink_ethtool_set_eee(struct phylink *, struct ethtool_eee *);
132int phylink_mii_ioctl(struct phylink *, struct ifreq *, int);
133
134#define phylink_zero(bm) \
135 bitmap_zero(bm, __ETHTOOL_LINK_MODE_MASK_NBITS)
136#define __phylink_do_bit(op, bm, mode) \
137 op(ETHTOOL_LINK_MODE_ ## mode ## _BIT, bm)
138
139#define phylink_set(bm, mode) __phylink_do_bit(__set_bit, bm, mode)
140#define phylink_clear(bm, mode) __phylink_do_bit(__clear_bit, bm, mode)
141#define phylink_test(bm, mode) __phylink_do_bit(test_bit, bm, mode)
142
143void phylink_set_port_modes(unsigned long *bits);
144
145#endif