]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[realtek] Work around hardware bug on RTL8211B 397/head
authorMichael Brown <mcb30@ipxe.org>
Tue, 22 Jun 2021 13:48:10 +0000 (14:48 +0100)
committerMichael Brown <mcb30@ipxe.org>
Thu, 24 Jun 2021 11:36:46 +0000 (12:36 +0100)
The RTL8211B seems to have a bug that prevents the link from coming up
unless the MII_MMD_DATA register is cleared.

The Linux kernel driver applies this workaround (in rtl8211b_resume())
only to the specific RTL8211B PHY model, along with a matching
workaround to set bit 9 of MII_MMD_DATA when suspending the PHY.
Since we have no need to ever suspend the PHY, and since writing a
zero ought to be harmless, we just clear the register unconditionally.

Debugged-by: Nikolay Pertsev <nikolay.p@cos.flag.org>
Tested-by: Nikolay Pertsev <nikolay.p@cos.flag.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/net/realtek.c
src/include/mii.h

index 0af3416d50ebf2ef1d347b32b4761975625ce2ea..a43efb68bb02595722f1cc006ab55a1296f707d0 100644 (file)
@@ -420,6 +420,16 @@ static int realtek_phy_reset ( struct realtek_nic *rtl ) {
                 */
        }
 
+       /* Some cards (e.g. RTL8211B) have a hardware errata that
+        * requires the MII_MMD_DATA register to be cleared before the
+        * link will come up.
+        */
+       if ( ( rc = mii_write ( &rtl->mii, MII_MMD_DATA, 0 ) ) != 0 ) {
+               /* Ignore failures, since the register may not be
+                * present on all PHYs.
+                */
+       }
+
        /* Restart autonegotiation */
        if ( ( rc = mii_restart ( &rtl->mii ) ) != 0 ) {
                DBGC ( rtl, "REALTEK %p could not restart MII: %s\n",
index e2afef854aae98e134732cf7f87e4b3e6f31cec6..515ba224d2b1232072464624aca793fb5fbd7a0a 100644 (file)
@@ -23,6 +23,8 @@ FILE_LICENCE ( GPL2_ONLY );
 #define MII_EXPANSION      0x06        /* Expansion register          */
 #define MII_CTRL1000       0x09        /* 1000BASE-T control          */
 #define MII_STAT1000       0x0a        /* 1000BASE-T status           */
+#define MII_MMD_CTRL       0x0d        /* MMD Access Control Register */
+#define MII_MMD_DATA       0x0e        /* MMD Access Data Register    */
 #define MII_ESTATUS        0x0f        /* Extended Status */
 #define MII_DCOUNTER       0x12        /* Disconnect counter          */
 #define MII_FCSCOUNTER     0x13        /* False carrier counter       */