a80a6d89b29edf5699b7de8a252f03db59088c31
[openwrt/staging/dedeckeh.git] / target / linux / realtek / files-5.4 / drivers / net / dsa / rtl83xx / rtl930x.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 extern struct rtl83xx_soc_info soc_info;
8
9 void rtl930x_print_matrix(void)
10 {
11 int i;
12 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
13
14 for (i = 0; i < 29; i++) {
15 rtl_table_read(r, i);
16 pr_debug("> %08x\n", sw_r32(rtl_table_data(r, 0)));
17 }
18 rtl_table_release(r);
19 }
20
21 inline void rtl930x_exec_tbl0_cmd(u32 cmd)
22 {
23 sw_w32(cmd, RTL930X_TBL_ACCESS_CTRL_0);
24 do { } while (sw_r32(RTL930X_TBL_ACCESS_CTRL_0) & (1 << 17));
25 }
26
27 inline void rtl930x_exec_tbl1_cmd(u32 cmd)
28 {
29 sw_w32(cmd, RTL930X_TBL_ACCESS_CTRL_1);
30 do { } while (sw_r32(RTL930X_TBL_ACCESS_CTRL_1) & (1 << 17));
31 }
32
33 inline int rtl930x_tbl_access_data_0(int i)
34 {
35 return RTL930X_TBL_ACCESS_DATA_0(i);
36 }
37
38 static inline int rtl930x_l2_port_new_salrn(int p)
39 {
40 return RTL930X_L2_PORT_SALRN(p);
41 }
42
43 static inline int rtl930x_l2_port_new_sa_fwd(int p)
44 {
45 // TODO: The definition of the fields changed, because of the master-cpu in a stack
46 return RTL930X_L2_PORT_NEW_SA_FWD(p);
47 }
48
49 inline static int rtl930x_trk_mbr_ctr(int group)
50 {
51 return RTL930X_TRK_MBR_CTRL + (group << 2);
52 }
53
54 static void rtl930x_vlan_tables_read(u32 vlan, struct rtl838x_vlan_info *info)
55 {
56 u32 v, w;
57 // Read VLAN table (1) via register 0
58 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 1);
59
60 rtl_table_read(r, vlan);
61 v = sw_r32(rtl_table_data(r, 0));
62 w = sw_r32(rtl_table_data(r, 1));
63 pr_debug("VLAN_READ %d: %08x %08x\n", vlan, v, w);
64 rtl_table_release(r);
65
66 info->tagged_ports = v >> 3;
67 info->profile_id = (w >> 24) & 7;
68 info->hash_mc_fid = !!(w & BIT(27));
69 info->hash_uc_fid = !!(w & BIT(28));
70 info->fid = ((v & 0x7) << 3) | ((w >> 29) & 0x7);
71
72 // Read UNTAG table via table register 2
73 r = rtl_table_get(RTL9300_TBL_2, 0);
74 rtl_table_read(r, vlan);
75 v = sw_r32(rtl_table_data(r, 0));
76 rtl_table_release(r);
77
78 info->untagged_ports = v >> 3;
79 }
80
81 static void rtl930x_vlan_set_tagged(u32 vlan, struct rtl838x_vlan_info *info)
82 {
83 u32 v, w;
84 // Access VLAN table (1) via register 0
85 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 1);
86
87 v = info->tagged_ports << 3;
88 v |= ((u32)info->fid) >> 3;
89
90 w = ((u32)info->fid) << 29;
91 w |= info->hash_mc_fid ? BIT(27) : 0;
92 w |= info->hash_uc_fid ? BIT(28) : 0;
93 w |= info->profile_id << 24;
94
95 sw_w32(v, rtl_table_data(r, 0));
96 sw_w32(w, rtl_table_data(r, 1));
97
98 rtl_table_write(r, vlan);
99 rtl_table_release(r);
100 }
101
102 void rtl930x_vlan_profile_dump(int profile)
103 {
104 u32 p[5];
105
106 if (profile < 0 || profile > 7)
107 return;
108
109 p[0] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile));
110 p[1] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 4);
111 p[2] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 8) & 0x1FFFFFFF;
112 p[3] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 12) & 0x1FFFFFFF;
113 p[4] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 16) & 0x1FFFFFFF;
114
115 pr_info("VLAN %d: L2 learn: %d; Unknown MC PMasks: L2 %0x, IPv4 %0x, IPv6: %0x",
116 profile, p[0] & (3 << 21), p[2], p[3], p[4]);
117 pr_info(" Routing enabled: IPv4 UC %c, IPv6 UC %c, IPv4 MC %c, IPv6 MC %c\n",
118 p[0] & BIT(17) ? 'y' : 'n', p[0] & BIT(16) ? 'y' : 'n',
119 p[0] & BIT(13) ? 'y' : 'n', p[0] & BIT(12) ? 'y' : 'n');
120 pr_info(" Bridge enabled: IPv4 MC %c, IPv6 MC %c,\n",
121 p[0] & BIT(15) ? 'y' : 'n', p[0] & BIT(14) ? 'y' : 'n');
122 pr_info("VLAN profile %d: raw %08x %08x %08x %08x %08x\n",
123 profile, p[0], p[1], p[2], p[3], p[4]);
124 }
125
126 static void rtl930x_vlan_set_untagged(u32 vlan, u64 portmask)
127 {
128 struct table_reg *r = rtl_table_get(RTL9300_TBL_2, 0);
129
130 sw_w32(portmask << 3, rtl_table_data(r, 0));
131 rtl_table_write(r, vlan);
132 rtl_table_release(r);
133 }
134
135 /* Sets the L2 forwarding to be based on either the inner VLAN tag or the outer
136 */
137 static void rtl930x_vlan_fwd_on_inner(int port, bool is_set)
138 {
139 // Always set all tag modes to fwd based on either inner or outer tag
140 if (is_set)
141 sw_w32_mask(0, 0xf, RTL930X_VLAN_PORT_FWD + (port << 2));
142 else
143 sw_w32_mask(0xf, 0, RTL930X_VLAN_PORT_FWD + (port << 2));
144 }
145
146 static void rtl930x_vlan_profile_setup(int profile)
147 {
148 u32 p[5];
149
150 pr_info("In %s\n", __func__);
151 p[0] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile));
152 p[1] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 4);
153
154 // Enable routing of Ipv4/6 Unicast and IPv4/6 Multicast traffic
155 p[0] |= BIT(17) | BIT(16) | BIT(13) | BIT(12);
156 p[2] = 0x0fffffff; // L2 unknwon MC flooding portmask: all but the CPU-port
157 p[3] = 0x0fffffff; // IPv4 unknwon MC flooding portmask
158 p[4] = 0x0fffffff; // IPv6 unknwon MC flooding portmask
159
160 sw_w32(p[0], RTL930X_VLAN_PROFILE_SET(profile));
161 sw_w32(p[1], RTL930X_VLAN_PROFILE_SET(profile) + 4);
162 sw_w32(p[2], RTL930X_VLAN_PROFILE_SET(profile) + 8);
163 sw_w32(p[3], RTL930X_VLAN_PROFILE_SET(profile) + 12);
164 sw_w32(p[4], RTL930X_VLAN_PROFILE_SET(profile) + 16);
165 pr_info("Leaving %s\n", __func__);
166 }
167
168 static void rtl930x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
169 {
170 int i;
171 u32 cmd = 1 << 17 /* Execute cmd */
172 | 0 << 16 /* Read */
173 | 4 << 12 /* Table type 0b10 */
174 | (msti & 0xfff);
175 priv->r->exec_tbl0_cmd(cmd);
176
177 for (i = 0; i < 2; i++)
178 port_state[i] = sw_r32(RTL930X_TBL_ACCESS_DATA_0(i));
179 pr_debug("MSTI: %d STATE: %08x, %08x\n", msti, port_state[0], port_state[1]);
180 }
181
182 static void rtl930x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
183 {
184 int i;
185 u32 cmd = 1 << 17 /* Execute cmd */
186 | 1 << 16 /* Write */
187 | 4 << 12 /* Table type 4 */
188 | (msti & 0xfff);
189
190 for (i = 0; i < 2; i++)
191 sw_w32(port_state[i], RTL930X_TBL_ACCESS_DATA_0(i));
192 priv->r->exec_tbl0_cmd(cmd);
193 }
194
195 static inline int rtl930x_mac_force_mode_ctrl(int p)
196 {
197 return RTL930X_MAC_FORCE_MODE_CTRL + (p << 2);
198 }
199
200 static inline int rtl930x_mac_port_ctrl(int p)
201 {
202 return RTL930X_MAC_L2_PORT_CTRL(p);
203 }
204
205 static inline int rtl930x_mac_link_spd_sts(int p)
206 {
207 return RTL930X_MAC_LINK_SPD_STS(p);
208 }
209
210 static void rtl930x_fill_l2_entry(u32 r[], struct rtl838x_l2_entry *e)
211 {
212 e->valid = !!(r[2] & BIT(31));
213 if (!e->valid)
214 return;
215
216 // TODO: Is there not a function to copy directly MAC memory?
217 e->mac[0] = (r[0] >> 24);
218 e->mac[1] = (r[0] >> 16);
219 e->mac[2] = (r[0] >> 8);
220 e->mac[3] = r[0];
221 e->mac[4] = (r[1] >> 24);
222 e->mac[5] = (r[1] >> 16);
223
224 /* Is it a unicast entry? check multicast bit */
225 if (!(e->mac[0] & 1)) {
226 e->type = L2_UNICAST;
227 e->is_static = !!(r[2] & BIT(14));
228 e->vid = r[2] & 0xfff;
229 e->rvid = r[1] & 0xfff;
230 e->port = (r[2] >> 20) & 0x3ff;
231 // Check for trunk port
232 if (r[2] & BIT(30)) {
233 e->stackDev = (e->port >> 9) & 1;
234 e->trunk = e->port & 0x3f;
235 } else {
236 e->stackDev = (e->port >> 6) & 0xf;
237 e->port = e->port & 0x3f;
238 }
239
240 e->block_da = !!(r[2] & BIT(15));
241 e->block_sa = !!(r[2] & BIT(16));
242 e->suspended = !!(r[2] & BIT(13));
243 e->next_hop = !!(r[2] & BIT(12));
244 e->age = (r[2] >> 17) & 3;
245 e->valid = true;
246
247 } else {
248 e->valid = true;
249 e->type = L2_MULTICAST;
250 e->mc_portmask_index = (r[2]>>6) & 0xfff;
251 }
252 }
253
254 static u64 rtl930x_read_l2_entry_using_hash(u32 hash, u32 position, struct rtl838x_l2_entry *e)
255 {
256 u64 entry;
257 u32 r[3];
258 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 0);
259 u32 idx = (0 << 14) | (hash << 2) | position;
260 int i;
261
262 rtl_table_read(q, idx);
263 for (i= 0; i < 3; i++)
264 r[i] = sw_r32(rtl_table_data(q, i));
265
266 rtl_table_release(q);
267
268 rtl930x_fill_l2_entry(r, e);
269 if (!e->valid)
270 return 0;
271
272 entry = ((u64)r[0] << 32) | (r[1] & 0xffff0000) | e->vid;
273 return entry;
274 }
275
276 static u64 rtl930x_read_cam(int idx, struct rtl838x_l2_entry *e)
277 {
278 u64 entry;
279 u32 r[3];
280 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 1);
281 int i;
282
283 rtl_table_read(q, idx);
284 for (i= 0; i < 3; i++)
285 r[i] = sw_r32(rtl_table_data(q, i));
286
287 rtl_table_release(q);
288
289 rtl930x_fill_l2_entry(r, e);
290 if (!e->valid)
291 return 0;
292
293 entry = ((u64)r[0] << 32) | (r[1] & 0xffff0000) | e->vid;
294
295 return entry;
296 }
297
298 static u64 rtl930x_read_mcast_pmask(int idx)
299 {
300 u32 portmask;
301 // Read MC_PORTMASK (2) via register RTL9300_TBL_L2
302 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 2);
303
304 rtl_table_read(q, idx);
305 portmask = sw_r32(rtl_table_data(q, 0));
306 portmask >>= 3;
307 rtl_table_release(q);
308
309 pr_debug("%s: Index idx %d has portmask %08x\n", __func__, idx, portmask);
310 return portmask;
311 }
312
313 static void rtl930x_write_mcast_pmask(int idx, u64 portmask)
314 {
315 u32 pm = portmask;
316
317 // Access MC_PORTMASK (2) via register RTL9300_TBL_L2
318 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 2);
319
320 pr_debug("%s: Index idx %d has portmask %08x\n", __func__, idx, pm);
321 pm <<= 3;
322 sw_w32(pm, rtl_table_data(q, 0));
323 rtl_table_write(q, idx);
324 rtl_table_release(q);
325 }
326
327 u64 rtl930x_traffic_get(int source)
328 {
329 u32 v;
330 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
331
332 rtl_table_read(r, source);
333 v = sw_r32(rtl_table_data(r, 0));
334 rtl_table_release(r);
335 return v >> 3;
336 }
337
338 /*
339 * Enable traffic between a source port and a destination port matrix
340 */
341 void rtl930x_traffic_set(int source, u64 dest_matrix)
342 {
343 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
344
345 sw_w32((dest_matrix << 3), rtl_table_data(r, 0));
346 rtl_table_write(r, source);
347 rtl_table_release(r);
348 }
349
350 void rtl930x_traffic_enable(int source, int dest)
351 {
352 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
353 rtl_table_read(r, source);
354 sw_w32_mask(0, BIT(dest + 3), rtl_table_data(r, 0));
355 rtl_table_write(r, source);
356 rtl_table_release(r);
357 }
358
359 void rtl930x_traffic_disable(int source, int dest)
360 {
361 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
362 rtl_table_read(r, source);
363 sw_w32_mask(BIT(dest + 3), 0, rtl_table_data(r, 0));
364 rtl_table_write(r, source);
365 rtl_table_release(r);
366 }
367
368 void rtl9300_dump_debug(void)
369 {
370 int i;
371 u16 r = RTL930X_STAT_PRVTE_DROP_COUNTER0;
372
373 for (i = 0; i < 10; i ++) {
374 pr_info("# %d %08x %08x %08x %08x %08x %08x %08x %08x\n", i * 8,
375 sw_r32(r), sw_r32(r + 4), sw_r32(r + 8), sw_r32(r + 12),
376 sw_r32(r + 16), sw_r32(r + 20), sw_r32(r + 24), sw_r32(r + 28));
377 r += 32;
378 }
379 pr_info("# %08x %08x %08x %08x %08x\n",
380 sw_r32(r), sw_r32(r + 4), sw_r32(r + 8), sw_r32(r + 12), sw_r32(r + 16));
381 rtl930x_print_matrix();
382 pr_info("RTL930X_L2_PORT_SABLK_CTRL: %08x, RTL930X_L2_PORT_DABLK_CTRL %08x\n",
383 sw_r32(RTL930X_L2_PORT_SABLK_CTRL), sw_r32(RTL930X_L2_PORT_DABLK_CTRL)
384
385 );
386 }
387
388 irqreturn_t rtl930x_switch_irq(int irq, void *dev_id)
389 {
390 struct dsa_switch *ds = dev_id;
391 u32 status = sw_r32(RTL930X_ISR_GLB);
392 u32 ports = sw_r32(RTL930X_ISR_PORT_LINK_STS_CHG);
393 u32 link;
394 int i;
395
396 /* Clear status */
397 sw_w32(ports, RTL930X_ISR_PORT_LINK_STS_CHG);
398 pr_info("RTL9300 Link change: status: %x, ports %x\n", status, ports);
399
400 rtl9300_dump_debug();
401
402 for (i = 0; i < 28; i++) {
403 if (ports & BIT(i)) {
404 /* Read the register twice because of issues with latency at least
405 * with the external RTL8226 PHY on the XGS1210 */
406 link = sw_r32(RTL930X_MAC_LINK_STS);
407 link = sw_r32(RTL930X_MAC_LINK_STS);
408 if (link & BIT(i))
409 dsa_port_phylink_mac_change(ds, i, true);
410 else
411 dsa_port_phylink_mac_change(ds, i, false);
412 }
413 }
414
415 return IRQ_HANDLED;
416 }
417
418 int rtl9300_sds_power(int mac, int val)
419 {
420 int sds_num;
421 u32 mode;
422
423 // TODO: these numbers are hard-coded for the Zyxel XGS1210 12 Switch
424 pr_info("SerDes: %s %d\n", __func__, mac);
425 switch (mac) {
426 case 24:
427 sds_num = 6;
428 mode = 0x12; // HISGMII
429 break;
430 case 25:
431 sds_num = 7;
432 mode = 0x12; // HISGMII
433 break;
434 case 26:
435 sds_num = 8;
436 mode = 0x1b; // 10GR/1000BX auto
437 break;
438 case 27:
439 sds_num = 9;
440 mode = 0x1b; // 10GR/1000BX auto
441 break;
442 default:
443 return -1;
444 }
445 if (!val)
446 mode = 0x1f; // OFF
447
448 rtl9300_sds_rst(sds_num, mode);
449
450 return 0;
451 }
452
453 int rtl930x_write_phy(u32 port, u32 page, u32 reg, u32 val)
454 {
455 u32 v;
456 int err = 0;
457
458 pr_debug("%s: port %d, page: %d, reg: %x, val: %x\n", __func__, port, page, reg, val);
459
460 if (port > 63 || page > 4095 || reg > 31)
461 return -ENOTSUPP;
462
463 val &= 0xffff;
464 mutex_lock(&smi_lock);
465
466 sw_w32(BIT(port), RTL930X_SMI_ACCESS_PHY_CTRL_0);
467 sw_w32_mask(0xffff << 16, val << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2);
468 v = reg << 20 | page << 3 | 0x1f << 15 | BIT(2) | BIT(0);
469 sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1);
470
471 do {
472 v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1);
473 } while (v & 0x1);
474
475 if (v & 0x2)
476 err = -EIO;
477
478 mutex_unlock(&smi_lock);
479
480 return err;
481 }
482
483 int rtl930x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
484 {
485 u32 v;
486 int err = 0;
487
488 // pr_info("In %s\n", __func__);
489 if (port > 63 || page > 4095 || reg > 31)
490 return -ENOTSUPP;
491
492 mutex_lock(&smi_lock);
493
494 sw_w32_mask(0xffff << 16, port << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2);
495 v = reg << 20 | page << 3 | 0x1f << 15 | 1;
496 sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1);
497
498 do {
499 v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1);
500 } while ( v & 0x1);
501
502 if (v & BIT(25)) {
503 pr_debug("Error reading phy %d, register %d\n", port, reg);
504 err = -EIO;
505 }
506 *val = (sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_2) & 0xffff);
507
508 pr_debug("%s: port %d, page: %d, reg: %x, val: %x\n", __func__, port, page, reg, *val);
509
510 mutex_unlock(&smi_lock);
511
512 return err;
513 }
514
515 /*
516 * Write to an mmd register of the PHY
517 */
518 int rtl930x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val)
519 {
520 int err = 0;
521 u32 v;
522
523 mutex_lock(&smi_lock);
524
525 // Set PHY to access
526 sw_w32(BIT(port), RTL930X_SMI_ACCESS_PHY_CTRL_0);
527
528 // Set data to write
529 sw_w32_mask(0xffff << 16, val << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2);
530
531 // Set MMD device number and register to write to
532 sw_w32(devnum << 16 | (regnum & 0xffff), RTL930X_SMI_ACCESS_PHY_CTRL_3);
533
534 v = BIT(2)| BIT(1)| BIT(0); // WRITE | MMD-access | EXEC
535 sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1);
536
537 do {
538 v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1);
539 } while ( v & BIT(0));
540
541 pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, val, err);
542 mutex_unlock(&smi_lock);
543 return err;
544 }
545
546 /*
547 * Read an mmd register of the PHY
548 */
549 int rtl930x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val)
550 {
551 int err = 0;
552 u32 v;
553
554 mutex_lock(&smi_lock);
555
556 // Set PHY to access
557 sw_w32_mask(0xffff << 16, port << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2);
558
559 // Set MMD device number and register to write to
560 sw_w32(devnum << 16 | (regnum & 0xffff), RTL930X_SMI_ACCESS_PHY_CTRL_3);
561
562 v = BIT(1)| BIT(0); // MMD-access | EXEC
563 sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1);
564
565 do {
566 v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1);
567 } while ( v & 0x1);
568 // There is no error-checking via BIT 25 of v, as it does not seem to be set correctly
569 *val = (sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_2) & 0xffff);
570 pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, *val, err);
571
572 mutex_unlock(&smi_lock);
573
574 return err;
575 }
576
577
578 /*
579 * Calculate both the block 0 and the block 1 hash, and return in
580 * lower and higher word of the return value since only 12 bit of
581 * the hash are significant
582 */
583 u32 rtl930x_hash(struct rtl838x_switch_priv *priv, u64 seed)
584 {
585 u32 k0, k1, h1, h2, h;
586
587 k0 = (u32) (((seed >> 55) & 0x1f) ^ ((seed >> 44) & 0x7ff)
588 ^ ((seed >> 33) & 0x7ff) ^ ((seed >> 22) & 0x7ff)
589 ^ ((seed >> 11) & 0x7ff) ^ (seed & 0x7ff));
590
591 h1 = (seed >> 11) & 0x7ff;
592 h1 = ((h1 & 0x1f) << 6) | ((h1 >> 5) & 0x3f);
593
594 h2 = (seed >> 33) & 0x7ff;
595 h2 = ((h2 & 0x3f) << 5)| ((h2 >> 6) & 0x3f);
596
597 k1 = (u32) (((seed << 55) & 0x1f) ^ ((seed >> 44) & 0x7ff) ^ h2
598 ^ ((seed >> 22) & 0x7ff) ^ h1
599 ^ (seed & 0x7ff));
600
601 // Algorithm choice for block 0
602 if (sw_r32(RTL930X_L2_CTRL) & BIT(0))
603 h = k1;
604 else
605 h = k0;
606
607 /* Algorithm choice for block 1
608 * Since k0 and k1 are < 2048, adding 2048 will offset the hash into the second
609 * half of hash-space
610 * 2048 is in fact the hash-table size 16384 divided by 4 hashes per bucket
611 * divided by 2 to divide the hash space in 2
612 */
613 if (sw_r32(RTL930X_L2_CTRL) & BIT(1))
614 h |= (k1 + 2048) << 16;
615 else
616 h |= (k0 + 2048) << 16;
617
618 return h;
619 }
620 /*
621 * Enables or disables the EEE/EEEP capability of a port
622 */
623 void rtl930x_port_eee_set(struct rtl838x_switch_priv *priv, int port, bool enable)
624 {
625 u32 v;
626
627 // This works only for Ethernet ports, and on the RTL930X, ports from 26 are SFP
628 if (port >= 26)
629 return;
630
631 pr_debug("In %s: setting port %d to %d\n", __func__, port, enable);
632 v = enable ? 0x3f : 0x0;
633
634 // Set EEE/EEEP state for 100, 500, 1000MBit and 2.5, 5 and 10GBit
635 sw_w32_mask(0, v << 10, rtl930x_mac_force_mode_ctrl(port));
636
637 // Set TX/RX EEE state
638 v = enable ? 0x3 : 0x0;
639 sw_w32(v, RTL930X_EEE_CTRL(port));
640
641 priv->ports[port].eee_enabled = enable;
642 }
643
644 /*
645 * Get EEE own capabilities and negotiation result
646 */
647 int rtl930x_eee_port_ability(struct rtl838x_switch_priv *priv, struct ethtool_eee *e, int port)
648 {
649 u32 link, a;
650
651 if (port >= 26)
652 return -ENOTSUPP;
653
654 pr_info("In %s, port %d\n", __func__, port);
655 link = sw_r32(RTL930X_MAC_LINK_STS);
656 link = sw_r32(RTL930X_MAC_LINK_STS);
657 if (!(link & BIT(port)))
658 return 0;
659
660 pr_info("Setting advertised\n");
661 if (sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(10))
662 e->advertised |= ADVERTISED_100baseT_Full;
663
664 if (sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(12))
665 e->advertised |= ADVERTISED_1000baseT_Full;
666
667 if (priv->ports[port].is2G5 && sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(13)) {
668 pr_info("ADVERTISING 2.5G EEE\n");
669 e->advertised |= ADVERTISED_2500baseX_Full;
670 }
671
672 if (priv->ports[port].is10G && sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(15))
673 e->advertised |= ADVERTISED_10000baseT_Full;
674
675 a = sw_r32(RTL930X_MAC_EEE_ABLTY);
676 a = sw_r32(RTL930X_MAC_EEE_ABLTY);
677 pr_info("Link partner: %08x\n", a);
678 if (a & BIT(port)) {
679 e->lp_advertised = ADVERTISED_100baseT_Full;
680 e->lp_advertised |= ADVERTISED_1000baseT_Full;
681 if (priv->ports[port].is2G5)
682 e->lp_advertised |= ADVERTISED_2500baseX_Full;
683 if (priv->ports[port].is10G)
684 e->lp_advertised |= ADVERTISED_10000baseT_Full;
685 }
686
687 // Read 2x to clear latched state
688 a = sw_r32(RTL930X_EEEP_PORT_CTRL(port));
689 a = sw_r32(RTL930X_EEEP_PORT_CTRL(port));
690 pr_info("%s RTL930X_EEEP_PORT_CTRL: %08x\n", __func__, a);
691
692 return 0;
693 }
694
695 static void rtl930x_init_eee(struct rtl838x_switch_priv *priv, bool enable)
696 {
697 int i;
698
699 pr_info("Setting up EEE, state: %d\n", enable);
700
701 // Setup EEE on all ports
702 for (i = 0; i < priv->cpu_port; i++) {
703 if (priv->ports[i].phy)
704 rtl930x_port_eee_set(priv, i, enable);
705 }
706
707 priv->eee_enabled = enable;
708 }
709
710 const struct rtl838x_reg rtl930x_reg = {
711 .mask_port_reg_be = rtl838x_mask_port_reg,
712 .set_port_reg_be = rtl838x_set_port_reg,
713 .get_port_reg_be = rtl838x_get_port_reg,
714 .mask_port_reg_le = rtl838x_mask_port_reg,
715 .set_port_reg_le = rtl838x_set_port_reg,
716 .get_port_reg_le = rtl838x_get_port_reg,
717 .stat_port_rst = RTL930X_STAT_PORT_RST,
718 .stat_rst = RTL930X_STAT_RST,
719 .stat_port_std_mib = RTL930X_STAT_PORT_MIB_CNTR,
720 .traffic_enable = rtl930x_traffic_enable,
721 .traffic_disable = rtl930x_traffic_disable,
722 .traffic_get = rtl930x_traffic_get,
723 .traffic_set = rtl930x_traffic_set,
724 .l2_ctrl_0 = RTL930X_L2_CTRL,
725 .l2_ctrl_1 = RTL930X_L2_AGE_CTRL,
726 .l2_port_aging_out = RTL930X_L2_PORT_AGE_CTRL,
727 .smi_poll_ctrl = RTL930X_SMI_POLL_CTRL, // TODO: Difference to RTL9300_SMI_PRVTE_POLLING_CTRL
728 .l2_tbl_flush_ctrl = RTL930X_L2_TBL_FLUSH_CTRL,
729 .exec_tbl0_cmd = rtl930x_exec_tbl0_cmd,
730 .exec_tbl1_cmd = rtl930x_exec_tbl1_cmd,
731 .tbl_access_data_0 = rtl930x_tbl_access_data_0,
732 .isr_glb_src = RTL930X_ISR_GLB,
733 .isr_port_link_sts_chg = RTL930X_ISR_PORT_LINK_STS_CHG,
734 .imr_port_link_sts_chg = RTL930X_IMR_PORT_LINK_STS_CHG,
735 .imr_glb = RTL930X_IMR_GLB,
736 .vlan_tables_read = rtl930x_vlan_tables_read,
737 .vlan_set_tagged = rtl930x_vlan_set_tagged,
738 .vlan_set_untagged = rtl930x_vlan_set_untagged,
739 .vlan_profile_dump = rtl930x_vlan_profile_dump,
740 .vlan_profile_setup = rtl930x_vlan_profile_setup,
741 .vlan_fwd_on_inner = rtl930x_vlan_fwd_on_inner,
742 .stp_get = rtl930x_stp_get,
743 .stp_set = rtl930x_stp_set,
744 .mac_force_mode_ctrl = rtl930x_mac_force_mode_ctrl,
745 .mac_port_ctrl = rtl930x_mac_port_ctrl,
746 .l2_port_new_salrn = rtl930x_l2_port_new_salrn,
747 .l2_port_new_sa_fwd = rtl930x_l2_port_new_sa_fwd,
748 .mir_ctrl = RTL930X_MIR_CTRL,
749 .mir_dpm = RTL930X_MIR_DPM_CTRL,
750 .mir_spm = RTL930X_MIR_SPM_CTRL,
751 .mac_link_sts = RTL930X_MAC_LINK_STS,
752 .mac_link_dup_sts = RTL930X_MAC_LINK_DUP_STS,
753 .mac_link_spd_sts = rtl930x_mac_link_spd_sts,
754 .mac_rx_pause_sts = RTL930X_MAC_RX_PAUSE_STS,
755 .mac_tx_pause_sts = RTL930X_MAC_TX_PAUSE_STS,
756 .read_l2_entry_using_hash = rtl930x_read_l2_entry_using_hash,
757 .read_cam = rtl930x_read_cam,
758 .vlan_port_egr_filter = RTL930X_VLAN_PORT_EGR_FLTR,
759 .vlan_port_igr_filter = RTL930X_VLAN_PORT_IGR_FLTR(0),
760 .vlan_port_pb = RTL930X_VLAN_PORT_PB_VLAN,
761 .vlan_port_tag_sts_ctrl = RTL930X_VLAN_PORT_TAG_STS_CTRL,
762 .trk_mbr_ctr = rtl930x_trk_mbr_ctr,
763 .rma_bpdu_fld_pmask = RTL930X_RMA_BPDU_FLD_PMSK,
764 .init_eee = rtl930x_init_eee,
765 .port_eee_set = rtl930x_port_eee_set,
766 .eee_port_ability = rtl930x_eee_port_ability,
767 .read_mcast_pmask = rtl930x_read_mcast_pmask,
768 .write_mcast_pmask = rtl930x_write_mcast_pmask,
769 };