820c78165a3c8677697fb25349cc10c4aff91c3f
[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 u64 rtl930x_l2_hash_seed(u64 mac, u32 vid)
211 {
212 u64 v = vid;
213
214 v <<= 48;
215 v |= mac;
216
217 return v;
218 }
219
220 /*
221 * Calculate both the block 0 and the block 1 hash by applyingthe same hash
222 * algorithm as the one used currently by the ASIC to the seed, and return
223 * both hashes in the lower and higher word of the return value since only 12 bit of
224 * the hash are significant
225 */
226 static u32 rtl930x_l2_hash_key(struct rtl838x_switch_priv *priv, u64 seed)
227 {
228 u32 k0, k1, h1, h2, h;
229
230 k0 = (u32) (((seed >> 55) & 0x1f) ^ ((seed >> 44) & 0x7ff)
231 ^ ((seed >> 33) & 0x7ff) ^ ((seed >> 22) & 0x7ff)
232 ^ ((seed >> 11) & 0x7ff) ^ (seed & 0x7ff));
233
234 h1 = (seed >> 11) & 0x7ff;
235 h1 = ((h1 & 0x1f) << 6) | ((h1 >> 5) & 0x3f);
236
237 h2 = (seed >> 33) & 0x7ff;
238 h2 = ((h2 & 0x3f) << 5)| ((h2 >> 6) & 0x3f);
239
240 k1 = (u32) (((seed << 55) & 0x1f) ^ ((seed >> 44) & 0x7ff) ^ h2
241 ^ ((seed >> 22) & 0x7ff) ^ h1
242 ^ (seed & 0x7ff));
243
244 // Algorithm choice for block 0
245 if (sw_r32(RTL930X_L2_CTRL) & BIT(0))
246 h = k1;
247 else
248 h = k0;
249
250 /* Algorithm choice for block 1
251 * Since k0 and k1 are < 2048, adding 2048 will offset the hash into the second
252 * half of hash-space
253 * 2048 is in fact the hash-table size 16384 divided by 4 hashes per bucket
254 * divided by 2 to divide the hash space in 2
255 */
256 if (sw_r32(RTL930X_L2_CTRL) & BIT(1))
257 h |= (k1 + 2048) << 16;
258 else
259 h |= (k0 + 2048) << 16;
260
261 return h;
262 }
263
264 /*
265 * Fills an L2 entry structure from the SoC registers
266 */
267 static void rtl930x_fill_l2_entry(u32 r[], struct rtl838x_l2_entry *e)
268 {
269 pr_debug("In %s valid?\n", __func__);
270 e->valid = !!(r[2] & BIT(31));
271 if (!e->valid)
272 return;
273
274 pr_debug("In %s is valid\n", __func__);
275 e->is_ip_mc = false;
276 e->is_ipv6_mc = false;
277
278 // TODO: Is there not a function to copy directly MAC memory?
279 e->mac[0] = (r[0] >> 24);
280 e->mac[1] = (r[0] >> 16);
281 e->mac[2] = (r[0] >> 8);
282 e->mac[3] = r[0];
283 e->mac[4] = (r[1] >> 24);
284 e->mac[5] = (r[1] >> 16);
285
286 e->next_hop = !!(r[2] & BIT(12));
287 e->rvid = r[1] & 0xfff;
288
289 /* Is it a unicast entry? check multicast bit */
290 if (!(e->mac[0] & 1)) {
291 e->type = L2_UNICAST;
292 e->is_static = !!(r[2] & BIT(14));
293 e->port = (r[2] >> 20) & 0x3ff;
294 // Check for trunk port
295 if (r[2] & BIT(30)) {
296 e->is_trunk = true;
297 e->stack_dev = (e->port >> 9) & 1;
298 e->trunk = e->port & 0x3f;
299 } else {
300 e->is_trunk = false;
301 e->stack_dev = (e->port >> 6) & 0xf;
302 e->port = e->port & 0x3f;
303 }
304
305 e->block_da = !!(r[2] & BIT(15));
306 e->block_sa = !!(r[2] & BIT(16));
307 e->suspended = !!(r[2] & BIT(13));
308 e->age = (r[2] >> 17) & 3;
309 e->valid = true;
310 // the UC_VID field in hardware is used for the VID or for the route id
311 if (e->next_hop) {
312 e->nh_route_id = r[2] & 0xfff;
313 e->vid = 0;
314 } else {
315 e->vid = r[2] & 0xfff;
316 e->nh_route_id = 0;
317 }
318 } else {
319 e->valid = true;
320 e->type = L2_MULTICAST;
321 e->mc_portmask_index = (r[2] >> 16) & 0x3ff;
322 }
323 }
324
325 /*
326 * Fills the 3 SoC table registers r[] with the information of in the rtl838x_l2_entry
327 */
328 static void rtl930x_fill_l2_row(u32 r[], struct rtl838x_l2_entry *e)
329 {
330 u32 port;
331
332 if (!e->valid) {
333 r[0] = r[1] = r[2] = 0;
334 return;
335 }
336
337 r[2] = BIT(31); // Set valid bit
338
339 r[0] = ((u32)e->mac[0]) << 24 | ((u32)e->mac[1]) << 16
340 | ((u32)e->mac[2]) << 8 | ((u32)e->mac[3]);
341 r[1] = ((u32)e->mac[4]) << 24 | ((u32)e->mac[5]) << 16;
342
343 r[2] |= e->next_hop ? BIT(12) : 0;
344
345 if (e->type == L2_UNICAST) {
346 r[2] |= e->is_static ? BIT(14) : 0;
347 r[1] |= e->rvid & 0xfff;
348 r[2] |= (e->port & 0x3ff) << 20;
349 if (e->is_trunk) {
350 r[2] |= BIT(30);
351 port = e->stack_dev << 9 | (e->port & 0x3f);
352 } else {
353 port = (e->stack_dev & 0xf) << 6;
354 port |= e->port & 0x3f;
355 }
356 r[2] |= port << 20;
357 r[2] |= e->block_da ? BIT(15) : 0;
358 r[2] |= e->block_sa ? BIT(17) : 0;
359 r[2] |= e->suspended ? BIT(13) : 0;
360 r[2] |= (e->age & 0x3) << 17;
361 // the UC_VID field in hardware is used for the VID or for the route id
362 if (e->next_hop)
363 r[2] |= e->nh_route_id & 0xfff;
364 else
365 r[2] |= e->vid & 0xfff;
366 } else { // L2_MULTICAST
367 r[2] |= (e->mc_portmask_index & 0x3ff) << 16;
368 r[2] |= e->mc_mac_index & 0x7ff;
369 }
370 }
371
372 /*
373 * Read an L2 UC or MC entry out of a hash bucket of the L2 forwarding table
374 * hash is the id of the bucket and pos is the position of the entry in that bucket
375 * The data read from the SoC is filled into rtl838x_l2_entry
376 */
377 static u64 rtl930x_read_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e)
378 {
379 u32 r[3];
380 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 0);
381 u32 idx;
382 int i;
383 u64 mac;
384 u64 seed;
385
386 pr_debug("%s: hash %08x, pos: %d\n", __func__, hash, pos);
387
388 /* On the RTL93xx, 2 different hash algorithms are used making it a total of
389 * 8 buckets that need to be searched, 4 for each hash-half
390 * Use second hash space when bucket is between 4 and 8 */
391 if (pos >= 4) {
392 pos -= 4;
393 hash >>= 16;
394 } else {
395 hash &= 0xffff;
396 }
397
398 idx = (0 << 14) | (hash << 2) | pos; // Search SRAM, with hash and at pos in bucket
399 pr_debug("%s: NOW hash %08x, pos: %d\n", __func__, hash, pos);
400
401 rtl_table_read(q, idx);
402 for (i = 0; i < 3; i++)
403 r[i] = sw_r32(rtl_table_data(q, i));
404
405 rtl_table_release(q);
406
407 rtl930x_fill_l2_entry(r, e);
408
409 pr_debug("%s: valid: %d, nh: %d\n", __func__, e->valid, e->next_hop);
410 if (!e->valid)
411 return 0;
412
413 mac = ((u64)e->mac[0]) << 40 | ((u64)e->mac[1]) << 32 | ((u64)e->mac[2]) << 24
414 | ((u64)e->mac[3]) << 16 | ((u64)e->mac[4]) << 8 | ((u64)e->mac[5]);
415
416 seed = rtl930x_l2_hash_seed(mac, e->rvid);
417 pr_debug("%s: mac %016llx, seed %016llx\n", __func__, mac, seed);
418 // return vid with concatenated mac as unique id
419 return seed;
420 }
421
422 static void rtl930x_write_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e)
423 {
424 u32 r[3];
425 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 0);
426 u32 idx = (0 << 14) | (hash << 2) | pos; // Access SRAM, with hash and at pos in bucket
427 int i;
428
429 pr_info("%s: hash %d, pos %d\n", __func__, hash, pos);
430 pr_info("%s: index %d -> mac %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, idx,
431 e->mac[0], e->mac[1], e->mac[2], e->mac[3],e->mac[4],e->mac[5]);
432
433 rtl930x_fill_l2_row(r, e);
434
435 for (i= 0; i < 3; i++)
436 sw_w32(r[i], rtl_table_data(q, i));
437
438 rtl_table_write(q, idx);
439 rtl_table_release(q);
440 }
441
442 static u64 rtl930x_read_cam(int idx, struct rtl838x_l2_entry *e)
443 {
444 u32 r[3];
445 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 1);
446 int i;
447
448 rtl_table_read(q, idx);
449 for (i= 0; i < 3; i++)
450 r[i] = sw_r32(rtl_table_data(q, i));
451
452 rtl_table_release(q);
453
454 rtl930x_fill_l2_entry(r, e);
455 if (!e->valid)
456 return 0;
457
458 // return mac with concatenated vid as unique id
459 return ((u64)r[0] << 28) | ((r[1] & 0xffff0000) >> 4) | e->vid;
460 }
461
462 static void rtl930x_write_cam(int idx, struct rtl838x_l2_entry *e)
463 {
464 u32 r[3];
465 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 1); // Access L2 Table 1
466 int i;
467
468 rtl930x_fill_l2_row(r, e);
469
470 for (i= 0; i < 3; i++)
471 sw_w32(r[i], rtl_table_data(q, i));
472
473 rtl_table_write(q, idx);
474 rtl_table_release(q);
475 }
476
477 static void dump_l2_entry(struct rtl838x_l2_entry *e)
478 {
479 pr_info("MAC: %02x:%02x:%02x:%02x:%02x:%02x vid: %d, rvid: %d, port: %d, valid: %d\n",
480 e->mac[0], e->mac[1], e->mac[2], e->mac[3], e->mac[4], e->mac[5],
481 e->vid, e->rvid, e->port, e->valid);
482 pr_info("Type: %d, is_static: %d, is_ip_mc: %d, is_ipv6_mc: %d, block_da: %d\n",
483 e->type, e->is_static, e->is_ip_mc, e->is_ipv6_mc, e->block_da);
484 pr_info(" block_sa: %d, suspended: %d, next_hop: %d, age: %d, is_trunk: %d, trunk: %d\n",
485 e->block_sa, e->suspended, e->next_hop, e->age, e->is_trunk, e->trunk);
486 if (e->is_ip_mc || e->is_ipv6_mc)
487 pr_info(" mc_portmask_index: %d, mc_gip: %d, mc_sip: %d\n",
488 e->mc_portmask_index, e->mc_gip, e->mc_sip);
489 pr_info(" stac_dev: %d, nh_route_id: %d, port: %d, dev_id\n",
490 e->stack_dev, e->nh_route_id, e->port);
491 }
492
493 /*
494 * Add an L2 nexthop entry for the L3 routing system in the SoC
495 * Use VID and MAC in rtl838x_l2_entry to identify either a free slot in the L2 hash table
496 * or mark an existing entry as a nexthop by setting it's nexthop bit
497 * Called from the L3 layer
498 * The index in the L2 hash table is filled into nh->l2_id;
499 */
500 static int rtl930x_l2_nexthop_add(struct rtl838x_switch_priv *priv, struct rtl838x_nexthop *nh)
501 {
502 struct rtl838x_l2_entry e;
503 u64 seed = rtl930x_l2_hash_seed(nh->mac, nh->vid);
504 u32 key = rtl930x_l2_hash_key(priv, seed);
505 int i, idx = -1;
506 u64 entry;
507
508 pr_info("%s searching for %08llx vid %d with key %d, seed: %016llx\n",
509 __func__, nh->mac, nh->vid, key, seed);
510
511 e.type = L2_UNICAST;
512 e.rvid = nh->fid; // Verify its the forwarding ID!!! l2_entry.un.unicast.fid
513 u64_to_ether_addr(nh->mac, &e.mac[0]);
514 e.port = RTL930X_PORT_IGNORE;
515
516 // Loop over all entries in the hash-bucket and over the second block on 93xx SoCs
517 for (i = 0; i < priv->l2_bucket_size; i++) {
518 entry = rtl930x_read_l2_entry_using_hash(key, i, &e);
519 pr_info("%s i: %d, entry %016llx, seed %016llx\n", __func__, i, entry, seed);
520 if (e.valid && e.next_hop)
521 continue;
522 if (!e.valid || ((entry & 0x0fffffffffffffffULL) == seed)) {
523 idx = i > 3 ? ((key >> 14) & 0xffff) | i >> 1
524 : ((key << 2) | i) & 0xffff;
525 break;
526 }
527 }
528
529 pr_info("%s: found idx %d and i %d\n", __func__, idx, i);
530
531 if (idx < 0) {
532 pr_err("%s: No more L2 forwarding entries available\n", __func__);
533 return -1;
534 }
535
536 // Found an existing or empty entry, make it a nexthop entry
537 pr_info("%s BEFORE -> key %d, pos: %d, index: %d\n", __func__, key, i, idx);
538 dump_l2_entry(&e);
539 nh->l2_id = idx;
540
541 // Found an existing (e->valid is true) or empty entry, make it a nexthop entry
542 if (e.valid) {
543 nh->port = e.port;
544 nh->fid = e.rvid;
545 nh->vid = e.vid;
546 nh->dev_id = e.stack_dev;
547 } else {
548 e.valid = true;
549 e.is_static = false;
550 e.vid = nh->vid;
551 e.rvid = nh->fid;
552 e.port = RTL930X_PORT_IGNORE;
553 u64_to_ether_addr(nh->mac, &e.mac[0]);
554 }
555 e.next_hop = true;
556 // For nexthop entries, the vid field in the table is used to denote the dest mac_id
557 e.nh_route_id = nh->mac_id;
558 pr_info("%s AFTER\n", __func__);
559 dump_l2_entry(&e);
560
561 rtl930x_write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e);
562
563 // _dal_longan_l2_nexthop_add
564 return 0;
565 }
566
567 static u64 rtl930x_read_mcast_pmask(int idx)
568 {
569 u32 portmask;
570 // Read MC_PORTMASK (2) via register RTL9300_TBL_L2
571 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 2);
572
573 rtl_table_read(q, idx);
574 portmask = sw_r32(rtl_table_data(q, 0));
575 portmask >>= 3;
576 rtl_table_release(q);
577
578 pr_debug("%s: Index idx %d has portmask %08x\n", __func__, idx, portmask);
579 return portmask;
580 }
581
582 static void rtl930x_write_mcast_pmask(int idx, u64 portmask)
583 {
584 u32 pm = portmask;
585
586 // Access MC_PORTMASK (2) via register RTL9300_TBL_L2
587 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 2);
588
589 pr_debug("%s: Index idx %d has portmask %08x\n", __func__, idx, pm);
590 pm <<= 3;
591 sw_w32(pm, rtl_table_data(q, 0));
592 rtl_table_write(q, idx);
593 rtl_table_release(q);
594 }
595
596 u64 rtl930x_traffic_get(int source)
597 {
598 u32 v;
599 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
600
601 rtl_table_read(r, source);
602 v = sw_r32(rtl_table_data(r, 0));
603 rtl_table_release(r);
604 return v >> 3;
605 }
606
607 /*
608 * Enable traffic between a source port and a destination port matrix
609 */
610 void rtl930x_traffic_set(int source, u64 dest_matrix)
611 {
612 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
613
614 sw_w32((dest_matrix << 3), rtl_table_data(r, 0));
615 rtl_table_write(r, source);
616 rtl_table_release(r);
617 }
618
619 void rtl930x_traffic_enable(int source, int dest)
620 {
621 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
622 rtl_table_read(r, source);
623 sw_w32_mask(0, BIT(dest + 3), rtl_table_data(r, 0));
624 rtl_table_write(r, source);
625 rtl_table_release(r);
626 }
627
628 void rtl930x_traffic_disable(int source, int dest)
629 {
630 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
631 rtl_table_read(r, source);
632 sw_w32_mask(BIT(dest + 3), 0, rtl_table_data(r, 0));
633 rtl_table_write(r, source);
634 rtl_table_release(r);
635 }
636
637 void rtl9300_dump_debug(void)
638 {
639 int i;
640 u16 r = RTL930X_STAT_PRVTE_DROP_COUNTER0;
641
642 for (i = 0; i < 10; i ++) {
643 pr_info("# %d %08x %08x %08x %08x %08x %08x %08x %08x\n", i * 8,
644 sw_r32(r), sw_r32(r + 4), sw_r32(r + 8), sw_r32(r + 12),
645 sw_r32(r + 16), sw_r32(r + 20), sw_r32(r + 24), sw_r32(r + 28));
646 r += 32;
647 }
648 pr_info("# %08x %08x %08x %08x %08x\n",
649 sw_r32(r), sw_r32(r + 4), sw_r32(r + 8), sw_r32(r + 12), sw_r32(r + 16));
650 rtl930x_print_matrix();
651 pr_info("RTL930X_L2_PORT_SABLK_CTRL: %08x, RTL930X_L2_PORT_DABLK_CTRL %08x\n",
652 sw_r32(RTL930X_L2_PORT_SABLK_CTRL), sw_r32(RTL930X_L2_PORT_DABLK_CTRL)
653
654 );
655 }
656
657 irqreturn_t rtl930x_switch_irq(int irq, void *dev_id)
658 {
659 struct dsa_switch *ds = dev_id;
660 u32 status = sw_r32(RTL930X_ISR_GLB);
661 u32 ports = sw_r32(RTL930X_ISR_PORT_LINK_STS_CHG);
662 u32 link;
663 int i;
664
665 /* Clear status */
666 sw_w32(ports, RTL930X_ISR_PORT_LINK_STS_CHG);
667 pr_info("RTL9300 Link change: status: %x, ports %x\n", status, ports);
668
669 rtl9300_dump_debug();
670
671 for (i = 0; i < 28; i++) {
672 if (ports & BIT(i)) {
673 /* Read the register twice because of issues with latency at least
674 * with the external RTL8226 PHY on the XGS1210 */
675 link = sw_r32(RTL930X_MAC_LINK_STS);
676 link = sw_r32(RTL930X_MAC_LINK_STS);
677 if (link & BIT(i))
678 dsa_port_phylink_mac_change(ds, i, true);
679 else
680 dsa_port_phylink_mac_change(ds, i, false);
681 }
682 }
683
684 return IRQ_HANDLED;
685 }
686
687 int rtl9300_sds_power(int mac, int val)
688 {
689 int sds_num;
690 u32 mode;
691
692 // TODO: these numbers are hard-coded for the Zyxel XGS1210 12 Switch
693 pr_info("SerDes: %s %d\n", __func__, mac);
694 switch (mac) {
695 case 24:
696 sds_num = 6;
697 mode = 0x12; // HISGMII
698 break;
699 case 25:
700 sds_num = 7;
701 mode = 0x12; // HISGMII
702 break;
703 case 26:
704 sds_num = 8;
705 mode = 0x1b; // 10GR/1000BX auto
706 break;
707 case 27:
708 sds_num = 9;
709 mode = 0x1b; // 10GR/1000BX auto
710 break;
711 default:
712 return -1;
713 }
714 if (!val)
715 mode = 0x1f; // OFF
716
717 rtl9300_sds_rst(sds_num, mode);
718
719 return 0;
720 }
721
722 int rtl930x_write_phy(u32 port, u32 page, u32 reg, u32 val)
723 {
724 u32 v;
725 int err = 0;
726
727 pr_debug("%s: port %d, page: %d, reg: %x, val: %x\n", __func__, port, page, reg, val);
728
729 if (port > 63 || page > 4095 || reg > 31)
730 return -ENOTSUPP;
731
732 val &= 0xffff;
733 mutex_lock(&smi_lock);
734
735 sw_w32(BIT(port), RTL930X_SMI_ACCESS_PHY_CTRL_0);
736 sw_w32_mask(0xffff << 16, val << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2);
737 v = reg << 20 | page << 3 | 0x1f << 15 | BIT(2) | BIT(0);
738 sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1);
739
740 do {
741 v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1);
742 } while (v & 0x1);
743
744 if (v & 0x2)
745 err = -EIO;
746
747 mutex_unlock(&smi_lock);
748
749 return err;
750 }
751
752 int rtl930x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
753 {
754 u32 v;
755 int err = 0;
756
757 if (port > 63 || page > 4095 || reg > 31)
758 return -ENOTSUPP;
759
760 mutex_lock(&smi_lock);
761
762 sw_w32_mask(0xffff << 16, port << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2);
763 v = reg << 20 | page << 3 | 0x1f << 15 | 1;
764 sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1);
765
766 do {
767 v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1);
768 } while ( v & 0x1);
769
770 if (v & BIT(25)) {
771 pr_debug("Error reading phy %d, register %d\n", port, reg);
772 err = -EIO;
773 }
774 *val = (sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_2) & 0xffff);
775
776 pr_debug("%s: port %d, page: %d, reg: %x, val: %x\n", __func__, port, page, reg, *val);
777
778 mutex_unlock(&smi_lock);
779
780 return err;
781 }
782
783 /*
784 * Write to an mmd register of the PHY
785 */
786 int rtl930x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val)
787 {
788 int err = 0;
789 u32 v;
790
791 mutex_lock(&smi_lock);
792
793 // Set PHY to access
794 sw_w32(BIT(port), RTL930X_SMI_ACCESS_PHY_CTRL_0);
795
796 // Set data to write
797 sw_w32_mask(0xffff << 16, val << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2);
798
799 // Set MMD device number and register to write to
800 sw_w32(devnum << 16 | (regnum & 0xffff), RTL930X_SMI_ACCESS_PHY_CTRL_3);
801
802 v = BIT(2) | BIT(1) | BIT(0); // WRITE | MMD-access | EXEC
803 sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1);
804
805 do {
806 v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1);
807 } while (v & BIT(0));
808
809 pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, val, err);
810 mutex_unlock(&smi_lock);
811 return err;
812 }
813
814 /*
815 * Read an mmd register of the PHY
816 */
817 int rtl930x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val)
818 {
819 int err = 0;
820 u32 v;
821
822 mutex_lock(&smi_lock);
823
824 // Set PHY to access
825 sw_w32_mask(0xffff << 16, port << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2);
826
827 // Set MMD device number and register to write to
828 sw_w32(devnum << 16 | (regnum & 0xffff), RTL930X_SMI_ACCESS_PHY_CTRL_3);
829
830 v = BIT(1) | BIT(0); // MMD-access | EXEC
831 sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1);
832
833 do {
834 v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1);
835 } while (v & BIT(0));
836 // There is no error-checking via BIT 25 of v, as it does not seem to be set correctly
837 *val = (sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_2) & 0xffff);
838 pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, *val, err);
839
840 mutex_unlock(&smi_lock);
841
842 return err;
843 }
844
845 /*
846 * Calculate both the block 0 and the block 1 hash, and return in
847 * lower and higher word of the return value since only 12 bit of
848 * the hash are significant
849 */
850 u32 rtl930x_hash(struct rtl838x_switch_priv *priv, u64 seed)
851 {
852 u32 k0, k1, h1, h2, h;
853
854 k0 = (u32) (((seed >> 55) & 0x1f) ^ ((seed >> 44) & 0x7ff)
855 ^ ((seed >> 33) & 0x7ff) ^ ((seed >> 22) & 0x7ff)
856 ^ ((seed >> 11) & 0x7ff) ^ (seed & 0x7ff));
857
858 h1 = (seed >> 11) & 0x7ff;
859 h1 = ((h1 & 0x1f) << 6) | ((h1 >> 5) & 0x3f);
860
861 h2 = (seed >> 33) & 0x7ff;
862 h2 = ((h2 & 0x3f) << 5)| ((h2 >> 6) & 0x3f);
863
864 k1 = (u32) (((seed << 55) & 0x1f) ^ ((seed >> 44) & 0x7ff) ^ h2
865 ^ ((seed >> 22) & 0x7ff) ^ h1
866 ^ (seed & 0x7ff));
867
868 // Algorithm choice for block 0
869 if (sw_r32(RTL930X_L2_CTRL) & BIT(0))
870 h = k1;
871 else
872 h = k0;
873
874 /* Algorithm choice for block 1
875 * Since k0 and k1 are < 2048, adding 2048 will offset the hash into the second
876 * half of hash-space
877 * 2048 is in fact the hash-table size 16384 divided by 4 hashes per bucket
878 * divided by 2 to divide the hash space in 2
879 */
880 if (sw_r32(RTL930X_L2_CTRL) & BIT(1))
881 h |= (k1 + 2048) << 16;
882 else
883 h |= (k0 + 2048) << 16;
884
885 return h;
886 }
887
888 /*
889 * Enables or disables the EEE/EEEP capability of a port
890 */
891 void rtl930x_port_eee_set(struct rtl838x_switch_priv *priv, int port, bool enable)
892 {
893 u32 v;
894
895 // This works only for Ethernet ports, and on the RTL930X, ports from 26 are SFP
896 if (port >= 26)
897 return;
898
899 pr_debug("In %s: setting port %d to %d\n", __func__, port, enable);
900 v = enable ? 0x3f : 0x0;
901
902 // Set EEE/EEEP state for 100, 500, 1000MBit and 2.5, 5 and 10GBit
903 sw_w32_mask(0, v << 10, rtl930x_mac_force_mode_ctrl(port));
904
905 // Set TX/RX EEE state
906 v = enable ? 0x3 : 0x0;
907 sw_w32(v, RTL930X_EEE_CTRL(port));
908
909 priv->ports[port].eee_enabled = enable;
910 }
911
912 /*
913 * Get EEE own capabilities and negotiation result
914 */
915 int rtl930x_eee_port_ability(struct rtl838x_switch_priv *priv, struct ethtool_eee *e, int port)
916 {
917 u32 link, a;
918
919 if (port >= 26)
920 return -ENOTSUPP;
921
922 pr_info("In %s, port %d\n", __func__, port);
923 link = sw_r32(RTL930X_MAC_LINK_STS);
924 link = sw_r32(RTL930X_MAC_LINK_STS);
925 if (!(link & BIT(port)))
926 return 0;
927
928 pr_info("Setting advertised\n");
929 if (sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(10))
930 e->advertised |= ADVERTISED_100baseT_Full;
931
932 if (sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(12))
933 e->advertised |= ADVERTISED_1000baseT_Full;
934
935 if (priv->ports[port].is2G5 && sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(13)) {
936 pr_info("ADVERTISING 2.5G EEE\n");
937 e->advertised |= ADVERTISED_2500baseX_Full;
938 }
939
940 if (priv->ports[port].is10G && sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(15))
941 e->advertised |= ADVERTISED_10000baseT_Full;
942
943 a = sw_r32(RTL930X_MAC_EEE_ABLTY);
944 a = sw_r32(RTL930X_MAC_EEE_ABLTY);
945 pr_info("Link partner: %08x\n", a);
946 if (a & BIT(port)) {
947 e->lp_advertised = ADVERTISED_100baseT_Full;
948 e->lp_advertised |= ADVERTISED_1000baseT_Full;
949 if (priv->ports[port].is2G5)
950 e->lp_advertised |= ADVERTISED_2500baseX_Full;
951 if (priv->ports[port].is10G)
952 e->lp_advertised |= ADVERTISED_10000baseT_Full;
953 }
954
955 // Read 2x to clear latched state
956 a = sw_r32(RTL930X_EEEP_PORT_CTRL(port));
957 a = sw_r32(RTL930X_EEEP_PORT_CTRL(port));
958 pr_info("%s RTL930X_EEEP_PORT_CTRL: %08x\n", __func__, a);
959
960 return 0;
961 }
962
963 static void rtl930x_init_eee(struct rtl838x_switch_priv *priv, bool enable)
964 {
965 int i;
966
967 pr_info("Setting up EEE, state: %d\n", enable);
968
969 // Setup EEE on all ports
970 for (i = 0; i < priv->cpu_port; i++) {
971 if (priv->ports[i].phy)
972 rtl930x_port_eee_set(priv, i, enable);
973 }
974
975 priv->eee_enabled = enable;
976 }
977
978 const struct rtl838x_reg rtl930x_reg = {
979 .mask_port_reg_be = rtl838x_mask_port_reg,
980 .set_port_reg_be = rtl838x_set_port_reg,
981 .get_port_reg_be = rtl838x_get_port_reg,
982 .mask_port_reg_le = rtl838x_mask_port_reg,
983 .set_port_reg_le = rtl838x_set_port_reg,
984 .get_port_reg_le = rtl838x_get_port_reg,
985 .stat_port_rst = RTL930X_STAT_PORT_RST,
986 .stat_rst = RTL930X_STAT_RST,
987 .stat_port_std_mib = RTL930X_STAT_PORT_MIB_CNTR,
988 .traffic_enable = rtl930x_traffic_enable,
989 .traffic_disable = rtl930x_traffic_disable,
990 .traffic_get = rtl930x_traffic_get,
991 .traffic_set = rtl930x_traffic_set,
992 .l2_ctrl_0 = RTL930X_L2_CTRL,
993 .l2_ctrl_1 = RTL930X_L2_AGE_CTRL,
994 .l2_port_aging_out = RTL930X_L2_PORT_AGE_CTRL,
995 .smi_poll_ctrl = RTL930X_SMI_POLL_CTRL, // TODO: Difference to RTL9300_SMI_PRVTE_POLLING_CTRL
996 .l2_tbl_flush_ctrl = RTL930X_L2_TBL_FLUSH_CTRL,
997 .exec_tbl0_cmd = rtl930x_exec_tbl0_cmd,
998 .exec_tbl1_cmd = rtl930x_exec_tbl1_cmd,
999 .tbl_access_data_0 = rtl930x_tbl_access_data_0,
1000 .isr_glb_src = RTL930X_ISR_GLB,
1001 .isr_port_link_sts_chg = RTL930X_ISR_PORT_LINK_STS_CHG,
1002 .imr_port_link_sts_chg = RTL930X_IMR_PORT_LINK_STS_CHG,
1003 .imr_glb = RTL930X_IMR_GLB,
1004 .vlan_tables_read = rtl930x_vlan_tables_read,
1005 .vlan_set_tagged = rtl930x_vlan_set_tagged,
1006 .vlan_set_untagged = rtl930x_vlan_set_untagged,
1007 .vlan_profile_dump = rtl930x_vlan_profile_dump,
1008 .vlan_profile_setup = rtl930x_vlan_profile_setup,
1009 .vlan_fwd_on_inner = rtl930x_vlan_fwd_on_inner,
1010 .stp_get = rtl930x_stp_get,
1011 .stp_set = rtl930x_stp_set,
1012 .mac_force_mode_ctrl = rtl930x_mac_force_mode_ctrl,
1013 .mac_port_ctrl = rtl930x_mac_port_ctrl,
1014 .l2_port_new_salrn = rtl930x_l2_port_new_salrn,
1015 .l2_port_new_sa_fwd = rtl930x_l2_port_new_sa_fwd,
1016 .mir_ctrl = RTL930X_MIR_CTRL,
1017 .mir_dpm = RTL930X_MIR_DPM_CTRL,
1018 .mir_spm = RTL930X_MIR_SPM_CTRL,
1019 .mac_link_sts = RTL930X_MAC_LINK_STS,
1020 .mac_link_dup_sts = RTL930X_MAC_LINK_DUP_STS,
1021 .mac_link_spd_sts = rtl930x_mac_link_spd_sts,
1022 .mac_rx_pause_sts = RTL930X_MAC_RX_PAUSE_STS,
1023 .mac_tx_pause_sts = RTL930X_MAC_TX_PAUSE_STS,
1024 .read_l2_entry_using_hash = rtl930x_read_l2_entry_using_hash,
1025 .write_l2_entry_using_hash = rtl930x_write_l2_entry_using_hash,
1026 .read_cam = rtl930x_read_cam,
1027 .write_cam = rtl930x_write_cam,
1028 .vlan_port_egr_filter = RTL930X_VLAN_PORT_EGR_FLTR,
1029 .vlan_port_igr_filter = RTL930X_VLAN_PORT_IGR_FLTR(0),
1030 .vlan_port_pb = RTL930X_VLAN_PORT_PB_VLAN,
1031 .vlan_port_tag_sts_ctrl = RTL930X_VLAN_PORT_TAG_STS_CTRL,
1032 .trk_mbr_ctr = rtl930x_trk_mbr_ctr,
1033 .rma_bpdu_fld_pmask = RTL930X_RMA_BPDU_FLD_PMSK,
1034 .init_eee = rtl930x_init_eee,
1035 .port_eee_set = rtl930x_port_eee_set,
1036 .eee_port_ability = rtl930x_eee_port_ability,
1037 .read_mcast_pmask = rtl930x_read_mcast_pmask,
1038 .write_mcast_pmask = rtl930x_write_mcast_pmask,
1039 };