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