Skip to content

Commit 91a208f

Browse files
Russell Kingdavem330
authored andcommitted
net: phylink: propagate resolved link config via mac_link_up()
Propagate the resolved link parameters via the mac_link_up() call for MACs that do not automatically track their PCS state. We propagate the link parameters via function arguments so that inappropriate members of struct phylink_link_state can't be accessed, and creating a new structure just for this adds needless complexity to the API. Tested-by: Andre Przywara <[email protected]> Tested-by: Alexandre Belloni <[email protected]> Tested-by: Vladimir Oltean <[email protected]> Signed-off-by: Russell King <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2e6af0f commit 91a208f

File tree

11 files changed

+105
-41
lines changed

11 files changed

+105
-41
lines changed

Documentation/networking/sfp-phylink.rst

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,13 @@ phylib to the sfp/phylink support. Please send patches to improve
7474
this documentation.
7575

7676
1. Optionally split the network driver's phylib update function into
77-
three parts dealing with link-down, link-up and reconfiguring the
78-
MAC settings. This can be done as a separate preparation commit.
77+
two parts dealing with link-down and link-up. This can be done as
78+
a separate preparation commit.
7979

80-
An example of this preparation can be found in git commit fc548b991fb0.
80+
An older example of this preparation can be found in git commit
81+
fc548b991fb0, although this was splitting into three parts; the
82+
link-up part now includes configuring the MAC for the link settings.
83+
Please see :c:func:`mac_link_up` for more information on this.
8184

8285
2. Replace::
8386

@@ -207,6 +210,14 @@ this documentation.
207210
using. This is particularly important for in-band negotiation
208211
methods such as 1000base-X and SGMII.
209212

213+
The :c:func:`mac_link_up` method is used to inform the MAC that the
214+
link has come up. The call includes the negotiation mode and interface
215+
for reference only. The finalised link parameters are also supplied
216+
(speed, duplex and flow control/pause enablement settings) which
217+
should be used to configure the MAC when the MAC and PCS are not
218+
tightly integrated, or when the settings are not coming from in-band
219+
negotiation.
220+
210221
The :c:func:`mac_config` method is used to update the MAC with the
211222
requested state, and must avoid unnecessarily taking the link down
212223
when making changes to the MAC configuration. This means the

drivers/net/ethernet/cadence/macb_main.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,8 +626,11 @@ static void macb_mac_link_down(struct phylink_config *config, unsigned int mode,
626626
netif_tx_stop_all_queues(ndev);
627627
}
628628

