net: phylink: add rxc_always_on flag to phylink_pcs
Some MAC drivers (e.g. stmmac) require a continuous receive clock signal to be generated by a PCS that is handled by a standalone PCS driver. Such a PCS driver does not have access to a PHY device, thus cannot check the PHY_F_RXC_ALWAYS_ON flag. They cannot check max_requires_rxc in the phylink config either, since it is a private member. Therefore, a new flag is needed to signal to the PCS that it should keep the RX clock signal up at all times. Co-developed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Signed-off-by: Romain Gantois <romain.gantois@bootlin.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Link: https://lore.kernel.org/r/20240326-rxc_bugfix-v6-2-24a74e5c761f@bootlin.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
21d9ba5bc5
commit
dceb393a0a
@ -1042,6 +1042,21 @@ static void phylink_pcs_poll_start(struct phylink *pl)
|
||||
mod_timer(&pl->link_poll, jiffies + HZ);
|
||||
}
|
||||
|
||||
int phylink_pcs_pre_init(struct phylink *pl, struct phylink_pcs *pcs)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* Signal to PCS driver that MAC requires RX clock for init */
|
||||
if (pl->config->mac_requires_rxc)
|
||||
pcs->rxc_always_on = true;
|
||||
|
||||
if (pcs->ops->pcs_pre_init)
|
||||
ret = pcs->ops->pcs_pre_init(pcs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phylink_pcs_pre_init);
|
||||
|
||||
static void phylink_mac_config(struct phylink *pl,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
|
@ -396,6 +396,10 @@ struct phylink_pcs_ops;
|
||||
* @phylink: pointer to &struct phylink_config
|
||||
* @neg_mode: provide PCS neg mode via "mode" argument
|
||||
* @poll: poll the PCS for link changes
|
||||
* @rxc_always_on: The MAC driver requires the reference clock
|
||||
* to always be on. Standalone PCS drivers which
|
||||
* do not have access to a PHY device can check
|
||||
* this instead of PHY_F_RXC_ALWAYS_ON.
|
||||
*
|
||||
* This structure is designed to be embedded within the PCS private data,
|
||||
* and will be passed between phylink and the PCS.
|
||||
@ -408,6 +412,7 @@ struct phylink_pcs {
|
||||
struct phylink *phylink;
|
||||
bool neg_mode;
|
||||
bool poll;
|
||||
bool rxc_always_on;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -422,6 +427,8 @@ struct phylink_pcs {
|
||||
* @pcs_an_restart: restart 802.3z BaseX autonegotiation.
|
||||
* @pcs_link_up: program the PCS for the resolved link configuration
|
||||
* (where necessary).
|
||||
* @pcs_pre_init: configure PCS components necessary for MAC hardware
|
||||
* initialization e.g. RX clock for stmmac.
|
||||
*/
|
||||
struct phylink_pcs_ops {
|
||||
int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
|
||||
@ -441,6 +448,7 @@ struct phylink_pcs_ops {
|
||||
void (*pcs_an_restart)(struct phylink_pcs *pcs);
|
||||
void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int neg_mode,
|
||||
phy_interface_t interface, int speed, int duplex);
|
||||
int (*pcs_pre_init)(struct phylink_pcs *pcs);
|
||||
};
|
||||
|
||||
#if 0 /* For kernel-doc purposes only. */
|
||||
@ -546,6 +554,34 @@ void pcs_an_restart(struct phylink_pcs *pcs);
|
||||
*/
|
||||
void pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
|
||||
phy_interface_t interface, int speed, int duplex);
|
||||
|
||||
/**
|
||||
* pcs_pre_init() - Configure PCS components necessary for MAC initialization
|
||||
* @pcs: a pointer to a &struct phylink_pcs.
|
||||
*
|
||||
* This function can be called by MAC drivers through the
|
||||
* phylink_pcs_pre_init() wrapper, before their hardware is initialized. It
|
||||
* should not be called after the link is brought up, as reconfiguring the PCS
|
||||
* at this point could break the link.
|
||||
*
|
||||
* Some MAC devices require specific hardware initialization to be performed by
|
||||
* their associated PCS device before they can properly initialize their own
|
||||
* hardware. An example of this is the initialization of stmmac controllers,
|
||||
* which requires an active REF_CLK signal to be provided by the PHY/PCS.
|
||||
*
|
||||
* By calling phylink_pcs_pre_init(), MAC drivers can ensure that the PCS is
|
||||
* setup in a way that allows for successful hardware initialization.
|
||||
*
|
||||
* The specific configuration performed by pcs_pre_init() is dependent on the
|
||||
* model of PCS and the requirements of the MAC device attached to it. PCS
|
||||
* driver authors should consider whether their target device is to be used in
|
||||
* conjunction with a MAC device whose driver calls phylink_pcs_pre_init(). MAC
|
||||
* driver authors should document their requirements for the PCS
|
||||
* pre-initialization.
|
||||
*
|
||||
*/
|
||||
int pcs_pre_init(struct phylink_pcs *pcs);
|
||||
|
||||
#endif
|
||||
|
||||
struct phylink *phylink_create(struct phylink_config *,
|
||||
@ -565,6 +601,8 @@ void phylink_disconnect_phy(struct phylink *);
|
||||
void phylink_mac_change(struct phylink *, bool up);
|
||||
void phylink_pcs_change(struct phylink_pcs *, bool up);
|
||||
|
||||
int phylink_pcs_pre_init(struct phylink *pl, struct phylink_pcs *pcs);
|
||||
|
||||
void phylink_start(struct phylink *);
|
||||
void phylink_stop(struct phylink *);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user