0081-kernel-add-at803x-fix-for-sgmii-mode.patch 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. From: Felix Fietkau <nbd@openwrt.org>
  2. Date: Sun, 27 Nov 2016 22:49:27 +0100
  3. Subject: kernel: add at803x fix for sgmii mode
  4. Some (possibly broken) bootloaders incorreclty initialize at8033
  5. phy. This patch enables sgmii autonegotiation mode.
  6. Signed-off-by: Roman Yeryomin <roman@advem.lv>
  7. Origin: backport, https://git.lede-project.org/?p=source.git;a=commit;h=e14d2aee0ab91c43d0bb14baf84cc9b997185870
  8. Bug-gluon: https://github.com/freifunk-gluon/gluon/issues/911
  9. diff --git a/target/linux/ar71xx/patches-3.18/735-net-phy-at803x-fix-at8033-sgmii-mode.patch b/target/linux/ar71xx/patches-3.18/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
  10. new file mode 100644
  11. index 0000000..4a8f532
  12. --- /dev/null
  13. +++ b/target/linux/ar71xx/patches-3.18/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
  14. @@ -0,0 +1,96 @@
  15. +--- a/drivers/net/phy/at803x.c
  16. ++++ b/drivers/net/phy/at803x.c
  17. +@@ -36,6 +36,9 @@
  18. + #define AT803X_INER 0x0012
  19. + #define AT803X_INER_INIT 0xec00
  20. + #define AT803X_INSR 0x0013
  21. ++#define AT803X_REG_CHIP_CONFIG 0x1f
  22. ++#define AT803X_BT_BX_REG_SEL 0x8000
  23. ++#define AT803X_SGMII_ANEG_EN 0x1000
  24. +
  25. + #define AT803X_PCS_SMART_EEE_CTRL3 0x805D
  26. + #define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_MASK 0x3
  27. +@@ -49,9 +52,10 @@
  28. + #define AT803X_DEBUG_SYSTEM_MODE_CTRL 0x05
  29. + #define AT803X_DEBUG_RGMII_TX_CLK_DLY BIT(8)
  30. +
  31. +-#define ATH8030_PHY_ID 0x004dd076
  32. +-#define ATH8031_PHY_ID 0x004dd074
  33. +-#define ATH8035_PHY_ID 0x004dd072
  34. ++#define AT803X_PHY_ID_MASK 0xffffffef
  35. ++#define ATH8030_PHY_ID 0x004dd076
  36. ++#define ATH8031_PHY_ID 0x004dd074
  37. ++#define ATH8035_PHY_ID 0x004dd072
  38. +
  39. + MODULE_DESCRIPTION("Atheros 803x PHY driver");
  40. + MODULE_AUTHOR("Matus Ujhelyi");
  41. +@@ -267,6 +271,27 @@ static int at803x_config_init(struct phy
  42. + {
  43. + struct at803x_platform_data *pdata;
  44. + int ret;
  45. ++ u32 v;
  46. ++
  47. ++ if (phydev->drv->phy_id == ATH8031_PHY_ID &&
  48. ++ phydev->interface == PHY_INTERFACE_MODE_SGMII)
  49. ++ {
  50. ++ v = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
  51. ++ /* select SGMII/fiber page */
  52. ++ ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG,
  53. ++ v & ~AT803X_BT_BX_REG_SEL);
  54. ++ if (ret)
  55. ++ return ret;
  56. ++ /* enable SGMII autonegotiation */
  57. ++ ret = phy_write(phydev, MII_BMCR, AT803X_SGMII_ANEG_EN);
  58. ++ if (ret)
  59. ++ return ret;
  60. ++ /* select copper page */
  61. ++ ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG,
  62. ++ v | AT803X_BT_BX_REG_SEL);
  63. ++ if (ret)
  64. ++ return ret;
  65. ++ }
  66. +
  67. + ret = genphy_config_init(phydev);
  68. + if (ret < 0)
  69. +@@ -393,7 +418,7 @@ static struct phy_driver at803x_driver[]
  70. + /* ATHEROS 8035 */
  71. + .phy_id = ATH8035_PHY_ID,
  72. + .name = "Atheros 8035 ethernet",
  73. +- .phy_id_mask = 0xffffffef,
  74. ++ .phy_id_mask = AT803X_PHY_ID_MASK,
  75. + .probe = at803x_probe,
  76. + .config_init = at803x_config_init,
  77. + .link_change_notify = at803x_link_change_notify,
  78. +@@ -412,7 +437,7 @@ static struct phy_driver at803x_driver[]
  79. + /* ATHEROS 8030 */
  80. + .phy_id = ATH8030_PHY_ID,
  81. + .name = "Atheros 8030 ethernet",
  82. +- .phy_id_mask = 0xffffffef,
  83. ++ .phy_id_mask = AT803X_PHY_ID_MASK,
  84. + .probe = at803x_probe,
  85. + .config_init = at803x_config_init,
  86. + .link_change_notify = at803x_link_change_notify,
  87. +@@ -430,8 +455,8 @@ static struct phy_driver at803x_driver[]
  88. + }, {
  89. + /* ATHEROS 8031 */
  90. + .phy_id = ATH8031_PHY_ID,
  91. +- .name = "Atheros 8031 ethernet",
  92. +- .phy_id_mask = 0xffffffef,
  93. ++ .name = "Atheros 8031/8033 ethernet",
  94. ++ .phy_id_mask = AT803X_PHY_ID_MASK,
  95. + .probe = at803x_probe,
  96. + .config_init = at803x_config_init,
  97. + .link_change_notify = at803x_link_change_notify,
  98. +@@ -465,9 +490,9 @@ module_init(atheros_init);
  99. + module_exit(atheros_exit);
  100. +
  101. + static struct mdio_device_id __maybe_unused atheros_tbl[] = {
  102. +- { ATH8030_PHY_ID, 0xffffffef },
  103. +- { ATH8031_PHY_ID, 0xffffffef },
  104. +- { ATH8035_PHY_ID, 0xffffffef },
  105. ++ { ATH8030_PHY_ID, AT803X_PHY_ID_MASK },
  106. ++ { ATH8031_PHY_ID, AT803X_PHY_ID_MASK },
  107. ++ { ATH8035_PHY_ID, AT803X_PHY_ID_MASK },
  108. + { }
  109. + };
  110. +