075-v5.13-0004-net-dsa-bcm_sf2-add-function-finding-RGMII-register.patch 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. From 55cfeb396965c3906a84d09a9c487d065e37773b Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <[email protected]>
  3. Date: Thu, 18 Mar 2021 09:01:42 +0100
  4. Subject: [PATCH 1/2] net: dsa: bcm_sf2: add function finding RGMII register
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. Simple macro like REG_RGMII_CNTRL_P() is insufficient as:
  9. 1. It doesn't validate port argument
  10. 2. It doesn't support chipsets with non-lineral RGMII regs layout
  11. Missing port validation could result in getting register offset from out
  12. of array. Random memory -> random offset -> random reads/writes. It
  13. affected e.g. BCM4908 for REG_RGMII_CNTRL_P(7).
  14. Fixes: a78e86ed586d ("net: dsa: bcm_sf2: Prepare for different register layouts")
  15. Signed-off-by: Rafał Miłecki <[email protected]>
  16. Acked-by: Florian Fainelli <[email protected]>
  17. Signed-off-by: David S. Miller <[email protected]>
  18. ---
  19. drivers/net/dsa/bcm_sf2.c | 49 +++++++++++++++++++++++++++++-----
  20. drivers/net/dsa/bcm_sf2_regs.h | 2 --
  21. 2 files changed, 42 insertions(+), 9 deletions(-)
  22. --- a/drivers/net/dsa/bcm_sf2.c
  23. +++ b/drivers/net/dsa/bcm_sf2.c
  24. @@ -31,6 +31,31 @@
  25. #include "b53/b53_priv.h"
  26. #include "b53/b53_regs.h"
  27. +static u16 bcm_sf2_reg_rgmii_cntrl(struct bcm_sf2_priv *priv, int port)
  28. +{
  29. + switch (priv->type) {
  30. + case BCM4908_DEVICE_ID:
  31. + /* TODO */
  32. + break;
  33. + default:
  34. + switch (port) {
  35. + case 0:
  36. + return REG_RGMII_0_CNTRL;
  37. + case 1:
  38. + return REG_RGMII_1_CNTRL;
  39. + case 2:
  40. + return REG_RGMII_2_CNTRL;
  41. + default:
  42. + break;
  43. + }
  44. + }
  45. +
  46. + WARN_ONCE(1, "Unsupported port %d\n", port);
  47. +
  48. + /* RO fallback reg */
  49. + return REG_SWITCH_STATUS;
  50. +}
  51. +
  52. static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
  53. {
  54. struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
  55. @@ -586,6 +611,7 @@ static void bcm_sf2_sw_mac_config(struct
  56. {
  57. struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
  58. u32 id_mode_dis = 0, port_mode;
  59. + u32 reg_rgmii_ctrl;
  60. u32 reg, offset;
  61. if (port == core_readl(priv, CORE_IMP0_PRT_ID))
  62. @@ -615,10 +641,12 @@ static void bcm_sf2_sw_mac_config(struct
  63. goto force_link;
  64. }
  65. + reg_rgmii_ctrl = bcm_sf2_reg_rgmii_cntrl(priv, port);
  66. +
  67. /* Clear id_mode_dis bit, and the existing port mode, let
  68. * RGMII_MODE_EN bet set by mac_link_{up,down}
  69. */
  70. - reg = reg_readl(priv, REG_RGMII_CNTRL_P(port));
  71. + reg = reg_readl(priv, reg_rgmii_ctrl);
  72. reg &= ~ID_MODE_DIS;
  73. reg &= ~(PORT_MODE_MASK << PORT_MODE_SHIFT);
  74. reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN);
  75. @@ -633,7 +661,7 @@ static void bcm_sf2_sw_mac_config(struct
  76. reg |= RX_PAUSE_EN;
  77. }
  78. - reg_writel(priv, reg, REG_RGMII_CNTRL_P(port));
  79. + reg_writel(priv, reg, reg_rgmii_ctrl);
  80. force_link:
  81. /* Force link settings detected from the PHY */
  82. @@ -659,6 +687,7 @@ static void bcm_sf2_sw_mac_link_set(stru
  83. phy_interface_t interface, bool link)
  84. {
  85. struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
  86. + u32 reg_rgmii_ctrl;
  87. u32 reg;
  88. if (!phy_interface_mode_is_rgmii(interface) &&
  89. @@ -666,13 +695,15 @@ static void bcm_sf2_sw_mac_link_set(stru
  90. interface != PHY_INTERFACE_MODE_REVMII)
  91. return;
  92. + reg_rgmii_ctrl = bcm_sf2_reg_rgmii_cntrl(priv, port);
  93. +
  94. /* If the link is down, just disable the interface to conserve power */
  95. - reg = reg_readl(priv, REG_RGMII_CNTRL_P(port));
  96. + reg = reg_readl(priv, reg_rgmii_ctrl);
  97. if (link)
  98. reg |= RGMII_MODE_EN;
  99. else
  100. reg &= ~RGMII_MODE_EN;
  101. - reg_writel(priv, reg, REG_RGMII_CNTRL_P(port));
  102. + reg_writel(priv, reg, reg_rgmii_ctrl);
  103. }
  104. static void bcm_sf2_sw_mac_link_down(struct dsa_switch *ds, int port,
  105. --- a/drivers/net/dsa/bcm_sf2_regs.h
  106. +++ b/drivers/net/dsa/bcm_sf2_regs.h
  107. @@ -55,8 +55,6 @@ enum bcm_sf2_reg_offs {
  108. #define CROSSBAR_BCM4908_EXT_GPHY4 1
  109. #define CROSSBAR_BCM4908_EXT_RGMII 2
  110. -#define REG_RGMII_CNTRL_P(x) (REG_RGMII_0_CNTRL + (x))
  111. -
  112. /* Relative to REG_RGMII_CNTRL */
  113. #define RGMII_MODE_EN (1 << 0)
  114. #define ID_MODE_DIS (1 << 1)