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