Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

doc: add phylink documentation to the networking book

Add some phylink documentation to the networking book detailing how
to convert network drivers from phylib to phylink.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Russell King and committed by
David S. Miller
0a6c33e8 0e29ae03

+269
+1
Documentation/networking/index.rst
··· 31 31 failover 32 32 net_failover 33 33 phy 34 + sfp-phylink 34 35 alias 35 36 bridge 36 37 snmp_counter
+268
Documentation/networking/sfp-phylink.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + ======= 4 + phylink 5 + ======= 6 + 7 + Overview 8 + ======== 9 + 10 + phylink is a mechanism to support hot-pluggable networking modules 11 + without needing to re-initialise the adapter on hot-plug events. 12 + 13 + phylink supports conventional phylib-based setups, fixed link setups 14 + and SFP (Small Formfactor Pluggable) modules at present. 15 + 16 + Modes of operation 17 + ================== 18 + 19 + phylink has several modes of operation, which depend on the firmware 20 + settings. 21 + 22 + 1. PHY mode 23 + 24 + In PHY mode, we use phylib to read the current link settings from 25 + the PHY, and pass them to the MAC driver. We expect the MAC driver 26 + to configure exactly the modes that are specified without any 27 + negotiation being enabled on the link. 28 + 29 + 2. Fixed mode 30 + 31 + Fixed mode is the same as PHY mode as far as the MAC driver is 32 + concerned. 33 + 34 + 3. In-band mode 35 + 36 + In-band mode is used with 802.3z, SGMII and similar interface modes, 37 + and we are expecting to use and honor the in-band negotiation or 38 + control word sent across the serdes channel. 39 + 40 + By example, what this means is that: 41 + 42 + .. code-block:: none 43 + 44 + &eth { 45 + phy = <&phy>; 46 + phy-mode = "sgmii"; 47 + }; 48 + 49 + does not use in-band SGMII signalling. The PHY is expected to follow 50 + exactly the settings given to it in its :c:func:`mac_config` function. 51 + The link should be forced up or down appropriately in the 52 + :c:func:`mac_link_up` and :c:func:`mac_link_down` functions. 53 + 54 + .. code-block:: none 55 + 56 + &eth { 57 + managed = "in-band-status"; 58 + phy = <&phy>; 59 + phy-mode = "sgmii"; 60 + }; 61 + 62 + uses in-band mode, where results from the PHY's negotiation are passed 63 + to the MAC through the SGMII control word, and the MAC is expected to 64 + acknowledge the control word. The :c:func:`mac_link_up` and 65 + :c:func:`mac_link_down` functions must not force the MAC side link 66 + up and down. 67 + 68 + Rough guide to converting a network driver to sfp/phylink 69 + ========================================================= 70 + 71 + This guide briefly describes how to convert a network driver from 72 + phylib to the sfp/phylink support. Please send patches to improve 73 + this documentation. 74 + 75 + 1. Optionally split the network driver's phylib update function into 76 + three parts dealing with link-down, link-up and reconfiguring the 77 + MAC settings. This can be done as a separate preparation commit. 78 + 79 + An example of this preparation can be found in git commit fc548b991fb0. 80 + 81 + 2. Replace:: 82 + 83 + select FIXED_PHY 84 + select PHYLIB 85 + 86 + with:: 87 + 88 + select PHYLINK 89 + 90 + in the driver's Kconfig stanza. 91 + 92 + 3. Add:: 93 + 94 + #include <linux/phylink.h> 95 + 96 + to the driver's list of header files. 97 + 98 + 4. Add:: 99 + 100 + struct phylink *phylink; 101 + 102 + to the driver's private data structure. We shall refer to the 103 + driver's private data pointer as ``priv`` below, and the driver's 104 + private data structure as ``struct foo_priv``. 105 + 106 + 5. Replace the following functions: 107 + 108 + .. flat-table:: 109 + :header-rows: 1 110 + :widths: 1 1 111 + :stub-columns: 0 112 + 113 + * - Original function 114 + - Replacement function 115 + * - phy_start(phydev) 116 + - phylink_start(priv->phylink) 117 + * - phy_stop(phydev) 118 + - phylink_stop(priv->phylink) 119 + * - phy_mii_ioctl(phydev, ifr, cmd) 120 + - phylink_mii_ioctl(priv->phylink, ifr, cmd) 121 + * - phy_ethtool_get_wol(phydev, wol) 122 + - phylink_ethtool_get_wol(priv->phylink, wol) 123 + * - phy_ethtool_set_wol(phydev, wol) 124 + - phylink_ethtool_set_wol(priv->phylink, wol) 125 + * - phy_disconnect(phydev) 126 + - phylink_disconnect_phy(priv->phylink) 127 + 128 + Please note that some of these functions must be called under the 129 + rtnl lock, and will warn if not. This will normally be the case, 130 + except if these are called from the driver suspend/resume paths. 131 + 132 + 6. Add/replace ksettings get/set methods with: 133 + 134 + .. code-block:: c 135 + 136 + static int foo_ethtool_set_link_ksettings(struct net_device *dev, 137 + const struct ethtool_link_ksettings *cmd) 138 + { 139 + struct foo_priv *priv = netdev_priv(dev); 140 + 141 + return phylink_ethtool_ksettings_set(priv->phylink, cmd); 142 + } 143 + 144 + static int foo_ethtool_get_link_ksettings(struct net_device *dev, 145 + struct ethtool_link_ksettings *cmd) 146 + { 147 + struct foo_priv *priv = netdev_priv(dev); 148 + 149 + return phylink_ethtool_ksettings_get(priv->phylink, cmd); 150 + } 151 + 152 + 7. Replace the call to: 153 + 154 + phy_dev = of_phy_connect(dev, node, link_func, flags, phy_interface); 155 + 156 + and associated code with a call to: 157 + 158 + err = phylink_of_phy_connect(priv->phylink, node, flags); 159 + 160 + For the most part, ``flags`` can be zero; these flags are passed to 161 + the of_phy_attach() inside this function call if a PHY is specified 162 + in the DT node ``node``. 163 + 164 + ``node`` should be the DT node which contains the network phy property, 165 + fixed link properties, and will also contain the sfp property. 166 + 167 + The setup of fixed links should also be removed; these are handled 168 + internally by phylink. 169 + 170 + of_phy_connect() was also passed a function pointer for link updates. 171 + This function is replaced by a different form of MAC updates 172 + described below in (8). 173 + 174 + Manipulation of the PHY's supported/advertised happens within phylink 175 + based on the validate callback, see below in (8). 176 + 177 + Note that the driver no longer needs to store the ``phy_interface``, 178 + and also note that ``phy_interface`` becomes a dynamic property, 179 + just like the speed, duplex etc. settings. 180 + 181 + Finally, note that the MAC driver has no direct access to the PHY 182 + anymore; that is because in the phylink model, the PHY can be 183 + dynamic. 184 + 185 + 8. Add a :c:type:`struct phylink_mac_ops <phylink_mac_ops>` instance to 186 + the driver, which is a table of function pointers, and implement 187 + these functions. The old link update function for 188 + :c:func:`of_phy_connect` becomes three methods: :c:func:`mac_link_up`, 189 + :c:func:`mac_link_down`, and :c:func:`mac_config`. If step 1 was 190 + performed, then the functionality will have been split there. 191 + 192 + It is important that if in-band negotiation is used, 193 + :c:func:`mac_link_up` and :c:func:`mac_link_down` do not prevent the 194 + in-band negotiation from completing, since these functions are called 195 + when the in-band link state changes - otherwise the link will never 196 + come up. 197 + 198 + The :c:func:`validate` method should mask the supplied supported mask, 199 + and ``state->advertising`` with the supported ethtool link modes. 200 + These are the new ethtool link modes, so bitmask operations must be 201 + used. For an example, see drivers/net/ethernet/marvell/mvneta.c. 202 + 203 + The :c:func:`mac_link_state` method is used to read the link state 204 + from the MAC, and report back the settings that the MAC is currently 205 + using. This is particularly important for in-band negotiation 206 + methods such as 1000base-X and SGMII. 207 + 208 + The :c:func:`mac_config` method is used to update the MAC with the 209 + requested state, and must avoid unnecessarily taking the link down 210 + when making changes to the MAC configuration. This means the 211 + function should modify the state and only take the link down when 212 + absolutely necessary to change the MAC configuration. An example 213 + of how to do this can be found in :c:func:`mvneta_mac_config` in 214 + drivers/net/ethernet/marvell/mvneta.c. 215 + 216 + For further information on these methods, please see the inline 217 + documentation in :c:type:`struct phylink_mac_ops <phylink_mac_ops>`. 218 + 219 + 9. Remove calls to of_parse_phandle() for the PHY, 220 + of_phy_register_fixed_link() for fixed links etc. from the probe 221 + function, and replace with: 222 + 223 + .. code-block:: c 224 + 225 + struct phylink *phylink; 226 + 227 + phylink = phylink_create(dev, node, phy_mode, &phylink_ops); 228 + if (IS_ERR(phylink)) { 229 + err = PTR_ERR(phylink); 230 + fail probe; 231 + } 232 + 233 + priv->phylink = phylink; 234 + 235 + and arrange to destroy the phylink in the probe failure path as 236 + appropriate and the removal path too by calling: 237 + 238 + .. code-block:: c 239 + 240 + phylink_destroy(priv->phylink); 241 + 242 + 10. Arrange for MAC link state interrupts to be forwarded into 243 + phylink, via: 244 + 245 + .. code-block:: c 246 + 247 + phylink_mac_change(priv->phylink, link_is_up); 248 + 249 + where ``link_is_up`` is true if the link is currently up or false 250 + otherwise. 251 + 252 + 11. Verify that the driver does not call:: 253 + 254 + netif_carrier_on() 255 + netif_carrier_off() 256 + 257 + as these will interfere with phylink's tracking of the link state, 258 + and cause phylink to omit calls via the :c:func:`mac_link_up` and 259 + :c:func:`mac_link_down` methods. 260 + 261 + Network drivers should call phylink_stop() and phylink_start() via their 262 + suspend/resume paths, which ensures that the appropriate 263 + :c:type:`struct phylink_mac_ops <phylink_mac_ops>` methods are called 264 + as necessary. 265 + 266 + For information describing the SFP cage in DT, please see the binding 267 + documentation in the kernel source tree 268 + ``Documentation/devicetree/bindings/net/sff,sfp.txt``