lantiq: clarify VG3503J name
[oweals/openwrt.git] / target / linux / mvebu / patches-4.9 / 416-phylink-add-hooks-for-SFP-support.patch
1 From: Russell King <rmk+kernel@arm.linux.org.uk>
2 Date: Thu, 24 Sep 2015 11:01:13 +0100
3 Subject: [PATCH] phylink: add hooks for SFP support
4
5 Add support to phylink for SFP, which needs to control and configure
6 the ethernet MAC link state.  Specifically, SFP needs to:
7
8 1. set the negotiation mode between SGMII and 1000base-X
9 2. attach and detach the module PHY
10 3. prevent the link coming up when errors are reported
11
12 In the absence of a PHY, we also need to set the ethtool port type
13 according to the module plugged in.
14
15 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
16 Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
17
18 - rework phylink_set_link_*(), combining into a single function.
19 ---
20
21 --- a/drivers/net/phy/phylink.c
22 +++ b/drivers/net/phy/phylink.c
23 @@ -11,6 +11,7 @@
24  #include <linux/ethtool.h>
25  #include <linux/export.h>
26  #include <linux/gpio/consumer.h>
27 +#include <linux/list.h>
28  #include <linux/netdevice.h>
29  #include <linux/of.h>
30  #include <linux/of_mdio.h>
31 @@ -29,11 +30,16 @@
32         (ADVERTISED_TP | ADVERTISED_MII | ADVERTISED_FIBRE | \
33          ADVERTISED_BNC | ADVERTISED_AUI | ADVERTISED_Backplane)
34  
35 +static LIST_HEAD(phylinks);
36 +static DEFINE_MUTEX(phylink_mutex);
37 +
38  enum {
39         PHYLINK_DISABLE_STOPPED,
40 +       PHYLINK_DISABLE_LINK,
41  };
42  
43  struct phylink {
44 +       struct list_head node;
45         struct net_device *netdev;
46         const struct phylink_mac_ops *ops;
47         struct mutex config_mutex;
48 @@ -375,12 +381,20 @@ struct phylink *phylink_create(struct ne
49         phylink_init_advert(pl, pl->link_an_mode, pl->supported,
50                             pl->link_config.advertising);
51  
52 +       mutex_lock(&phylink_mutex);
53 +       list_add_tail(&pl->node, &phylinks);
54 +       mutex_unlock(&phylink_mutex);
55 +
56         return pl;
57  }
58  EXPORT_SYMBOL_GPL(phylink_create);
59  
60  void phylink_destroy(struct phylink *pl)
61  {
62 +       mutex_lock(&phylink_mutex);
63 +       list_del(&pl->node);
64 +       mutex_unlock(&phylink_mutex);
65 +
66         cancel_work_sync(&pl->resolve);
67         kfree(pl);
68  }
69 @@ -900,4 +914,93 @@ int phylink_mii_ioctl(struct phylink *pl
70  }
71  EXPORT_SYMBOL_GPL(phylink_mii_ioctl);
72  
73 +
74 +
75 +void phylink_disable(struct phylink *pl)
76 +{
77 +       set_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state);
78 +       flush_work(&pl->resolve);
79 +
80 +       netif_carrier_off(pl->netdev);
81 +}
82 +EXPORT_SYMBOL_GPL(phylink_disable);
83 +
84 +void phylink_enable(struct phylink *pl)
85 +{
86 +       clear_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state);
87 +       phylink_run_resolve(pl);
88 +}
89 +EXPORT_SYMBOL_GPL(phylink_enable);
90 +
91 +int phylink_set_link(struct phylink *pl, unsigned int mode, u8 port,
92 +                    const unsigned long *support)
93 +{
94 +       __ETHTOOL_DECLARE_LINK_MODE_MASK(mask);
95 +       int ret = 0;
96 +
97 +       netdev_dbg(pl->netdev, "requesting link mode %s with support %*pb\n",
98 +                  phylink_an_mode_str(mode),
99 +                  __ETHTOOL_LINK_MODE_MASK_NBITS, support);
100 +
101 +       if (mode == MLO_AN_FIXED)
102 +               return -EINVAL;
103 +
104 +       linkmode_copy(mask, support);
105 +
106 +       /* Ignore errors if we're expecting a PHY to attach later */
107 +       ret = phylink_validate_support(pl, mode, mask);
108 +       if (ret && mode != MLO_AN_PHY)
109 +               return ret;
110 +
111 +       mutex_lock(&pl->config_mutex);
112 +       if (mode == MLO_AN_8023Z && pl->phydev) {
113 +               ret = -EINVAL;
114 +       } else {
115 +               bool changed = !bitmap_equal(pl->supported, mask,
116 +                                            __ETHTOOL_LINK_MODE_MASK_NBITS);
117 +               if (changed) {
118 +                       linkmode_copy(pl->supported, mask);
119 +
120 +                       phylink_init_advert(pl, mode, mask,
121 +                                           pl->link_config.advertising);
122 +               }
123 +
124 +               if (pl->link_an_mode != mode) {
125 +                       pl->link_an_mode = mode;
126 +
127 +                       changed = true;
128 +
129 +                       netdev_info(pl->netdev, "switched to %s link mode\n",
130 +                                   phylink_an_mode_str(mode));
131 +               }
132 +
133 +               pl->link_port = port;
134 +
135 +               if (changed && !test_bit(PHYLINK_DISABLE_STOPPED,
136 +                                        &pl->phylink_disable_state))
137 +                       phylink_mac_config(pl, &pl->link_config);
138 +       }
139 +       mutex_unlock(&pl->config_mutex);
140 +
141 +       return ret;
142 +}
143 +EXPORT_SYMBOL_GPL(phylink_set_link);
144 +
145 +struct phylink *phylink_lookup_by_netdev(struct net_device *ndev)
146 +{
147 +       struct phylink *pl, *found = NULL;
148 +
149 +       mutex_lock(&phylink_mutex);
150 +       list_for_each_entry(pl, &phylinks, node)
151 +               if (pl->netdev == ndev) {
152 +                       found = pl;
153 +                       break;
154 +               }
155 +
156 +       mutex_unlock(&phylink_mutex);
157 +
158 +       return found;
159 +}
160 +EXPORT_SYMBOL_GPL(phylink_lookup_by_netdev);
161 +
162  MODULE_LICENSE("GPL");
163 --- a/include/linux/phylink.h
164 +++ b/include/linux/phylink.h
165 @@ -88,6 +88,12 @@ int phylink_ethtool_ksettings_set(struct
166                                   const struct ethtool_link_ksettings *);
167  int phylink_mii_ioctl(struct phylink *, struct ifreq *, int);
168  
169 +int phylink_set_link(struct phylink *pl, unsigned int mode, u8 port,
170 +                    const unsigned long *support);
171 +void phylink_disable(struct phylink *pl);
172 +void phylink_enable(struct phylink *pl);
173 +struct phylink *phylink_lookup_by_netdev(struct net_device *ndev);
174 +
175  #define phylink_zero(bm) \
176         bitmap_zero(bm, __ETHTOOL_LINK_MODE_MASK_NBITS)
177  #define __phylink_do_bit(op, bm, mode) \