]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: add serdes patch for 10G_QXGMII
authorDamien Dejean <dam.dejean@gmail.com>
Wed, 27 Aug 2025 14:05:39 +0000 (16:05 +0200)
committerRobert Marko <robimarko@gmail.com>
Sun, 26 Oct 2025 10:24:51 +0000 (11:24 +0100)
Adds the serdes patch sequence [1] and configuration [2] for the
PHY_INTERFACE_MODE_10G_QXGMII mode (aka USXGMII_QX in Realtek sources).
It is required by devices with light bootloaders (ie not u-boot) that
does not initialize the hardware before booting the kernel.

[1] https://github.com/ddejean/dms-1250-oss-release/blob/main/sdk/sdk_rtk_switch/rtk-sdk/src/dal/longan/dal_longan_construct.c#L1075
[2] https://github.com/ddejean/dms-1250-oss-release/blob/main/sdk/sdk_rtk_switch/rtk-sdk/src/dal/longan/dal_longan_construct.c#L1315

Signed-off-by: Damien Dejean <dam.dejean@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/20472
Signed-off-by: Robert Marko <robimarko@gmail.com>
target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c

index 7fe9db36dc7c87b223816ba58aa094609b25b418..9392dd0a38ad1e50ac1a9e08904a5176a85c7021 100644 (file)
@@ -2565,6 +2565,70 @@ static const sds_config rtsds_930x_cfg_10g_2500bx_odd[] =
        {0x2D, 0x13, 0x3C87}, {0x2D, 0x14, 0x1808},
 };
 