629-
static void macb_mac_link_up(struct phylink_config *config, unsigned int mode,
630-
phy_interface_t interface, struct phy_device *phy)
629+
static void macb_mac_link_up(struct phylink_config *config,
630+
struct phy_device *phy,
631+
unsigned int mode, phy_interface_t interface,
632+
int speed, int duplex,
633+
bool tx_pause, bool rx_pause)
631634
{
632635
struct net_device *ndev = to_net_dev(config->dev);
633636
struct macb *bp = netdev_priv(ndev);

drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,11 @@ static void dpaa2_mac_config(struct phylink_config *config, unsigned int mode,
154154
netdev_err(mac->net_dev, "dpmac_set_link_state() = %d\n", err);
155155
}
156156

157-
static void dpaa2_mac_link_up(struct phylink_config *config, unsigned int mode,
158-
phy_interface_t interface, struct phy_device *phy)
157+
static void dpaa2_mac_link_up(struct phylink_config *config,
158+
struct phy_device *phy,
159+
unsigned int mode, phy_interface_t interface,
160+
int speed, int duplex,
161+
bool tx_pause, bool rx_pause)
159162
{
160163
struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
161164
struct dpmac_link_state *dpmac_state = &mac->state;

drivers/net/ethernet/marvell/mvneta.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3965,9 +3965,11 @@ static void mvneta_mac_link_down(struct phylink_config *config,
39653965
mvneta_set_eee(pp, false);
39663966
}
39673967

3968-
static void mvneta_mac_link_up(struct phylink_config *config, unsigned int mode,
3969-
phy_interface_t interface,
3970-
struct phy_device *phy)
3968+
static void mvneta_mac_link_up(struct phylink_config *config,
3969+
struct phy_device *phy,
3970+
unsigned int mode, phy_interface_t interface,
3971+
int speed, int duplex,
3972+
bool tx_pause, bool rx_pause)
39713973
{
39723974
struct net_device *ndev = to_net_dev(config->dev);
39733975
struct mvneta_port *pp = netdev_priv(ndev);

drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,11 @@ static struct {
5858
*/
5959
static void mvpp2_mac_config(struct phylink_config *config, unsigned int mode,
6060
const struct phylink_link_state *state);
61-
static void mvpp2_mac_link_up(struct phylink_config *config, unsigned int mode,
62-
phy_interface_t interface, struct phy_device *phy);
61+
static void mvpp2_mac_link_up(struct phylink_config *config,
62+
struct phy_device *phy,
63+
unsigned int mode, phy_interface_t interface,
64+
int speed, int duplex,
65+
bool tx_pause, bool rx_pause);
6366

6467
/* Queue modes */
6568
#define MVPP2_QDIST_SINGLE_MODE 0
@@ -3473,8 +3476,9 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
34733476
.interface = port->phy_interface,
34743477
};
34753478
mvpp2_mac_config(&port->phylink_config, MLO_AN_INBAND, &state);
3476-
mvpp2_mac_link_up(&port->phylink_config, MLO_AN_INBAND,
3477-
port->phy_interface, NULL);
3479+
mvpp2_mac_link_up(&port->phylink_config, NULL,
3480+
MLO_AN_INBAND, port->phy_interface,
3481+
SPEED_UNKNOWN, DUPLEX_UNKNOWN, false, false);
34783482
}
34793483

34803484
netif_tx_start_all_queues(port->dev);
@@ -5141,8 +5145,11 @@ static void mvpp2_mac_config(struct phylink_config *config, unsigned int mode,
51415145
mvpp2_port_enable(port);
51425146
}
51435147

5144-
static void mvpp2_mac_link_up(struct phylink_config *config, unsigned int mode,
5145-
phy_interface_t interface, struct phy_device *phy)
5148+
static void mvpp2_mac_link_up(struct phylink_config *config,
5149+
struct phy_device *phy,
5150+
unsigned int mode, phy_interface_t interface,
5151+
int speed, int duplex,
5152+
bool tx_pause, bool rx_pause)
51465153
{
51475154
struct net_device *dev = to_net_dev(config->dev);
51485155
struct mvpp2_port *port = netdev_priv(dev);

drivers/net/ethernet/mediatek/mtk_eth_soc.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,9 +412,10 @@ static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
412412
mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
413413
}
414414

415-
static void mtk_mac_link_up(struct phylink_config *config, unsigned int mode,
416-
phy_interface_t interface,
417-
struct phy_device *phy)
415+
static void mtk_mac_link_up(struct phylink_config *config,
416+
struct phy_device *phy,
417+
unsigned int mode, phy_interface_t interface,
418+
int speed, int duplex, bool tx_pause, bool rx_pause)
418419
{
419420
struct mtk_mac *mac = container_of(config, struct mtk_mac,
420421
phylink_config);

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,8 +950,10 @@ static void stmmac_mac_link_down(struct phylink_config *config,
950950
}
951951

952952
static void stmmac_mac_link_up(struct phylink_config *config,
953+
struct phy_device *phy,
953954
unsigned int mode, phy_interface_t interface,
954-
struct phy_device *phy)
955+
int speed, int duplex,
956+
bool tx_pause, bool rx_pause)
955957
{
956958
struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
957959

drivers/net/ethernet/xilinx/xilinx_axienet_main.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,9 +1486,10 @@ static void axienet_mac_link_down(struct phylink_config *config,
14861486
}
14871487

14881488
static void axienet_mac_link_up(struct phylink_config *config,
1489-
unsigned int mode,
1490-
phy_interface_t interface,
1491-
struct phy_device *phy)
1489+
struct phy_device *phy,
1490+
unsigned int mode, phy_interface_t interface,
1491+
int speed, int duplex,
1492+
bool tx_pause, bool rx_pause)
14921493
{
14931494
/* nothing meaningful to do */
14941495
}

drivers/net/phy/phylink.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,11 @@ static void phylink_mac_link_up(struct phylink *pl,
480480
struct net_device *ndev = pl->netdev;
481481

482482
pl->cur_interface = link_state.interface;
483-
pl->ops->mac_link_up(pl->config, pl->cur_link_an_mode,
484-
pl->cur_interface, pl->phydev);
483+
pl->ops->mac_link_up(pl->config, pl->phydev,
484+
pl->cur_link_an_mode, pl->cur_interface,
485+
link_state.speed, link_state.duplex,
486+
!!(link_state.pause & MLO_PAUSE_TX),
487+
!!(link_state.pause & MLO_PAUSE_RX));
485488

486489
if (ndev)
487490
netif_carrier_on(ndev);
@@ -547,6 +550,8 @@ static void phylink_resolve(struct work_struct *w)
547550
link_state.pause = pl->phy_state.pause;
548551
phylink_apply_manual_flow(pl, &link_state);
549552
phylink_mac_config(pl, &link_state);
553+
} else {
554+
phylink_apply_manual_flow(pl, &link_state);
550555
}
551556
break;
552557
}

include/linux/phylink.h

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,10 @@ struct phylink_mac_ops {
9191
void (*mac_an_restart)(struct phylink_config *config);
9292
void (*mac_link_down)(struct phylink_config *config, unsigned int mode,
9393
phy_interface_t interface);
94-
void (*mac_link_up)(struct phylink_config *config, unsigned int mode,
95-
phy_interface_t interface,
96-
struct phy_device *phy);
94+
void (*mac_link_up)(struct phylink_config *config,
95+
struct phy_device *phy, unsigned int mode,
96+
phy_interface_t interface, int speed, int duplex,
97+
bool tx_pause, bool rx_pause);
9798
};
9899

99100
#if 0 /* For kernel-doc purposes only. */
@@ -152,6 +153,9 @@ void mac_pcs_get_state(struct phylink_config *config,
152153
* guaranteed to be correct, and so any mac_config() implementation must
153154
* never reference these fields.
154155
*
156+
* (this requires a rewrite - please refer to mac_link_up() for situations
157+
* where the PCS and MAC are not tightly integrated.)
158+
*
155159
* In all negotiation modes, as defined by @mode, @state->pause indicates the
156160
* pause settings which should be applied as follows. If %MLO_PAUSE_AN is not
157161
* set, %MLO_PAUSE_TX and %MLO_PAUSE_RX indicate whether the MAC should send
@@ -162,12 +166,20 @@ void mac_pcs_get_state(struct phylink_config *config,
162166
* The action performed depends on the currently selected mode:
163167
*
164168
* %MLO_AN_FIXED, %MLO_AN_PHY:
165-
* Configure the specified @state->speed and @state->duplex over a link
166-
* specified by @state->interface. @state->advertising may be used, but
167-
* is not required. Pause modes as above. Other members of @state must
168-
* be ignored.
169+
* Configure for non-inband negotiation mode, where the link settings
170+
* are completely communicated via mac_link_up(). The physical link
171+
* protocol from the MAC is specified by @state->interface.
172+
*
173+
* @state->advertising may be used, but is not required.
174+
*
175+
* Older drivers (prior to the mac_link_up() change) may use @state->speed,
176+
* @state->duplex and @state->pause to configure the MAC, but this is
177+
* deprecated; such drivers should be converted to use mac_link_up().
169178
*
170-
* Valid state members: interface, speed, duplex, pause, advertising.
179+
* Other members of @state must be ignored.
180+
*
181+
* Valid state members: interface, advertising.
182+
* Deprecated state members: speed, duplex, pause.
171183
*
172184
* %MLO_AN_INBAND:
173185
* place the link in an inband negotiation mode (such as 802.3z
@@ -228,19 +240,34 @@ void mac_link_down(struct phylink_config *config, unsigned int mode,
228240
/**
229241
* mac_link_up() - allow the link to come up
230242
* @config: a pointer to a &struct phylink_config.
243+
* @phy: any attached phy
231244
* @mode: link autonegotiation mode
232245
* @interface: link &typedef phy_interface_t mode
233-
* @phy: any attached phy
246+
* @speed: link speed
247+
* @duplex: link duplex
248+
* @tx_pause: link transmit pause enablement status
249+
* @rx_pause: link receive pause enablement status
234250
*
235-
* If @mode is not an in-band negotiation mode (as defined by
236-
* phylink_autoneg_inband()), allow the link to come up. If @phy
237-
* is non-%NULL, configure Energy Efficient Ethernet by calling
251+
* Configure the MAC for an established link.
252+
*
253+
* @speed, @duplex, @tx_pause and @rx_pause indicate the finalised link
254+
* settings, and should be used to configure the MAC block appropriately
255+
* where these settings are not automatically conveyed from the PCS block,
256+
* or if in-band negotiation (as defined by phylink_autoneg_inband(@mode))
257+
* is disabled.
258+
*
259+
* Note that when 802.3z in-band negotiation is in use, it is possible
260+
* that the user wishes to override the pause settings, and this should
261+
* be allowed when considering the implementation of this method.
262+
*
263+
* If in-band negotiation mode is disabled, allow the link to come up. If
264+
* @phy is non-%NULL, configure Energy Efficient Ethernet by calling
238265
* phy_init_eee() and perform appropriate MAC configuration for EEE.
239266
* Interface type selection must be done in mac_config().
240267
*/
241-
void mac_link_up(struct phylink_config *config, unsigned int mode,
242-
phy_interface_t interface,
243-
struct phy_device *phy);
268+
void mac_link_up(struct phylink_config *config, struct phy_device *phy,
269+
unsigned int mode, phy_interface_t interface,
270+
int speed, int duplex, bool tx_pause, bool rx_pause);
244271
#endif
245272

246273
struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *,

0 commit comments

Comments
 (0)