realtek: update the tree to the latest refactored version
[openwrt/staging/jow.git] / target / linux / realtek / files-5.4 / drivers / net / dsa / rtl83xx / rtl838x.c
1 // SPDX-License-Identifier: GPL-2.0-only
2
3 #include <asm/mach-rtl838x/mach-rtl83xx.h>
4 #include "rtl83xx.h"
5
6 extern struct mutex smi_lock;
7
8
9 static inline void rtl838x_mask_port_reg(u64 clear, u64 set, int reg)
10 {
11 sw_w32_mask((u32)clear, (u32)set, reg);
12 }
13
14 static inline void rtl838x_set_port_reg(u64 set, int reg)
15 {
16 sw_w32(set, reg);
17 }
18
19 static inline u64 rtl838x_get_port_reg(int reg)
20 {
21 return ((u64) sw_r32(reg));
22 }
23
24 static inline int rtl838x_stat_port_std_mib(int p)
25 {
26 return RTL838X_STAT_PORT_STD_MIB + (p << 8);
27 }
28
29 static inline int rtl838x_port_iso_ctrl(int p)
30 {
31 return RTL838X_PORT_ISO_CTRL(p);
32 }
33
34 static inline void rtl838x_exec_tbl0_cmd(u32 cmd)
35 {
36 sw_w32(cmd, RTL838X_TBL_ACCESS_CTRL_0);
37 do { } while (sw_r32(RTL838X_TBL_ACCESS_CTRL_0) & BIT(15));
38 }
39
40 static inline void rtl838x_exec_tbl1_cmd(u32 cmd)
41 {
42 sw_w32(cmd, RTL838X_TBL_ACCESS_CTRL_1);
43 do { } while (sw_r32(RTL838X_TBL_ACCESS_CTRL_1) & BIT(15));
44 }
45
46 static inline int rtl838x_tbl_access_data_0(int i)
47 {
48 return RTL838X_TBL_ACCESS_DATA_0(i);
49 }
50
51 static void rtl838x_vlan_tables_read(u32 vlan, struct rtl838x_vlan_info *info)
52 {
53 u32 cmd, v;
54
55 cmd = BIT(15) /* Execute cmd */
56 | BIT(14) /* Read */
57 | 0 << 12 /* Table type 0b00 */
58 | (vlan & 0xfff);
59 rtl838x_exec_tbl0_cmd(cmd);
60 info->tagged_ports = sw_r32(RTL838X_TBL_ACCESS_DATA_0(0));
61 v = sw_r32(RTL838X_TBL_ACCESS_DATA_0(1));
62 info->profile_id = v & 0x7;
63 info->hash_mc_fid = !!(v & 0x8);
64 info->hash_uc_fid = !!(v & 0x10);
65 info->fid = (v >> 5) & 0x3f;
66
67
68 cmd = BIT(15) /* Execute cmd */
69 | BIT(14) /* Read */
70 | 0 << 12 /* Table type 0b00 */
71 | (vlan & 0xfff);
72 rtl838x_exec_tbl1_cmd(cmd);
73 info->untagged_ports = sw_r32(RTL838X_TBL_ACCESS_DATA_1(0));
74 }
75
76 static void rtl838x_vlan_set_tagged(u32 vlan, struct rtl838x_vlan_info *info)
77 {
78 u32 cmd = BIT(15) /* Execute cmd */
79 | 0 << 14 /* Write */
80 | 0 << 12 /* Table type 0b00 */
81 | (vlan & 0xfff);
82 u32 v;
83
84 sw_w32(info->tagged_ports, RTL838X_TBL_ACCESS_DATA_0(0));
85
86 v = info->profile_id;
87 v |= info->hash_mc_fid ? 0x8 : 0;
88 v |= info->hash_uc_fid ? 0x10 : 0;
89 v |= ((u32)info->fid) << 5;
90
91 sw_w32(v, RTL838X_TBL_ACCESS_DATA_0(1));
92 rtl838x_exec_tbl0_cmd(cmd);
93 }
94
95 static void rtl838x_vlan_set_untagged(u32 vlan, u64 portmask)
96 {
97 u32 cmd = BIT(15) /* Execute cmd */
98 | 0 << 14 /* Write */
99 | 0 << 12 /* Table type 0b00 */
100 | (vlan & 0xfff);
101 sw_w32(portmask & 0x1fffffff, RTL838X_TBL_ACCESS_DATA_1(0));
102 rtl838x_exec_tbl1_cmd(cmd);
103 }
104
105 static inline int rtl838x_mac_force_mode_ctrl(int p)
106 {
107 return RTL838X_MAC_FORCE_MODE_CTRL + (p << 2);
108 }
109
110 static inline int rtl838x_mac_port_ctrl(int p)
111 {
112 return RTL838X_MAC_PORT_CTRL(p);
113 }
114
115 static inline int rtl838x_l2_port_new_salrn(int p)
116 {
117 return RTL838X_L2_PORT_NEW_SALRN(p);
118 }
119
120 static inline int rtl838x_l2_port_new_sa_fwd(int p)
121 {
122 return RTL838X_L2_PORT_NEW_SA_FWD(p);
123 }
124
125 static inline int rtl838x_mir_ctrl(int group)
126 {
127 return RTL838X_MIR_CTRL(group);
128 }
129
130 static inline int rtl838x_mir_dpm(int group)
131 {
132 return RTL838X_MIR_DPM_CTRL(group);
133 }
134
135 static inline int rtl838x_mir_spm(int group)
136 {
137 return RTL838X_MIR_SPM_CTRL(group);
138 }
139
140 static inline int rtl838x_mac_link_spd_sts(int p)
141 {
142 return RTL838X_MAC_LINK_SPD_STS(p);
143 }
144
145 static u64 rtl838x_read_l2_entry_using_hash(u32 hash, u32 position, struct rtl838x_l2_entry *e)
146 {
147 u64 entry;
148 u32 r[3];
149
150 /* Search in SRAM, with hash and at position in hash bucket (0-3) */
151 u32 idx = (0 << 14) | (hash << 2) | position;
152
153 u32 cmd = BIT(16) /* Execute cmd */
154 | BIT(15) /* Read */
155 | 0 << 13 /* Table type 0b00 */
156 | (idx & 0x1fff);
157
158 sw_w32(cmd, RTL838X_TBL_ACCESS_L2_CTRL);
159 do { } while (sw_r32(RTL838X_TBL_ACCESS_L2_CTRL) & BIT(16));
160 r[0] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(0));
161 r[1] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(1));
162 r[2] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(2));
163
164 e->mac[0] = (r[1] >> 20);
165 e->mac[1] = (r[1] >> 12);
166 e->mac[2] = (r[1] >> 4);
167 e->mac[3] = (r[1] & 0xf) << 4 | (r[2] >> 28);
168 e->mac[4] = (r[2] >> 20);
169 e->mac[5] = (r[2] >> 12);
170 e->is_static = !!((r[0] >> 19) & 1);
171 e->vid = r[0] & 0xfff;
172 e->rvid = r[2] & 0xfff;
173 e->port = (r[0] >> 12) & 0x1f;
174
175 e->valid = true;
176 if (!(r[0] >> 17)) /* Check for invalid entry */
177 e->valid = false;
178
179 if (e->valid)
180 pr_debug("Found in Hash: R1 %x R2 %x R3 %x\n", r[0], r[1], r[2]);
181
182 entry = (((u64) r[1]) << 32) | (r[2] & 0xfffff000) | (r[0] & 0xfff);
183 return entry;
184 }
185
186 static u64 rtl838x_read_cam(int idx, struct rtl838x_l2_entry *e)
187 {
188 u64 entry;
189 u32 r[3];
190
191 u32 cmd = BIT(16) /* Execute cmd */
192 | BIT(15) /* Read */
193 | BIT(13) /* Table type 0b01 */
194 | (idx & 0x3f);
195 sw_w32(cmd, RTL838X_TBL_ACCESS_L2_CTRL);
196 do { } while (sw_r32(RTL838X_TBL_ACCESS_L2_CTRL) & BIT(16));
197 r[0] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(0));
198 r[1] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(1));
199 r[2] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(2));
200
201 e->mac[0] = (r[1] >> 20);
202 e->mac[1] = (r[1] >> 12);
203 e->mac[2] = (r[1] >> 4);
204 e->mac[3] = (r[1] & 0xf) << 4 | (r[2] >> 28);
205 e->mac[4] = (r[2] >> 20);
206 e->mac[5] = (r[2] >> 12);
207 e->is_static = !!((r[0] >> 19) & 1);
208 e->vid = r[0] & 0xfff;
209 e->rvid = r[2] & 0xfff;
210 e->port = (r[0] >> 12) & 0x1f;
211
212 e->valid = true;
213 if (!(r[0] >> 17)) /* Check for invalid entry */
214 e->valid = false;
215
216 if (e->valid)
217 pr_debug("Found in CAM: R1 %x R2 %x R3 %x\n", r[0], r[1], r[2]);
218
219 entry = (((u64) r[1]) << 32) | (r[2] & 0xfffff000) | (r[0] & 0xfff);
220 return entry;
221 }
222
223 static inline int rtl838x_vlan_profile(int profile)
224 {
225 return RTL838X_VLAN_PROFILE(profile);
226 }
227
228 static inline int rtl838x_vlan_port_egr_filter(int port)
229 {
230 return RTL838X_VLAN_PORT_EGR_FLTR;
231 }
232
233 static inline int rtl838x_vlan_port_igr_filter(int port)
234 {
235 return RTL838X_VLAN_PORT_IGR_FLTR(port);
236 }
237
238 static inline int rtl838x_vlan_port_pb(int port)
239 {
240 return RTL838X_VLAN_PORT_PB_VLAN(port);
241 }
242
243 static inline int rtl838x_vlan_port_tag_sts_ctrl(int port)
244 {
245 return RTL838X_VLAN_PORT_TAG_STS_CTRL(port);
246 }
247
248 const struct rtl838x_reg rtl838x_reg = {
249 .mask_port_reg_be = rtl838x_mask_port_reg,
250 .set_port_reg_be = rtl838x_set_port_reg,
251 .get_port_reg_be = rtl838x_get_port_reg,
252 .mask_port_reg_le = rtl838x_mask_port_reg,
253 .set_port_reg_le = rtl838x_set_port_reg,
254 .get_port_reg_le = rtl838x_get_port_reg,
255 .stat_port_rst = RTL838X_STAT_PORT_RST,
256 .stat_rst = RTL838X_STAT_RST,
257 .stat_port_std_mib = rtl838x_stat_port_std_mib,
258 .port_iso_ctrl = rtl838x_port_iso_ctrl,
259 .l2_ctrl_0 = RTL838X_L2_CTRL_0,
260 .l2_ctrl_1 = RTL838X_L2_CTRL_1,
261 .l2_port_aging_out = RTL838X_L2_PORT_AGING_OUT,
262 .smi_poll_ctrl = RTL838X_SMI_POLL_CTRL,
263 .l2_tbl_flush_ctrl = RTL838X_L2_TBL_FLUSH_CTRL,
264 .exec_tbl0_cmd = rtl838x_exec_tbl0_cmd,
265 .exec_tbl1_cmd = rtl838x_exec_tbl1_cmd,
266 .tbl_access_data_0 = rtl838x_tbl_access_data_0,
267 .isr_glb_src = RTL838X_ISR_GLB_SRC,
268 .isr_port_link_sts_chg = RTL838X_ISR_PORT_LINK_STS_CHG,
269 .imr_port_link_sts_chg = RTL838X_IMR_PORT_LINK_STS_CHG,
270 .imr_glb = RTL838X_IMR_GLB,
271 .vlan_tables_read = rtl838x_vlan_tables_read,
272 .vlan_set_tagged = rtl838x_vlan_set_tagged,
273 .vlan_set_untagged = rtl838x_vlan_set_untagged,
274 .mac_force_mode_ctrl = rtl838x_mac_force_mode_ctrl,
275 .mac_port_ctrl = rtl838x_mac_port_ctrl,
276 .l2_port_new_salrn = rtl838x_l2_port_new_salrn,
277 .l2_port_new_sa_fwd = rtl838x_l2_port_new_sa_fwd,
278 .mir_ctrl = rtl838x_mir_ctrl,
279 .mir_dpm = rtl838x_mir_dpm,
280 .mir_spm = rtl838x_mir_spm,
281 .mac_link_sts = RTL838X_MAC_LINK_STS,
282 .mac_link_dup_sts = RTL838X_MAC_LINK_DUP_STS,
283 .mac_link_spd_sts = rtl838x_mac_link_spd_sts,
284 .mac_rx_pause_sts = RTL838X_MAC_RX_PAUSE_STS,
285 .mac_tx_pause_sts = RTL838X_MAC_TX_PAUSE_STS,
286 .read_l2_entry_using_hash = rtl838x_read_l2_entry_using_hash,
287 .read_cam = rtl838x_read_cam,
288 .vlan_profile = rtl838x_vlan_profile,
289 .vlan_port_egr_filter = rtl838x_vlan_port_egr_filter,
290 .vlan_port_igr_filter = rtl838x_vlan_port_igr_filter,
291 .vlan_port_pb = rtl838x_vlan_port_pb,
292 .vlan_port_tag_sts_ctrl = rtl838x_vlan_port_tag_sts_ctrl,
293 };
294
295 irqreturn_t rtl838x_switch_irq(int irq, void *dev_id)
296 {
297 struct dsa_switch *ds = dev_id;
298 u32 status = sw_r32(RTL838X_ISR_GLB_SRC);
299 u32 ports = sw_r32(RTL838X_ISR_PORT_LINK_STS_CHG);
300 u32 link;
301 int i;
302
303 /* Clear status */
304 sw_w32(ports, RTL838X_ISR_PORT_LINK_STS_CHG);
305 pr_debug("RTL8380 Link change: status: %x, ports %x\n", status, ports);
306
307 for (i = 0; i < 28; i++) {
308 if (ports & BIT(i)) {
309 link = sw_r32(RTL838X_MAC_LINK_STS);
310 if (link & BIT(i))
311 dsa_port_phylink_mac_change(ds, i, true);
312 else
313 dsa_port_phylink_mac_change(ds, i, false);
314 }
315 }
316 return IRQ_HANDLED;
317 }
318
319 int rtl838x_smi_wait_op(int timeout)
320 {
321 do {
322 timeout--;
323 udelay(10);
324 } while ((sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_1) & 0x1) && (timeout >= 0));
325 if (timeout <= 0)
326 return -1;
327 return 0;
328 }
329
330 /*
331 * Reads a register in a page from the PHY
332 */
333 int rtl838x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
334 {
335 u32 v;
336 u32 park_page;
337
338 if (port > 31) {
339 *val = 0xffff;
340 return 0;
341 }
342
343 if (page > 4095 || reg > 31)
344 return -ENOTSUPP;
345
346 mutex_lock(&smi_lock);
347
348 if (rtl838x_smi_wait_op(10000))
349 goto timeout;
350
351 sw_w32_mask(0xffff0000, port << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
352
353 park_page = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_1) & ((0x1f << 15) | 0x2);
354 v = reg << 20 | page << 3;
355 sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1);
356 sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1);
357
358 if (rtl838x_smi_wait_op(10000))
359 goto timeout;
360
361 *val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
362
363 mutex_unlock(&smi_lock);
364 return 0;
365
366 timeout:
367 mutex_unlock(&smi_lock);
368 return -ETIMEDOUT;
369 }
370
371 /*
372 * Write to a register in a page of the PHY
373 */
374 int rtl838x_write_phy(u32 port, u32 page, u32 reg, u32 val)
375 {
376 u32 v;
377 u32 park_page;
378
379 val &= 0xffff;
380 if (port > 31 || page > 4095 || reg > 31)
381 return -ENOTSUPP;
382
383 mutex_lock(&smi_lock);
384 if (rtl838x_smi_wait_op(10000))
385 goto timeout;
386
387 sw_w32(BIT(port), RTL838X_SMI_ACCESS_PHY_CTRL_0);
388 mdelay(10);
389
390 sw_w32_mask(0xffff0000, val << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
391
392 park_page = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_1) & ((0x1f << 15) | 0x2);
393 v = reg << 20 | page << 3 | 0x4;
394 sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1);
395 sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1);
396
397 if (rtl838x_smi_wait_op(10000))
398 goto timeout;
399
400 mutex_unlock(&smi_lock);
401 return 0;
402
403 timeout:
404 mutex_unlock(&smi_lock);
405 return -ETIMEDOUT;
406 }
407
408 void rtl8380_get_version(struct rtl838x_switch_priv *priv)
409 {
410 u32 rw_save, info_save;
411 u32 info;
412
413 rw_save = sw_r32(RTL838X_INT_RW_CTRL);
414 sw_w32(rw_save | 0x3, RTL838X_INT_RW_CTRL);
415
416 info_save = sw_r32(RTL838X_CHIP_INFO);
417 sw_w32(info_save | 0xA0000000, RTL838X_CHIP_INFO);
418
419 info = sw_r32(RTL838X_CHIP_INFO);
420 sw_w32(info_save, RTL838X_CHIP_INFO);
421 sw_w32(rw_save, RTL838X_INT_RW_CTRL);
422
423 if ((info & 0xFFFF) == 0x6275) {
424 if (((info >> 16) & 0x1F) == 0x1)
425 priv->version = RTL8380_VERSION_A;
426 else if (((info >> 16) & 0x1F) == 0x2)
427 priv->version = RTL8380_VERSION_B;
428 else
429 priv->version = RTL8380_VERSION_B;
430 } else {
431 priv->version = '-';
432 }
433 }
434
435 /*
436 * Applies the same hash algorithm as the one used currently by the ASIC
437 */
438 u32 rtl838x_hash(struct rtl838x_switch_priv *priv, u64 seed)
439 {
440 u32 h1, h2, h3, h;
441
442 if (sw_r32(priv->r->l2_ctrl_0) & 1) {
443 h1 = (seed >> 11) & 0x7ff;
444 h1 = ((h1 & 0x1f) << 6) | ((h1 >> 5) & 0x3f);
445
446 h2 = (seed >> 33) & 0x7ff;
447 h2 = ((h2 & 0x3f) << 5) | ((h2 >> 6) & 0x1f);
448
449 h3 = (seed >> 44) & 0x7ff;
450 h3 = ((h3 & 0x7f) << 4) | ((h3 >> 7) & 0xf);
451
452 h = h1 ^ h2 ^ h3 ^ ((seed >> 55) & 0x1ff);
453 h ^= ((seed >> 22) & 0x7ff) ^ (seed & 0x7ff);
454 } else {
455 h = ((seed >> 55) & 0x1ff) ^ ((seed >> 44) & 0x7ff)
456 ^ ((seed >> 33) & 0x7ff) ^ ((seed >> 22) & 0x7ff)
457 ^ ((seed >> 11) & 0x7ff) ^ (seed & 0x7ff);
458 }
459
460 return h;
461 }
462
463 void rtl838x_vlan_profile_dump(int index)
464 {
465 u32 profile;
466
467 if (index < 0 || index > 7)
468 return;
469
470 profile = sw_r32(RTL838X_VLAN_PROFILE(index));
471
472 pr_debug("VLAN %d: L2 learning: %d, L2 Unknown MultiCast Field %x, \
473 IPv4 Unknown MultiCast Field %x, IPv6 Unknown MultiCast Field: %x",
474 index, profile & 1, (profile >> 1) & 0x1ff, (profile >> 10) & 0x1ff,
475 (profile >> 19) & 0x1ff);
476 }