+sds_config rtsds_930x_cfg_usxgmii_qx_even[] =
+{
+    {0x06, 0x00, 0x0000}, {0x06, 0x0D, 0x0F00}, {0x06, 0x0E, 0x055A}, {0x06, 0x1D, 0x0600},
+    {0x07, 0x10, 0x6003}, {0x06, 0x13, 0x68C1}, {0x06, 0x14, 0xF021}, {0x07, 0x06, 0x1401},
+    {0x21, 0x03, 0x8206}, {0x21, 0x05, 0x40B0}, {0x21, 0x06, 0x0010}, {0x21, 0x07, 0xF09F},
+    {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009}, {0x21, 0x0E, 0x0000}, {0x21, 0x0F, 0x0008},
+    {0x2E, 0x00, 0xA668}, {0x2E, 0x01, 0x2088}, {0x2E, 0x02, 0xD020}, {0x2E, 0x06, 0xC000},
+    {0x2E, 0x0B, 0x1892}, {0x2E, 0x0F, 0xFFDF}, {0x2E, 0x11, 0x8280}, {0x2E, 0x12, 0x0484},
+    {0x2E, 0x13, 0x027F}, {0x2E, 0x14, 0x1311}, {0x2E, 0x17, 0xA100}, {0x2E, 0x1A, 0x0001},
+    {0x2E, 0x1C, 0x0400}, {0x2F, 0x01, 0x0300}, {0x2F, 0x02, 0x1017}, {0x2F, 0x03, 0xFFDF},
+    {0x2F, 0x05, 0x7F7C}, {0x2F, 0x07, 0x8104}, {0x2F, 0x08, 0x0001}, {0x2F, 0x09, 0xFFD4},
+    {0x2F, 0x0A, 0x7C2F}, {0x2F, 0x0E, 0x003F}, {0x2F, 0x0F, 0x0121}, {0x2F, 0x10, 0x0020},
+    {0x2F, 0x11, 0x8840},
+    {0x2B, 0x13, 0x0050}, {0x2B, 0x18, 0x8E88}, {0x2B, 0x19, 0x4902}, {0x2B, 0x1D, 0x2501},
+    {0x2D, 0x13, 0x0050}, {0x2D, 0x18, 0x8E88}, {0x2D, 0x19, 0x4902}, {0x2D, 0x1D, 0x2641},
+    {0x2F, 0x13, 0x0050}, {0x2F, 0x18, 0x8E88}, {0x2F, 0x19, 0x4902}, {0x2F, 0x1D, 0x66E1},
+    /* enable IEEE 802.3az EEE */
+    {0x06, 0x03, 0xc45c},
+};
+
+sds_config rtsds_930x_cfg_usxgmii_qx_odd[] =
+{
+    {0x06, 0x00, 0x0000}, {0x06, 0x0D, 0x0F00}, {0x06, 0x0E, 0x055A}, {0x06, 0x1D, 0x0600},
+    {0x07, 0x10, 0x6003}, {0x06, 0x13, 0x68C1}, {0x06, 0x14, 0xF021}, {0x07, 0x06, 0x1401},
+    {0x21, 0x03, 0x8206}, {0x21, 0x05, 0x40B0}, {0x21, 0x06, 0x0010}, {0x21, 0x07, 0xF09F},
+    {0x21, 0x0A, 0x0003}, {0x21, 0x0B, 0x0005}, {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009},
+    {0x21, 0x0E, 0x0000}, {0x21, 0x0F, 0x0008},
+    {0x2E, 0x00, 0xA668}, {0x2E, 0x02, 0xD020}, {0x2E, 0x06, 0xC000}, {0x2E, 0x0B, 0x1892},
+    {0x2E, 0x0F, 0xFFDF}, {0x2E, 0x11, 0x8280}, {0x2E, 0x12, 0x0484}, {0x2E, 0x13, 0x027F},
+    {0x2E, 0x14, 0x1311}, {0x2E, 0x17, 0xA100}, {0x2E, 0x1A, 0x0001}, {0x2E, 0x1C, 0x0400},
+    {0x2F, 0x00, 0x820F}, {0x2F, 0x01, 0x0300}, {0x2F, 0x02, 0x1017}, {0x2F, 0x03, 0xFFDF},
+    {0x2F, 0x05, 0x7F7C}, {0x2F, 0x07, 0x8104}, {0x2F, 0x08, 0x0001}, {0x2F, 0x09, 0xFFD4},
+    {0x2F, 0x0A, 0x7C2F}, {0x2F, 0x0E, 0x003F}, {0x2F, 0x0F, 0x0121}, {0x2F, 0x10, 0x0020},
+    {0x2F, 0x11, 0x8840},
+    {0x2B, 0x13, 0x3D87}, {0x2B, 0x14, 0x3108},
+    {0x2D, 0x13, 0x3C87}, {0x2D, 0x14, 0x1808},
+    /* enable IEEE 802.3az EEE */
+    {0x06, 0x03, 0xc45c},
+};
+
+static void rtsds_930x_usxgmii_config(int sds, int nway_en, u32 opcode, u32 am_period, u32 all_am_markers, u32 an_table, u32 sync_bit)
+{
+       rtl9300_sds_field_w(sds, 0x7, 0x11, 0, 0, nway_en);
+       rtl9300_sds_field_w(sds, 0x7, 0x11, 1, 1, nway_en);
+       rtl9300_sds_field_w(sds, 0x7, 0x11, 2, 2, nway_en);
+       rtl9300_sds_field_w(sds, 0x7, 0x11, 3, 3, nway_en);
+       rtl9300_sds_field_w(sds, 0x6, 0x12, 15, 0, am_period);
+       rtl9300_sds_field_w(sds, 0x6, 0x13, 7,  0, all_am_markers);
+       rtl9300_sds_field_w(sds, 0x6, 0x13, 15, 8, all_am_markers);
+       rtl9300_sds_field_w(sds, 0x6, 0x14, 7,  0, all_am_markers);
+       rtl9300_sds_field_w(sds, 0x6, 0x14, 15, 8, all_am_markers);
+       rtl9300_sds_field_w(sds, 0x6, 0x15, 7,  0, all_am_markers);
+       rtl9300_sds_field_w(sds, 0x6, 0x15, 15, 8, all_am_markers);
+       rtl9300_sds_field_w(sds, 0x6, 0x16, 7,  0, all_am_markers);
+       rtl9300_sds_field_w(sds, 0x6, 0x16, 15, 8, all_am_markers);
+       rtl9300_sds_field_w(sds, 0x6, 0x17, 7,  0, all_am_markers);
+       rtl9300_sds_field_w(sds, 0x6, 0x17, 15, 8, all_am_markers);
+       rtl9300_sds_field_w(sds, 0x6, 0x18, 7,  0, all_am_markers);
+       rtl9300_sds_field_w(sds, 0x6, 0x18, 15, 8, all_am_markers);
+       rtl9300_sds_field_w(sds, 0x7, 0x10, 7, 0, opcode);
+       rtl9300_sds_field_w(sds, 0x6, 0xe, 10, 10, an_table);
+       rtl9300_sds_field_w(sds, 0x6, 0x1d, 11, 10, sync_bit);
+}
+
 static void rtsds_930x_patch_serdes(int sds, phy_interface_t mode)
 {
        const bool even_sds = ((sds & 1) == 0);
@@ -2594,6 +2658,16 @@ static void rtsds_930x_patch_serdes(int sds, phy_interface_t mode)
                }
                break;
 
+       case PHY_INTERFACE_MODE_10G_QXGMII:
+               if (even_sds) {
+                       config = rtsds_930x_cfg_usxgmii_qx_even;
+                       count = ARRAY_SIZE(rtsds_930x_cfg_usxgmii_qx_even);
+               } else {
+                       config = rtsds_930x_cfg_usxgmii_qx_odd;
+                       count = ARRAY_SIZE(rtsds_930x_cfg_usxgmii_qx_odd);
+               }
+               break;
+
        default:
                pr_warn("%s: unsupported mode %s on serdes %d\n", __func__, phy_modes(mode), sds);
                return;
@@ -2604,6 +2678,11 @@ static void rtsds_930x_patch_serdes(int sds, phy_interface_t mode)
                                          config[i].reg,
                                          config[i].data);
        }
+
+       if (mode == PHY_INTERFACE_MODE_10G_QXGMII) {
+               /* Default configuration */
+               rtsds_930x_usxgmii_config(sds, 1, 0xaa, 0x5078, 0, 1, 0x1);
+       }
 }
 
 int rtl9300_sds_cmu_band_get(int sds)