blob: 00ea23005baa7b7988b3233ca6e4856e7af0327b [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From af30f8eaa8fe4ff1987280f716309711997bd979 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
3Date: Wed, 29 Dec 2021 18:16:42 +0100
4Subject: [PATCH] net: dsa: bcm_sf2: refactor LED regs access
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
91. Define more regs. Some switches (e.g. BCM4908) have up to 6 regs.
102. Add helper for handling non-lineral port <-> reg mappings.
113. Add support for 12 B LED reg blocks on BCM4908 (different layout)
12
13Complete support for LEDs setup will be implemented once Linux receives
14a proper design & implementation for "hardware" LEDs.
15
16Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
17Acked-by: Florian Fainelli <f.fainelli@gmail.com>
18Link: https://lore.kernel.org/r/20211229171642.22942-1-zajec5@gmail.com
19Signed-off-by: Jakub Kicinski <kuba@kernel.org>
20---
21 drivers/net/dsa/bcm_sf2.c | 54 ++++++++++++++++++++++++----
22 drivers/net/dsa/bcm_sf2.h | 10 ++++++
23 drivers/net/dsa/bcm_sf2_regs.h | 65 +++++++++++++++++++++++++++++++---
24 3 files changed, 119 insertions(+), 10 deletions(-)
25
26--- a/drivers/net/dsa/bcm_sf2.c
27+++ b/drivers/net/dsa/bcm_sf2.c
28@@ -31,6 +31,38 @@
29 #include "b53/b53_priv.h"
30 #include "b53/b53_regs.h"
31
32+static u16 bcm_sf2_reg_led_base(struct bcm_sf2_priv *priv, int port)
33+{
34+ switch (port) {
35+ case 0:
36+ return REG_LED_0_CNTRL;
37+ case 1:
38+ return REG_LED_1_CNTRL;
39+ case 2:
40+ return REG_LED_2_CNTRL;
41+ }
42+
43+ switch (priv->type) {
44+ case BCM4908_DEVICE_ID:
45+ switch (port) {
46+ case 3:
47+ return REG_LED_3_CNTRL;
48+ case 7:
49+ return REG_LED_4_CNTRL;
50+ default:
51+ break;
52+ }
53+ break;
54+ default:
55+ break;
56+ }
57+
58+ WARN_ONCE(1, "Unsupported port %d\n", port);
59+
60+ /* RO fallback reg */
61+ return REG_SWITCH_STATUS;
62+}
63+
64 static u16 bcm_sf2_reg_rgmii_cntrl(struct bcm_sf2_priv *priv, int port)
65 {
66 switch (priv->type) {
67@@ -141,9 +173,14 @@ static void bcm_sf2_gphy_enable_set(stru
68
69 /* Use PHY-driven LED signaling */
70 if (!enable) {
71- reg = reg_readl(priv, REG_LED_CNTRL(0));
72- reg |= SPDLNK_SRC_SEL;
73- reg_writel(priv, reg, REG_LED_CNTRL(0));
74+ u16 led_ctrl = bcm_sf2_reg_led_base(priv, 0);
75+
76+ if (priv->type == BCM7278_DEVICE_ID ||
77+ priv->type == BCM7445_DEVICE_ID) {
78+ reg = reg_led_readl(priv, led_ctrl, 0);
79+ reg |= LED_CNTRL_SPDLNK_SRC_SEL;
80+ reg_led_writel(priv, reg, led_ctrl, 0);
81+ }
82 }
83 }
84
85@@ -1113,9 +1150,14 @@ static const u16 bcm_sf2_4908_reg_offset
86 [REG_SPHY_CNTRL] = 0x24,
87 [REG_CROSSBAR] = 0xc8,
88 [REG_RGMII_11_CNTRL] = 0x014c,
89- [REG_LED_0_CNTRL] = 0x40,
90- [REG_LED_1_CNTRL] = 0x4c,
91- [REG_LED_2_CNTRL] = 0x58,
92+ [REG_LED_0_CNTRL] = 0x40,
93+ [REG_LED_1_CNTRL] = 0x4c,
94+ [REG_LED_2_CNTRL] = 0x58,
95+ [REG_LED_3_CNTRL] = 0x64,
96+ [REG_LED_4_CNTRL] = 0x88,
97+ [REG_LED_5_CNTRL] = 0xa0,
98+ [REG_LED_AGGREGATE_CTRL] = 0xb8,
99+
100 };
101
102 static const struct bcm_sf2_of_data bcm_sf2_4908_data = {
103--- a/drivers/net/dsa/bcm_sf2.h
104+++ b/drivers/net/dsa/bcm_sf2.h
105@@ -206,6 +206,16 @@ SF2_IO_MACRO(acb);
106 SWITCH_INTR_L2(0);
107 SWITCH_INTR_L2(1);
108
109+static inline u32 reg_led_readl(struct bcm_sf2_priv *priv, u16 off, u16 reg)
110+{
111+ return readl_relaxed(priv->reg + priv->reg_offsets[off] + reg);
112+}
113+
114+static inline void reg_led_writel(struct bcm_sf2_priv *priv, u32 val, u16 off, u16 reg)
115+{
116+ writel_relaxed(val, priv->reg + priv->reg_offsets[off] + reg);
117+}
118+
119 /* RXNFC */
120 int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port,
121 struct ethtool_rxnfc *nfc, u32 *rule_locs);
122--- a/drivers/net/dsa/bcm_sf2_regs.h
123+++ b/drivers/net/dsa/bcm_sf2_regs.h
124@@ -25,6 +25,10 @@ enum bcm_sf2_reg_offs {
125 REG_LED_0_CNTRL,
126 REG_LED_1_CNTRL,
127 REG_LED_2_CNTRL,
128+ REG_LED_3_CNTRL,
129+ REG_LED_4_CNTRL,
130+ REG_LED_5_CNTRL,
131+ REG_LED_AGGREGATE_CTRL,
132 REG_SWITCH_REG_MAX,
133 };
134
135@@ -56,6 +60,63 @@ enum bcm_sf2_reg_offs {
136 #define CROSSBAR_BCM4908_EXT_GPHY4 1
137 #define CROSSBAR_BCM4908_EXT_RGMII 2
138
139+/* Relative to REG_LED_*_CNTRL (BCM7278, BCM7445) */
140+#define LED_CNTRL_NO_LINK_ENCODE_SHIFT 0
141+#define LED_CNTRL_M10_ENCODE_SHIFT 2
142+#define LED_CNTRL_M100_ENCODE_SHIFT 4
143+#define LED_CNTRL_M1000_ENCODE_SHIFT 6
144+#define LED_CNTRL_SEL_NO_LINK_ENCODE_SHIFT 8
145+#define LED_CNTRL_SEL_10M_ENCODE_SHIFT 10
146+#define LED_CNTRL_SEL_100M_ENCODE_SHIFT 12
147+#define LED_CNTRL_SEL_1000M_ENCODE_SHIFT 14
148+#define LED_CNTRL_RX_DV_EN (1 << 16)
149+#define LED_CNTRL_TX_EN_EN (1 << 17)
150+#define LED_CNTRL_SPDLNK_LED0_ACT_SEL_SHIFT 18
151+#define LED_CNTRL_SPDLNK_LED1_ACT_SEL_SHIFT 20
152+#define LED_CNTRL_ACT_LED_ACT_SEL_SHIFT 22
153+#define LED_CNTRL_SPDLNK_SRC_SEL (1 << 24)
154+#define LED_CNTRL_SPDLNK_LED0_ACT_POL_SEL (1 << 25)
155+#define LED_CNTRL_SPDLNK_LED1_ACT_POL_SEL (1 << 26)
156+#define LED_CNTRL_ACT_LED_POL_SEL (1 << 27)
157+#define LED_CNTRL_MASK 0x3
158+
159+/* Register relative to REG_LED_*_CNTRL (BCM4908) */
160+#define REG_LED_CTRL 0x0
161+#define LED_CTRL_RX_ACT_EN 0x00000001
162+#define LED_CTRL_TX_ACT_EN 0x00000002
163+#define LED_CTRL_SPDLNK_LED0_ACT_SEL 0x00000004
164+#define LED_CTRL_SPDLNK_LED1_ACT_SEL 0x00000008
165+#define LED_CTRL_SPDLNK_LED2_ACT_SEL 0x00000010
166+#define LED_CTRL_ACT_LED_ACT_SEL 0x00000020
167+#define LED_CTRL_SPDLNK_LED0_ACT_POL_SEL 0x00000040
168+#define LED_CTRL_SPDLNK_LED1_ACT_POL_SEL 0x00000080
169+#define LED_CTRL_SPDLNK_LED2_ACT_POL_SEL 0x00000100
170+#define LED_CTRL_ACT_LED_POL_SEL 0x00000200
171+#define LED_CTRL_LED_SPD_OVRD 0x00001c00
172+#define LED_CTRL_LNK_STATUS_OVRD 0x00002000
173+#define LED_CTRL_SPD_OVRD_EN 0x00004000
174+#define LED_CTRL_LNK_OVRD_EN 0x00008000
175+
176+/* Register relative to REG_LED_*_CNTRL (BCM4908) */
177+#define REG_LED_LINK_SPEED_ENC_SEL 0x4
178+#define LED_LINK_SPEED_ENC_SEL_NO_LINK_SHIFT 0
179+#define LED_LINK_SPEED_ENC_SEL_10M_SHIFT 3
180+#define LED_LINK_SPEED_ENC_SEL_100M_SHIFT 6
181+#define LED_LINK_SPEED_ENC_SEL_1000M_SHIFT 9
182+#define LED_LINK_SPEED_ENC_SEL_2500M_SHIFT 12
183+#define LED_LINK_SPEED_ENC_SEL_10G_SHIFT 15
184+#define LED_LINK_SPEED_ENC_SEL_MASK 0x7
185+
186+/* Register relative to REG_LED_*_CNTRL (BCM4908) */
187+#define REG_LED_LINK_SPEED_ENC 0x8
188+#define LED_LINK_SPEED_ENC_NO_LINK_SHIFT 0
189+#define LED_LINK_SPEED_ENC_M10_SHIFT 3
190+#define LED_LINK_SPEED_ENC_M100_SHIFT 6
191+#define LED_LINK_SPEED_ENC_M1000_SHIFT 9
192+#define LED_LINK_SPEED_ENC_M2500_SHIFT 12
193+#define LED_LINK_SPEED_ENC_M10G_SHIFT 15
194+#define LED_LINK_SPEED_ENC_MASK 0x7
195+
196 /* Relative to REG_RGMII_CNTRL */
197 #define RGMII_MODE_EN (1 << 0)
198 #define ID_MODE_DIS (1 << 1)
199@@ -73,10 +134,6 @@ enum bcm_sf2_reg_offs {
200 #define LPI_COUNT_SHIFT 9
201 #define LPI_COUNT_MASK 0x3F
202
203-#define REG_LED_CNTRL(x) (REG_LED_0_CNTRL + (x))
204-
205-#define SPDLNK_SRC_SEL (1 << 24)
206-
207 /* Register set relative to 'INTRL2_0' and 'INTRL2_1' */
208 #define INTRL2_CPU_STATUS 0x00
209 #define INTRL2_CPU_SET 0x04