realtek: Setup all VLANs with default configurations
[openwrt/openwrt.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 void rtl838x_print_matrix(void)
9 {
10 unsigned volatile int *ptr8;
11 int i;
12
13 ptr8 = RTL838X_SW_BASE + RTL838X_PORT_ISO_CTRL(0);
14 for (i = 0; i < 28; i += 8)
15 pr_debug("> %8x %8x %8x %8x %8x %8x %8x %8x\n",
16 ptr8[i + 0], ptr8[i + 1], ptr8[i + 2], ptr8[i + 3],
17 ptr8[i + 4], ptr8[i + 5], ptr8[i + 6], ptr8[i + 7]);
18 pr_debug("CPU_PORT> %8x\n", ptr8[28]);
19 }
20
21 static inline int rtl838x_port_iso_ctrl(int p)
22 {
23 return RTL838X_PORT_ISO_CTRL(p);
24 }
25
26 static inline void rtl838x_exec_tbl0_cmd(u32 cmd)
27 {
28 sw_w32(cmd, RTL838X_TBL_ACCESS_CTRL_0);
29 do { } while (sw_r32(RTL838X_TBL_ACCESS_CTRL_0) & BIT(15));
30 }
31
32 static inline void rtl838x_exec_tbl1_cmd(u32 cmd)
33 {
34 sw_w32(cmd, RTL838X_TBL_ACCESS_CTRL_1);
35 do { } while (sw_r32(RTL838X_TBL_ACCESS_CTRL_1) & BIT(15));
36 }
37
38 static inline int rtl838x_tbl_access_data_0(int i)
39 {
40 return RTL838X_TBL_ACCESS_DATA_0(i);
41 }
42
43 static void rtl838x_vlan_tables_read(u32 vlan, struct rtl838x_vlan_info *info)
44 {
45 u32 v;
46 // Read VLAN table (0) via register 0
47 struct table_reg *r = rtl_table_get(RTL8380_TBL_0, 0);
48
49 rtl_table_read(r, vlan);
50 info->tagged_ports = sw_r32(rtl_table_data(r, 0));
51 v = sw_r32(rtl_table_data(r, 1));
52 pr_debug("VLAN_READ %d: %016llx %08x\n", vlan, info->tagged_ports, v);
53 rtl_table_release(r);
54
55 info->profile_id = v & 0x7;
56 info->hash_mc_fid = !!(v & 0x8);
57 info->hash_uc_fid = !!(v & 0x10);
58 info->fid = (v >> 5) & 0x3f;
59
60 // Read UNTAG table (0) via table register 1
61 r = rtl_table_get(RTL8380_TBL_1, 0);
62 rtl_table_read(r, vlan);
63 info->untagged_ports = sw_r32(rtl_table_data(r, 0));
64 rtl_table_release(r);
65 }
66
67 static void rtl838x_vlan_set_tagged(u32 vlan, struct rtl838x_vlan_info *info)
68 {
69 u32 v;
70 // Access VLAN table (0) via register 0
71 struct table_reg *r = rtl_table_get(RTL8380_TBL_0, 0);
72
73 sw_w32(info->tagged_ports, rtl_table_data(r, 0));
74
75 v = info->profile_id;
76 v |= info->hash_mc_fid ? 0x8 : 0;
77 v |= info->hash_uc_fid ? 0x10 : 0;
78 v |= ((u32)info->fid) << 5;
79 sw_w32(v, rtl_table_data(r, 1));
80
81 rtl_table_write(r, vlan);
82 rtl_table_release(r);
83 }
84
85 static void rtl838x_vlan_set_untagged(u32 vlan, u64 portmask)
86 {
87 // Access UNTAG table (0) via register 1
88 struct table_reg *r = rtl_table_get(RTL8380_TBL_1, 0);
89
90 sw_w32(portmask & 0x1fffffff, rtl_table_data(r, 0));
91 rtl_table_write(r, vlan);
92 rtl_table_release(r);
93 }
94
95 /* Sets the L2 forwarding to be based on either the inner VLAN tag or the outer
96 */
97 static void rtl838x_vlan_fwd_on_inner(int port, bool is_set)
98 {
99 if (is_set)
100 sw_w32_mask(BIT(port), 0, RTL838X_VLAN_PORT_FWD);
101 else
102 sw_w32_mask(0, BIT(port), RTL838X_VLAN_PORT_FWD);
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_mac_link_spd_sts(int p)
126 {
127 return RTL838X_MAC_LINK_SPD_STS(p);
128 }
129
130 inline static int rtl838x_trk_mbr_ctr(int group)
131 {
132 return RTL838X_TRK_MBR_CTR + (group << 2);
133 }
134
135 static u64 rtl838x_read_l2_entry_using_hash(u32 hash, u32 position, struct rtl838x_l2_entry *e)
136 {
137 u64 entry;
138 u32 r[3];
139
140 /* Search in SRAM, with hash and at position in hash bucket (0-3) */
141 u32 idx = (0 << 14) | (hash << 2) | position;
142
143 u32 cmd = BIT(16) /* Execute cmd */
144 | BIT(15) /* Read */
145 | 0 << 13 /* Table type 0b00 */
146 | (idx & 0x1fff);
147
148 sw_w32(cmd, RTL838X_TBL_ACCESS_L2_CTRL);
149 do { } while (sw_r32(RTL838X_TBL_ACCESS_L2_CTRL) & BIT(16));
150 r[0] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(0));
151 r[1] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(1));
152 r[2] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(2));
153
154 e->mac[0] = (r[1] >> 20);
155 e->mac[1] = (r[1] >> 12);
156 e->mac[2] = (r[1] >> 4);
157 e->mac[3] = (r[1] & 0xf) << 4 | (r[2] >> 28);
158 e->mac[4] = (r[2] >> 20);
159 e->mac[5] = (r[2] >> 12);
160 e->is_static = !!((r[0] >> 19) & 1);
161 e->vid = r[0] & 0xfff;
162 e->rvid = r[2] & 0xfff;
163 e->port = (r[0] >> 12) & 0x1f;
164
165 e->valid = true;
166 if (!(r[0] >> 17)) /* Check for invalid entry */
167 e->valid = false;
168
169 if (e->valid)
170 pr_debug("Found in Hash: R1 %x R2 %x R3 %x\n", r[0], r[1], r[2]);
171
172 entry = (((u64) r[1]) << 32) | (r[2] & 0xfffff000) | (r[0] & 0xfff);
173 return entry;
174 }
175
176 static u64 rtl838x_read_cam(int idx, struct rtl838x_l2_entry *e)
177 {
178 u64 entry;
179 u32 r[3];
180
181 u32 cmd = BIT(16) /* Execute cmd */
182 | BIT(15) /* Read */
183 | BIT(13) /* Table type 0b01 */
184 | (idx & 0x3f);
185 sw_w32(cmd, RTL838X_TBL_ACCESS_L2_CTRL);
186 do { } while (sw_r32(RTL838X_TBL_ACCESS_L2_CTRL) & BIT(16));
187 r[0] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(0));
188 r[1] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(1));
189 r[2] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(2));
190
191 e->mac[0] = (r[1] >> 20);
192 e->mac[1] = (r[1] >> 12);
193 e->mac[2] = (r[1] >> 4);
194 e->mac[3] = (r[1] & 0xf) << 4 | (r[2] >> 28);
195 e->mac[4] = (r[2] >> 20);
196 e->mac[5] = (r[2] >> 12);
197 e->is_static = !!((r[0] >> 19) & 1);
198 e->vid = r[0] & 0xfff;
199 e->rvid = r[2] & 0xfff;
200 e->port = (r[0] >> 12) & 0x1f;
201
202 e->valid = true;
203 if (!(r[0] >> 17)) /* Check for invalid entry */
204 e->valid = false;
205
206 if (e->valid)
207 pr_debug("Found in CAM: R1 %x R2 %x R3 %x\n", r[0], r[1], r[2]);
208
209 entry = (((u64) r[1]) << 32) | (r[2] & 0xfffff000) | (r[0] & 0xfff);
210 return entry;
211 }
212
213 static u64 rtl838x_read_mcast_pmask(int idx)
214 {
215 u32 portmask;
216 // Read MC_PMSK (2) via register RTL8380_TBL_L2
217 struct table_reg *q = rtl_table_get(RTL8380_TBL_L2, 2);
218
219 rtl_table_read(q, idx);
220 portmask = sw_r32(rtl_table_data(q, 0));
221 rtl_table_release(q);
222
223 return portmask;
224 }
225
226 static void rtl838x_write_mcast_pmask(int idx, u64 portmask)
227 {
228 // Access MC_PMSK (2) via register RTL8380_TBL_L2
229 struct table_reg *q = rtl_table_get(RTL8380_TBL_L2, 2);
230
231 sw_w32(((u32)portmask) & 0x1fffffff, rtl_table_data(q, 0));
232 rtl_table_write(q, idx);
233 rtl_table_release(q);
234 }
235
236 static void rtl838x_vlan_profile_setup(int profile)
237 {
238 u32 pmask_id = UNKNOWN_MC_PMASK;
239 // Enable L2 Learning BIT 0, portmask UNKNOWN_MC_PMASK for unknown MC traffic flooding
240 u32 p = 1 | pmask_id << 1 | pmask_id << 10 | pmask_id << 19;
241
242 sw_w32(p, RTL838X_VLAN_PROFILE(profile));
243
244 /* RTL8380 and RTL8390 use an index into the portmask table to set the
245 * unknown multicast portmask, setup a default at a safe location
246 * On RTL93XX, the portmask is directly set in the profile,
247 * see e.g. rtl9300_vlan_profile_setup
248 */
249 rtl838x_write_mcast_pmask(UNKNOWN_MC_PMASK, 0xfffffff);
250 }
251
252 static inline int rtl838x_vlan_port_egr_filter(int port)
253 {
254 return RTL838X_VLAN_PORT_EGR_FLTR;
255 }
256
257 static inline int rtl838x_vlan_port_igr_filter(int port)
258 {
259 return RTL838X_VLAN_PORT_IGR_FLTR(port);
260 }
261
262 static void rtl838x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
263 {
264 int i;
265 u32 cmd = 1 << 15 /* Execute cmd */
266 | 1 << 14 /* Read */
267 | 2 << 12 /* Table type 0b10 */
268 | (msti & 0xfff);
269 priv->r->exec_tbl0_cmd(cmd);
270
271 for (i = 0; i < 2; i++)
272 port_state[i] = sw_r32(priv->r->tbl_access_data_0(i));
273 }
274
275 static void rtl838x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
276 {
277 int i;
278 u32 cmd = 1 << 15 /* Execute cmd */
279 | 0 << 14 /* Write */
280 | 2 << 12 /* Table type 0b10 */
281 | (msti & 0xfff);
282
283 for (i = 0; i < 2; i++)
284 sw_w32(port_state[i], priv->r->tbl_access_data_0(i));
285 priv->r->exec_tbl0_cmd(cmd);
286 }
287
288 u64 rtl838x_traffic_get(int source)
289 {
290 return rtl838x_get_port_reg(rtl838x_port_iso_ctrl(source));
291 }
292
293 void rtl838x_traffic_set(int source, u64 dest_matrix)
294 {
295 rtl838x_set_port_reg(dest_matrix, rtl838x_port_iso_ctrl(source));
296 }
297
298 void rtl838x_traffic_enable(int source, int dest)
299 {
300 rtl838x_mask_port_reg(0, BIT(dest), rtl838x_port_iso_ctrl(source));
301 }
302
303 void rtl838x_traffic_disable(int source, int dest)
304 {
305 rtl838x_mask_port_reg(BIT(dest), 0, rtl838x_port_iso_ctrl(source));
306 }
307
308 /*
309 * Enables or disables the EEE/EEEP capability of a port
310 */
311 static void rtl838x_port_eee_set(struct rtl838x_switch_priv *priv, int port, bool enable)
312 {
313 u32 v;
314
315 // This works only for Ethernet ports, and on the RTL838X, ports from 24 are SFP
316 if (port >= 24)
317 return;
318
319 pr_debug("In %s: setting port %d to %d\n", __func__, port, enable);
320 v = enable ? 0x3 : 0x0;
321
322 // Set EEE state for 100 (bit 9) & 1000MBit (bit 10)
323 sw_w32_mask(0x3 << 9, v << 9, priv->r->mac_force_mode_ctrl(port));
324
325 // Set TX/RX EEE state
326 if (enable) {
327 sw_w32_mask(0, BIT(port), RTL838X_EEE_PORT_TX_EN);
328 sw_w32_mask(0, BIT(port), RTL838X_EEE_PORT_RX_EN);
329 } else {
330 sw_w32_mask(BIT(port), 0, RTL838X_EEE_PORT_TX_EN);
331 sw_w32_mask(BIT(port), 0, RTL838X_EEE_PORT_RX_EN);
332 }
333 priv->ports[port].eee_enabled = enable;
334 }
335
336
337 /*
338 * Get EEE own capabilities and negotiation result
339 */
340 static int rtl838x_eee_port_ability(struct rtl838x_switch_priv *priv,
341 struct ethtool_eee *e, int port)
342 {
343 u64 link;
344
345 if (port >= 24)
346 return 0;
347
348 link = rtl839x_get_port_reg_le(RTL838X_MAC_LINK_STS);
349 if (!(link & BIT(port)))
350 return 0;
351
352 if (sw_r32(rtl838x_mac_force_mode_ctrl(port)) & BIT(9))
353 e->advertised |= ADVERTISED_100baseT_Full;
354
355 if (sw_r32(rtl838x_mac_force_mode_ctrl(port)) & BIT(10))
356 e->advertised |= ADVERTISED_1000baseT_Full;
357
358 if (sw_r32(RTL838X_MAC_EEE_ABLTY) & BIT(port)) {
359 e->lp_advertised = ADVERTISED_100baseT_Full;
360 e->lp_advertised |= ADVERTISED_1000baseT_Full;
361 return 1;
362 }
363
364 return 0;
365 }
366
367 static void rtl838x_init_eee(struct rtl838x_switch_priv *priv, bool enable)
368 {
369 int i;
370
371 pr_info("Setting up EEE, state: %d\n", enable);
372 sw_w32_mask(0x4, 0, RTL838X_SMI_GLB_CTRL);
373
374 /* Set timers for EEE */
375 sw_w32(0x5001411, RTL838X_EEE_TX_TIMER_GIGA_CTRL);
376 sw_w32(0x5001417, RTL838X_EEE_TX_TIMER_GELITE_CTRL);
377
378 // Enable EEE MAC support on ports
379 for (i = 0; i < priv->cpu_port; i++) {
380 if (priv->ports[i].phy)
381 rtl838x_port_eee_set(priv, i, enable);
382 }
383 priv->eee_enabled = enable;
384 }
385
386 const struct rtl838x_reg rtl838x_reg = {
387 .mask_port_reg_be = rtl838x_mask_port_reg,
388 .set_port_reg_be = rtl838x_set_port_reg,
389 .get_port_reg_be = rtl838x_get_port_reg,
390 .mask_port_reg_le = rtl838x_mask_port_reg,
391 .set_port_reg_le = rtl838x_set_port_reg,
392 .get_port_reg_le = rtl838x_get_port_reg,
393 .stat_port_rst = RTL838X_STAT_PORT_RST,
394 .stat_rst = RTL838X_STAT_RST,
395 .stat_port_std_mib = RTL838X_STAT_PORT_STD_MIB,
396 .port_iso_ctrl = rtl838x_port_iso_ctrl,
397 .traffic_enable = rtl838x_traffic_enable,
398 .traffic_disable = rtl838x_traffic_disable,
399 .traffic_get = rtl838x_traffic_get,
400 .traffic_set = rtl838x_traffic_set,
401 .l2_ctrl_0 = RTL838X_L2_CTRL_0,
402 .l2_ctrl_1 = RTL838X_L2_CTRL_1,
403 .l2_port_aging_out = RTL838X_L2_PORT_AGING_OUT,
404 .smi_poll_ctrl = RTL838X_SMI_POLL_CTRL,
405 .l2_tbl_flush_ctrl = RTL838X_L2_TBL_FLUSH_CTRL,
406 .exec_tbl0_cmd = rtl838x_exec_tbl0_cmd,
407 .exec_tbl1_cmd = rtl838x_exec_tbl1_cmd,
408 .tbl_access_data_0 = rtl838x_tbl_access_data_0,
409 .isr_glb_src = RTL838X_ISR_GLB_SRC,
410 .isr_port_link_sts_chg = RTL838X_ISR_PORT_LINK_STS_CHG,
411 .imr_port_link_sts_chg = RTL838X_IMR_PORT_LINK_STS_CHG,
412 .imr_glb = RTL838X_IMR_GLB,
413 .vlan_tables_read = rtl838x_vlan_tables_read,
414 .vlan_set_tagged = rtl838x_vlan_set_tagged,
415 .vlan_set_untagged = rtl838x_vlan_set_untagged,
416 .mac_force_mode_ctrl = rtl838x_mac_force_mode_ctrl,
417 .vlan_profile_dump = rtl838x_vlan_profile_dump,
418 .vlan_profile_setup = rtl838x_vlan_profile_setup,
419 .vlan_fwd_on_inner = rtl838x_vlan_fwd_on_inner,
420 .stp_get = rtl838x_stp_get,
421 .stp_set = rtl838x_stp_set,
422 .mac_port_ctrl = rtl838x_mac_port_ctrl,
423 .l2_port_new_salrn = rtl838x_l2_port_new_salrn,
424 .l2_port_new_sa_fwd = rtl838x_l2_port_new_sa_fwd,
425 .mir_ctrl = RTL838X_MIR_CTRL,
426 .mir_dpm = RTL838X_MIR_DPM_CTRL,
427 .mir_spm = RTL838X_MIR_SPM_CTRL,
428 .mac_link_sts = RTL838X_MAC_LINK_STS,
429 .mac_link_dup_sts = RTL838X_MAC_LINK_DUP_STS,
430 .mac_link_spd_sts = rtl838x_mac_link_spd_sts,
431 .mac_rx_pause_sts = RTL838X_MAC_RX_PAUSE_STS,
432 .mac_tx_pause_sts = RTL838X_MAC_TX_PAUSE_STS,
433 .read_l2_entry_using_hash = rtl838x_read_l2_entry_using_hash,
434 .read_cam = rtl838x_read_cam,
435 .vlan_port_egr_filter = RTL838X_VLAN_PORT_EGR_FLTR,
436 .vlan_port_igr_filter = RTL838X_VLAN_PORT_IGR_FLTR(0),
437 .vlan_port_pb = RTL838X_VLAN_PORT_PB_VLAN,
438 .vlan_port_tag_sts_ctrl = RTL838X_VLAN_PORT_TAG_STS_CTRL,
439 .trk_mbr_ctr = rtl838x_trk_mbr_ctr,
440 .rma_bpdu_fld_pmask = RTL838X_RMA_BPDU_FLD_PMSK,
441 .spcl_trap_eapol_ctrl = RTL838X_SPCL_TRAP_EAPOL_CTRL,
442 .init_eee = rtl838x_init_eee,
443 .port_eee_set = rtl838x_port_eee_set,
444 .eee_port_ability = rtl838x_eee_port_ability,
445 .read_mcast_pmask = rtl838x_read_mcast_pmask,
446 .write_mcast_pmask = rtl838x_write_mcast_pmask,
447 };
448
449 irqreturn_t rtl838x_switch_irq(int irq, void *dev_id)
450 {
451 struct dsa_switch *ds = dev_id;
452 u32 status = sw_r32(RTL838X_ISR_GLB_SRC);
453 u32 ports = sw_r32(RTL838X_ISR_PORT_LINK_STS_CHG);
454 u32 link;
455 int i;
456
457 /* Clear status */
458 sw_w32(ports, RTL838X_ISR_PORT_LINK_STS_CHG);
459 pr_info("RTL8380 Link change: status: %x, ports %x\n", status, ports);
460
461 for (i = 0; i < 28; i++) {
462 if (ports & BIT(i)) {
463 link = sw_r32(RTL838X_MAC_LINK_STS);
464 if (link & BIT(i))
465 dsa_port_phylink_mac_change(ds, i, true);
466 else
467 dsa_port_phylink_mac_change(ds, i, false);
468 }
469 }
470 return IRQ_HANDLED;
471 }
472
473 int rtl838x_smi_wait_op(int timeout)
474 {
475 do {
476 timeout--;
477 udelay(10);
478 } while ((sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_1) & 0x1) && (timeout >= 0));
479 if (timeout <= 0)
480 return -1;
481 return 0;
482 }
483
484 /*
485 * Reads a register in a page from the PHY
486 */
487 int rtl838x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
488 {
489 u32 v;
490 u32 park_page;
491
492 if (port > 31) {
493 *val = 0xffff;
494 return 0;
495 }
496
497 if (page > 4095 || reg > 31)
498 return -ENOTSUPP;
499
500 mutex_lock(&smi_lock);
501
502 if (rtl838x_smi_wait_op(10000))
503 goto timeout;
504
505 sw_w32_mask(0xffff0000, port << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
506
507 park_page = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_1) & ((0x1f << 15) | 0x2);
508 v = reg << 20 | page << 3;
509 sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1);
510 sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1);
511
512 if (rtl838x_smi_wait_op(10000))
513 goto timeout;
514
515 *val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
516
517 mutex_unlock(&smi_lock);
518 return 0;
519
520 timeout:
521 mutex_unlock(&smi_lock);
522 return -ETIMEDOUT;
523 }
524
525 /*
526 * Write to a register in a page of the PHY
527 */
528 int rtl838x_write_phy(u32 port, u32 page, u32 reg, u32 val)
529 {
530 u32 v;
531 u32 park_page;
532
533 val &= 0xffff;
534 if (port > 31 || page > 4095 || reg > 31)
535 return -ENOTSUPP;
536
537 mutex_lock(&smi_lock);
538 if (rtl838x_smi_wait_op(10000))
539 goto timeout;
540
541 sw_w32(BIT(port), RTL838X_SMI_ACCESS_PHY_CTRL_0);
542 mdelay(10);
543
544 sw_w32_mask(0xffff0000, val << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
545
546 park_page = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_1) & ((0x1f << 15) | 0x2);
547 v = reg << 20 | page << 3 | 0x4;
548 sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1);
549 sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1);
550
551 if (rtl838x_smi_wait_op(10000))
552 goto timeout;
553
554 mutex_unlock(&smi_lock);
555 return 0;
556
557 timeout:
558 mutex_unlock(&smi_lock);
559 return -ETIMEDOUT;
560 }
561
562 /*
563 * Read an mmd register of a PHY
564 */
565 int rtl838x_read_mmd_phy(u32 port, u32 addr, u32 reg, u32 *val)
566 {
567 u32 v;
568
569 mutex_lock(&smi_lock);
570
571 if (rtl838x_smi_wait_op(10000))
572 goto timeout;
573
574 sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
575 mdelay(10);
576
577 sw_w32_mask(0xffff0000, port << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
578
579 v = addr << 16 | reg;
580 sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_3);
581
582 /* mmd-access | read | cmd-start */
583 v = 1 << 1 | 0 << 2 | 1;
584 sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
585
586 if (rtl838x_smi_wait_op(10000))
587 goto timeout;
588
589 *val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
590
591 mutex_unlock(&smi_lock);
592 return 0;
593
594 timeout:
595 mutex_unlock(&smi_lock);
596 return -ETIMEDOUT;
597 }
598
599 /*
600 * Write to an mmd register of a PHY
601 */
602 int rtl838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val)
603 {
604 u32 v;
605
606 pr_debug("MMD write: port %d, dev %d, reg %d, val %x\n", port, addr, reg, val);
607 val &= 0xffff;
608 mutex_lock(&smi_lock);
609
610 if (rtl838x_smi_wait_op(10000))
611 goto timeout;
612
613 sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
614 mdelay(10);
615
616 sw_w32_mask(0xffff0000, val << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
617
618 sw_w32_mask(0x1f << 16, addr << 16, RTL838X_SMI_ACCESS_PHY_CTRL_3);
619 sw_w32_mask(0xffff, reg, RTL838X_SMI_ACCESS_PHY_CTRL_3);
620 /* mmd-access | write | cmd-start */
621 v = 1 << 1 | 1 << 2 | 1;
622 sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
623
624 if (rtl838x_smi_wait_op(10000))
625 goto timeout;
626
627 mutex_unlock(&smi_lock);
628 return 0;
629
630 timeout:
631 mutex_unlock(&smi_lock);
632 return -ETIMEDOUT;
633 }
634
635 void rtl8380_get_version(struct rtl838x_switch_priv *priv)
636 {
637 u32 rw_save, info_save;
638 u32 info;
639
640 rw_save = sw_r32(RTL838X_INT_RW_CTRL);
641 sw_w32(rw_save | 0x3, RTL838X_INT_RW_CTRL);
642
643 info_save = sw_r32(RTL838X_CHIP_INFO);
644 sw_w32(info_save | 0xA0000000, RTL838X_CHIP_INFO);
645
646 info = sw_r32(RTL838X_CHIP_INFO);
647 sw_w32(info_save, RTL838X_CHIP_INFO);
648 sw_w32(rw_save, RTL838X_INT_RW_CTRL);
649
650 if ((info & 0xFFFF) == 0x6275) {
651 if (((info >> 16) & 0x1F) == 0x1)
652 priv->version = RTL8380_VERSION_A;
653 else if (((info >> 16) & 0x1F) == 0x2)
654 priv->version = RTL8380_VERSION_B;
655 else
656 priv->version = RTL8380_VERSION_B;
657 } else {
658 priv->version = '-';
659 }
660 }
661
662 /*
663 * Applies the same hash algorithm as the one used currently by the ASIC
664 */
665 u32 rtl838x_hash(struct rtl838x_switch_priv *priv, u64 seed)
666 {
667 u32 h1, h2, h3, h;
668
669 if (sw_r32(priv->r->l2_ctrl_0) & 1) {
670 h1 = (seed >> 11) & 0x7ff;
671 h1 = ((h1 & 0x1f) << 6) | ((h1 >> 5) & 0x3f);
672
673 h2 = (seed >> 33) & 0x7ff;
674 h2 = ((h2 & 0x3f) << 5) | ((h2 >> 6) & 0x1f);
675
676 h3 = (seed >> 44) & 0x7ff;
677 h3 = ((h3 & 0x7f) << 4) | ((h3 >> 7) & 0xf);
678
679 h = h1 ^ h2 ^ h3 ^ ((seed >> 55) & 0x1ff);
680 h ^= ((seed >> 22) & 0x7ff) ^ (seed & 0x7ff);
681 } else {
682 h = ((seed >> 55) & 0x1ff) ^ ((seed >> 44) & 0x7ff)
683 ^ ((seed >> 33) & 0x7ff) ^ ((seed >> 22) & 0x7ff)
684 ^ ((seed >> 11) & 0x7ff) ^ (seed & 0x7ff);
685 }
686
687 return h;
688 }
689
690 void rtl838x_vlan_profile_dump(int profile)
691 {
692 u32 p;
693
694 if (profile < 0 || profile > 7)
695 return;
696
697 p = sw_r32(RTL838X_VLAN_PROFILE(profile));
698
699 pr_info("VLAN profile %d: L2 learning: %d, UNKN L2MC FLD PMSK %d, \
700 UNKN IPMC FLD PMSK %d, UNKN IPv6MC FLD PMSK: %d",
701 profile, p & 1, (p >> 1) & 0x1ff, (p >> 10) & 0x1ff, (p >> 19) & 0x1ff);
702 }
703
704 void rtl8380_sds_rst(int mac)
705 {
706 u32 offset = (mac == 24) ? 0 : 0x100;
707
708 sw_w32_mask(1 << 11, 0, RTL838X_SDS4_FIB_REG0 + offset);
709 sw_w32_mask(0x3, 0, RTL838X_SDS4_REG28 + offset);
710 sw_w32_mask(0x3, 0x3, RTL838X_SDS4_REG28 + offset);
711 sw_w32_mask(0, 0x1 << 6, RTL838X_SDS4_DUMMY0 + offset);
712 sw_w32_mask(0x1 << 6, 0, RTL838X_SDS4_DUMMY0 + offset);
713 pr_debug("SERDES reset: %d\n", mac);
714 }
715
716 int rtl8380_sds_power(int mac, int val)
717 {
718 u32 mode = (val == 1) ? 0x4 : 0x9;
719 u32 offset = (mac == 24) ? 5 : 0;
720
721 if ((mac != 24) && (mac != 26)) {
722 pr_err("%s: not a fibre port: %d\n", __func__, mac);
723 return -1;
724 }
725
726 sw_w32_mask(0x1f << offset, mode << offset, RTL838X_SDS_MODE_SEL);
727
728 rtl8380_sds_rst(mac);
729
730 return 0;
731 }