summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2015-09-22 20:52:18 +0100
committerRussell King <rmk+kernel@armlinux.org.uk>2017-02-20 10:47:20 +0000
commitc8aa45c936a98312a44084c2e3d5a67fbb3ceeb0 (patch)
tree5074e6eed3bc833ea11fa366825ef39413747106 /include
parentec7dfa830b279806bf72424f57435b0202eb31ec (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
Diffstat (limited to 'include')
-rw-r--r--include/linux/phy.h2
-rw-r--r--include/linux/phylink.h127
2 files changed, 129 insertions, 0 deletions
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 0062c0545e5f..0a18488d075a 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -168,6 +168,7 @@ static inline const char *phy_modes(phy_interface_t interface)
#define MII_ADDR_C45 (1<<30)
struct device;
+struct phylink;
struct sk_buff;
/*
@@ -446,6 +447,7 @@ struct phy_device {
struct mutex lock;
+ struct phylink *phylink;
struct net_device *attached_dev;
u8 mdix;
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
new file mode 100644
index 000000000000..1096e24a2eb2
--- /dev/null
+++ b/include/linux/phylink.h
@@ -0,0 +1,127 @@
+#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_AN_PHY = 0, /* Conventional PHY */
+ MLO_AN_FIXED, /* Fixed-link mode */
+ MLO_AN_SGMII, /* Cisco SGMII protocol */
+ MLO_AN_8023Z, /* 1000base-X protocol */
+};
+
+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
+ * @ndev: net_device structure associated with MAC
+ * @mode: desired negotiation operating mode
+ * @support: pointer to the desired support mask
+ *
+ * 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 *ndev, unsigned int mode,
+ unsigned long *support);
+
+ /**
+ * validate_advert: validate and update the advertisment
+ * @ndev: net_device structure associated with the MAC
+ * @mode: desired negotiation operating mode
+ * @support: current support mask
+ * @advert: desired advertisment mask
+ *
+ * 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 *ndev, 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 */
+ /**
+ * mac_config: configure the MAC for the selected mode and state
+ * @ndev: net_device structure for the MAC
+ * @mode: one of MLO_AN_FIXED, MLO_AN_PHY, MLO_AN_8023Z, MLO_AN_SGMII
+ * @state: state structure
+ *
+ * The action performed depends on the currently selected mode:
+ *
+ * %MLO_AN_FIXED, %MLO_AN_PHY:
+ * set the specified speed, duplex, pause mode, and phy interface
+ * mode in the provided @state.
+ * %MLO_AN_8023Z:
+ * place the link in 1000base-X mode, advertising the parameters
+ * given in advertising in @state.
+ * %MLO_AN_SGMII:
+ * place the link in Cisco SGMII mode - there is no advertisment
+ * to make as the PHY communicates the speed and duplex to the
+ * MAC over the in-band control word. Configuration of the pause
+ * mode is as per MLO_AN_PHY since this is not included.
+ */
+ void (*mac_config)(struct net_device *ndev, unsigned int mode,
+ const struct phylink_link_state *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_mii_ioctl(struct phylink *, struct ifreq *, int);
+
+#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