lantiq: clarify VG3503J name
[oweals/openwrt.git] / target / linux / mvebu / patches-4.9 / 436-phylink-propagate-PHY-interface-mode-to-MAC-driver.patch
1 From: Russell King <rmk+kernel@armlinux.org.uk>
2 Date: Tue, 3 Jan 2017 18:34:17 +0000
3 Subject: [PATCH] phylink: propagate PHY interface mode to MAC driver
4
5 Some 10Gigabit PHYs automatically switch the mode of their host
6 interface depending on their negotiated speed.  We need to communicate
7 this to the MAC driver so the MAC can switch its host interface to
8 match the PHYs new operating mode.  Provide the current PHY interface
9 mode to the MAC driver.
10
11 Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
12 ---
13
14 --- a/drivers/net/phy/phylink.c
15 +++ b/drivers/net/phy/phylink.c
16 @@ -242,8 +242,9 @@ static void phylink_mac_config(struct ph
17                                const struct phylink_link_state *state)
18  {
19         netdev_dbg(pl->netdev,
20 -                  "%s: mode=%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n",
21 +                  "%s: mode=%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n",
22                    __func__, phylink_an_mode_str(pl->link_an_mode),
23 +                  phy_modes(state->interface),
24                    phy_speed_to_str(state->speed),
25                    phy_duplex_to_str(state->duplex),
26                    __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising,
27 @@ -264,6 +265,7 @@ static int phylink_get_mac_state(struct
28  
29         linkmode_copy(state->advertising, pl->link_config.advertising);
30         linkmode_zero(state->lp_advertising);
31 +       state->interface = pl->link_config.interface;
32         state->an_enabled = pl->link_config.an_enabled;
33         state->link = 1;
34  
35 @@ -344,19 +346,38 @@ static void phylink_resolve(struct work_
36                 case MLO_AN_PHY:
37                         link_state = pl->phy_state;
38                         phylink_resolve_flow(pl, &link_state);
39 +                       phylink_mac_config(pl, &link_state);
40                         break;
41  
42                 case MLO_AN_FIXED:
43                         phylink_get_fixed_state(pl, &link_state);
44 +                       phylink_mac_config(pl, &link_state);
45                         break;
46  
47                 case MLO_AN_SGMII:
48                         phylink_get_mac_state(pl, &link_state);
49                         if (pl->phydev) {
50 +                               bool changed = false;
51 +
52                                 link_state.link = link_state.link &&
53                                                   pl->phy_state.link;
54 -                               link_state.pause |= pl->phy_state.pause;
55 -                               phylink_resolve_flow(pl, &link_state);
56 +
57 +                               if (pl->phy_state.interface !=
58 +                                   link_state.interface) {
59 +                                       link_state.interface = pl->phy_state.interface;
60 +                                       changed = true;
61 +                               }
62 +
63 +                               /* Propagate the flow control from the PHY
64 +                                * to the MAC. Also propagate the interface
65 +                                * if changed.
66 +                                */
67 +                               if (pl->phy_state.link || changed) {
68 +                                       link_state.pause |= pl->phy_state.pause;
69 +                                       phylink_resolve_flow(pl, &link_state);
70 +
71 +                                       phylink_mac_config(pl, &link_state);
72 +                               }
73                         }
74                         break;
75  
76 @@ -372,13 +393,6 @@ static void phylink_resolve(struct work_
77                         pl->ops->mac_link_down(ndev, pl->link_an_mode);
78                         netdev_info(ndev, "Link is Down\n");
79                 } else {
80 -                       /* If we have a PHY, we need the MAC updated with
81 -                        * the current link parameters (eg, in SGMII mode,
82 -                        * with flow control status.)
83 -                        */
84 -                       if (pl->phydev)
85 -                               phylink_mac_config(pl, &link_state);
86 -
87                         pl->ops->mac_link_up(ndev, pl->link_an_mode,
88                                              pl->phydev);
89  
90 @@ -414,8 +428,10 @@ struct phylink *phylink_create(struct ne
91         mutex_init(&pl->config_mutex);
92         INIT_WORK(&pl->resolve, phylink_resolve);
93         pl->netdev = ndev;
94 +       pl->phy_state.interface = iface;
95         pl->link_interface = iface;
96         pl->link_port = PORT_MII;
97 +       pl->link_config.interface = iface;
98         pl->link_config.pause = MLO_PAUSE_AN;
99         pl->link_config.speed = SPEED_UNKNOWN;
100         pl->link_config.duplex = DUPLEX_UNKNOWN;
101 @@ -471,12 +487,14 @@ void phylink_phy_change(struct phy_devic
102                 pl->phy_state.pause |= MLO_PAUSE_SYM;
103         if (phydev->asym_pause)
104                 pl->phy_state.pause |= MLO_PAUSE_ASYM;
105 +       pl->phy_state.interface = phydev->interface;
106         pl->phy_state.link = up;
107         mutex_unlock(&pl->state_mutex);
108  
109         phylink_run_resolve(pl);
110  
111 -       netdev_dbg(pl->netdev, "phy link %s %s/%s\n", up ? "up" : "down",
112 +       netdev_dbg(pl->netdev, "phy link %s %s/%s/%s\n", up ? "up" : "down",
113 +                  phy_modes(phydev->interface),
114                    phy_speed_to_str(phydev->speed),
115                    phy_duplex_to_str(phydev->duplex));
116  }
117 --- a/include/linux/phylink.h
118 +++ b/include/linux/phylink.h
119 @@ -27,6 +27,7 @@ enum {
120  struct phylink_link_state {
121         __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
122         __ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising);
123 +       phy_interface_t interface;      /* PHY_INTERFACE_xxx */
124         int speed;
125         int duplex;
126         int pause;