Skip to content

Commit

Permalink
Merge branch 'net-fec-fix-temporary-rmii-clock-reset-on-link-up'
Browse files Browse the repository at this point in the history
Laurent Badel says:

====================
net: fec: Fix temporary RMII clock reset on link up

v2: fixed a compilation warning

The FEC drivers performs a "hardware reset" of the MAC module when the
link is reported to be up. This causes a short glitch in the RMII clock
due to the hardware reset clearing the receive control register which
controls the MII mode. It seems that some link partners do not tolerate
this glitch, and invalidate the link, which leads to a never-ending loop
of negotiation-link up-link down events.

This was observed with the iMX28 Soc and LAN8720/LAN8742 PHYs, with two
Intel adapters I218-LM and X722-DA2 as link partners, though a number of
other link partners do not seem to mind the clock glitch. Changing the
hardware reset to a software reset (clearing bit 1 of the ECR register)
cured the issue.

Attempts to optimize fec_restart() in order to minimize the duration of
the glitch were unsuccessful. Furthermore manually producing the glitch by
setting MII mode and then back to RMII in two consecutive instructions,
resulting in a clock glitch <10us in duration, was enough to cause the
partner to invalidate the link. This strongly suggests that the root cause
of the link being dropped is indeed the change in clock frequency.

In an effort to minimize changes to driver, the patch proposes to use
soft reset only for tested SoCs (iMX28) and only if the link is up. This
preserves hardware reset in other situations, which might be required for
proper setup of the MAC.
====================

Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
kuba-moo committed Jan 27, 2021
2 parents b491e6a + c730ab4 commit 2bd2974
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 2 deletions.
5 changes: 5 additions & 0 deletions drivers/net/ethernet/freescale/fec.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,11 @@ struct bufdesc_ex {
*/
#define FEC_QUIRK_CLEAR_SETUP_MII (1 << 17)

/* Some link partners do not tolerate the momentary reset of the REF_CLK
* frequency when the RNCTL register is cleared by hardware reset.
*/
#define FEC_QUIRK_NO_HARD_RESET (1 << 18)

struct bufdesc_prop {
int qid;
/* Address of Rx and Tx buffers */
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/ethernet/freescale/fec_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ static const struct fec_devinfo fec_imx27_info = {
static const struct fec_devinfo fec_imx28_info = {
.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME |
FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC |
FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII,
FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII |
FEC_QUIRK_NO_HARD_RESET,
};

static const struct fec_devinfo fec_imx6q_info = {
Expand Down Expand Up @@ -953,7 +954,8 @@ fec_restart(struct net_device *ndev)
* For i.MX6SX SOC, enet use AXI bus, we use disable MAC
* instead of reset MAC itself.
*/
if (fep->quirks & FEC_QUIRK_HAS_AVB) {
if (fep->quirks & FEC_QUIRK_HAS_AVB ||
((fep->quirks & FEC_QUIRK_NO_HARD_RESET) && fep->link)) {
writel(0, fep->hwp + FEC_ECNTRL);
} else {
writel(1, fep->hwp + FEC_ECNTRL);
Expand Down

0 comments on commit 2bd2974

Please sign in to comment.