realtek: Packet Inspection Engine support for RTL930x SoCs
[openwrt/staging/dedeckeh.git] / target / linux / realtek / files-5.10 / 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 /* Definition of the RTL930X-specific template field IDs as used in the PIE */
10 enum template_field_id {
11 TEMPLATE_FIELD_SPM0 = 0, // Source portmask ports 0-15
12 TEMPLATE_FIELD_SPM1 = 1, // Source portmask ports 16-31
13 TEMPLATE_FIELD_DMAC0 = 2, // Destination MAC [15:0]
14 TEMPLATE_FIELD_DMAC1 = 3, // Destination MAC [31:16]
15 TEMPLATE_FIELD_DMAC2 = 4, // Destination MAC [47:32]
16 TEMPLATE_FIELD_SMAC0 = 5, // Source MAC [15:0]
17 TEMPLATE_FIELD_SMAC1 = 6, // Source MAC [31:16]
18 TEMPLATE_FIELD_SMAC2 = 7, // Source MAC [47:32]
19 TEMPLATE_FIELD_ETHERTYPE = 8, // Ethernet frame type field
20 TEMPLATE_FIELD_OTAG = 9,
21 TEMPLATE_FIELD_ITAG = 10,
22 TEMPLATE_FIELD_SIP0 = 11,
23 TEMPLATE_FIELD_SIP1 = 12,
24 TEMPLATE_FIELD_DIP0 = 13,
25 TEMPLATE_FIELD_DIP1 = 14,
26 TEMPLATE_FIELD_IP_TOS_PROTO = 15,
27 TEMPLATE_FIELD_L4_SPORT = 16,
28 TEMPLATE_FIELD_L4_DPORT = 17,
29 TEMPLATE_FIELD_L34_HEADER = 18,
30 TEMPLATE_FIELD_TCP_INFO = 19,
31 TEMPLATE_FIELD_FIELD_SELECTOR_VALID = 20,
32 TEMPLATE_FIELD_FIELD_SELECTOR_0 = 21,
33 TEMPLATE_FIELD_FIELD_SELECTOR_1 = 22,
34 TEMPLATE_FIELD_FIELD_SELECTOR_2 = 23,
35 TEMPLATE_FIELD_FIELD_SELECTOR_3 = 24,
36 TEMPLATE_FIELD_FIELD_SELECTOR_4 = 25,
37 TEMPLATE_FIELD_FIELD_SELECTOR_5 = 26,
38 TEMPLATE_FIELD_SIP2 = 27,
39 TEMPLATE_FIELD_SIP3 = 28,
40 TEMPLATE_FIELD_SIP4 = 29,
41 TEMPLATE_FIELD_SIP5 = 30,
42 TEMPLATE_FIELD_SIP6 = 31,
43 TEMPLATE_FIELD_SIP7 = 32,
44 TEMPLATE_FIELD_DIP2 = 33,
45 TEMPLATE_FIELD_DIP3 = 34,
46 TEMPLATE_FIELD_DIP4 = 35,
47 TEMPLATE_FIELD_DIP5 = 36,
48 TEMPLATE_FIELD_DIP6 = 37,
49 TEMPLATE_FIELD_DIP7 = 38,
50 TEMPLATE_FIELD_PKT_INFO = 39,
51 TEMPLATE_FIELD_FLOW_LABEL = 40,
52 TEMPLATE_FIELD_DSAP_SSAP = 41,
53 TEMPLATE_FIELD_SNAP_OUI = 42,
54 TEMPLATE_FIELD_FWD_VID = 43,
55 TEMPLATE_FIELD_RANGE_CHK = 44,
56 TEMPLATE_FIELD_VLAN_GMSK = 45, // VLAN Group Mask/IP range check
57 TEMPLATE_FIELD_DLP = 46,
58 TEMPLATE_FIELD_META_DATA = 47,
59 TEMPLATE_FIELD_SRC_FWD_VID = 48,
60 TEMPLATE_FIELD_SLP = 49,
61 };
62
63 /* The meaning of TEMPLATE_FIELD_VLAN depends on phase and the configuration in
64 * RTL930X_PIE_CTRL. We use always the same definition and map to the inner VLAN tag:
65 */
66 #define TEMPLATE_FIELD_VLAN TEMPLATE_FIELD_ITAG
67
68 // Number of fixed templates predefined in the RTL9300 SoC
69 #define N_FIXED_TEMPLATES 5
70 // RTL9300 specific predefined templates
71 static enum template_field_id fixed_templates[N_FIXED_TEMPLATES][N_FIXED_FIELDS] =
72 {
73 {
74 TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2,
75 TEMPLATE_FIELD_SMAC0, TEMPLATE_FIELD_SMAC1, TEMPLATE_FIELD_SMAC2,
76 TEMPLATE_FIELD_VLAN, TEMPLATE_FIELD_IP_TOS_PROTO, TEMPLATE_FIELD_DSAP_SSAP,
77 TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1
78 }, {
79 TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0,
80 TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_IP_TOS_PROTO, TEMPLATE_FIELD_TCP_INFO,
81 TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT, TEMPLATE_FIELD_VLAN,
82 TEMPLATE_FIELD_RANGE_CHK, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1
83 }, {
84 TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2,
85 TEMPLATE_FIELD_VLAN, TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_IP_TOS_PROTO,
86 TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0,
87 TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT
88 }, {
89 TEMPLATE_FIELD_DIP0, TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_DIP2,
90 TEMPLATE_FIELD_DIP3, TEMPLATE_FIELD_DIP4, TEMPLATE_FIELD_DIP5,
91 TEMPLATE_FIELD_DIP6, TEMPLATE_FIELD_DIP7, TEMPLATE_FIELD_IP_TOS_PROTO,
92 TEMPLATE_FIELD_TCP_INFO, TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT
93 }, {
94 TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_SIP2,
95 TEMPLATE_FIELD_SIP3, TEMPLATE_FIELD_SIP4, TEMPLATE_FIELD_SIP5,
96 TEMPLATE_FIELD_SIP6, TEMPLATE_FIELD_SIP7, TEMPLATE_FIELD_VLAN,
97 TEMPLATE_FIELD_RANGE_CHK, TEMPLATE_FIELD_SPM1, TEMPLATE_FIELD_SPM1
98 },
99 };
100
101 void rtl930x_print_matrix(void)
102 {
103 int i;
104 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
105
106 for (i = 0; i < 29; i++) {
107 rtl_table_read(r, i);
108 pr_debug("> %08x\n", sw_r32(rtl_table_data(r, 0)));
109 }
110 rtl_table_release(r);
111 }
112
113 inline void rtl930x_exec_tbl0_cmd(u32 cmd)
114 {
115 sw_w32(cmd, RTL930X_TBL_ACCESS_CTRL_0);
116 do { } while (sw_r32(RTL930X_TBL_ACCESS_CTRL_0) & (1 << 17));
117 }
118
119 inline void rtl930x_exec_tbl1_cmd(u32 cmd)
120 {
121 sw_w32(cmd, RTL930X_TBL_ACCESS_CTRL_1);
122 do { } while (sw_r32(RTL930X_TBL_ACCESS_CTRL_1) & (1 << 17));
123 }
124
125 inline int rtl930x_tbl_access_data_0(int i)
126 {
127 return RTL930X_TBL_ACCESS_DATA_0(i);
128 }
129
130 static inline int rtl930x_l2_port_new_salrn(int p)
131 {
132 return RTL930X_L2_PORT_SALRN(p);
133 }
134
135 static inline int rtl930x_l2_port_new_sa_fwd(int p)
136 {
137 // TODO: The definition of the fields changed, because of the master-cpu in a stack
138 return RTL930X_L2_PORT_NEW_SA_FWD(p);
139 }
140
141 inline static int rtl930x_trk_mbr_ctr(int group)
142 {
143 return RTL930X_TRK_MBR_CTRL + (group << 2);
144 }
145
146 static void rtl930x_vlan_tables_read(u32 vlan, struct rtl838x_vlan_info *info)
147 {
148 u32 v, w;
149 // Read VLAN table (1) via register 0
150 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 1);
151
152 rtl_table_read(r, vlan);
153 v = sw_r32(rtl_table_data(r, 0));
154 w = sw_r32(rtl_table_data(r, 1));
155 pr_debug("VLAN_READ %d: %08x %08x\n", vlan, v, w);
156 rtl_table_release(r);
157
158 info->tagged_ports = v >> 3;
159 info->profile_id = (w >> 24) & 7;
160 info->hash_mc_fid = !!(w & BIT(27));
161 info->hash_uc_fid = !!(w & BIT(28));
162 info->fid = ((v & 0x7) << 3) | ((w >> 29) & 0x7);
163
164 // Read UNTAG table via table register 2
165 r = rtl_table_get(RTL9300_TBL_2, 0);
166 rtl_table_read(r, vlan);
167 v = sw_r32(rtl_table_data(r, 0));
168 rtl_table_release(r);
169
170 info->untagged_ports = v >> 3;
171 }
172
173 static void rtl930x_vlan_set_tagged(u32 vlan, struct rtl838x_vlan_info *info)
174 {
175 u32 v, w;
176 // Access VLAN table (1) via register 0
177 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 1);
178
179 v = info->tagged_ports << 3;
180 v |= ((u32)info->fid) >> 3;
181
182 w = ((u32)info->fid) << 29;
183 w |= info->hash_mc_fid ? BIT(27) : 0;
184 w |= info->hash_uc_fid ? BIT(28) : 0;
185 w |= info->profile_id << 24;
186
187 sw_w32(v, rtl_table_data(r, 0));
188 sw_w32(w, rtl_table_data(r, 1));
189
190 rtl_table_write(r, vlan);
191 rtl_table_release(r);
192 }
193
194 void rtl930x_vlan_profile_dump(int profile)
195 {
196 u32 p[5];
197
198 if (profile < 0 || profile > 7)
199 return;
200
201 p[0] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile));
202 p[1] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 4);
203 p[2] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 8) & 0x1FFFFFFF;
204 p[3] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 12) & 0x1FFFFFFF;
205 p[4] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 16) & 0x1FFFFFFF;
206
207 pr_info("VLAN %d: L2 learn: %d; Unknown MC PMasks: L2 %0x, IPv4 %0x, IPv6: %0x",
208 profile, p[0] & (3 << 21), p[2], p[3], p[4]);
209 pr_info(" Routing enabled: IPv4 UC %c, IPv6 UC %c, IPv4 MC %c, IPv6 MC %c\n",
210 p[0] & BIT(17) ? 'y' : 'n', p[0] & BIT(16) ? 'y' : 'n',
211 p[0] & BIT(13) ? 'y' : 'n', p[0] & BIT(12) ? 'y' : 'n');
212 pr_info(" Bridge enabled: IPv4 MC %c, IPv6 MC %c,\n",
213 p[0] & BIT(15) ? 'y' : 'n', p[0] & BIT(14) ? 'y' : 'n');
214 pr_info("VLAN profile %d: raw %08x %08x %08x %08x %08x\n",
215 profile, p[0], p[1], p[2], p[3], p[4]);
216 }
217
218 static void rtl930x_vlan_set_untagged(u32 vlan, u64 portmask)
219 {
220 struct table_reg *r = rtl_table_get(RTL9300_TBL_2, 0);
221
222 sw_w32(portmask << 3, rtl_table_data(r, 0));
223 rtl_table_write(r, vlan);
224 rtl_table_release(r);
225 }
226
227 /* Sets the L2 forwarding to be based on either the inner VLAN tag or the outer
228 */
229 static void rtl930x_vlan_fwd_on_inner(int port, bool is_set)
230 {
231 // Always set all tag modes to fwd based on either inner or outer tag
232 if (is_set)
233 sw_w32_mask(0, 0xf, RTL930X_VLAN_PORT_FWD + (port << 2));
234 else
235 sw_w32_mask(0xf, 0, RTL930X_VLAN_PORT_FWD + (port << 2));
236 }
237
238 static void rtl930x_vlan_profile_setup(int profile)
239 {
240 u32 p[5];
241
242 pr_info("In %s\n", __func__);
243 p[0] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile));
244 p[1] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 4);
245
246 // Enable routing of Ipv4/6 Unicast and IPv4/6 Multicast traffic
247 p[0] |= BIT(17) | BIT(16) | BIT(13) | BIT(12);
248 p[2] = 0x1fffffff; // L2 unknown MC flooding portmask all ports, including the CPU-port
249 p[3] = 0x1fffffff; // IPv4 unknown MC flooding portmask
250 p[4] = 0x1fffffff; // IPv6 unknown MC flooding portmask
251
252 sw_w32(p[0], RTL930X_VLAN_PROFILE_SET(profile));
253 sw_w32(p[1], RTL930X_VLAN_PROFILE_SET(profile) + 4);
254 sw_w32(p[2], RTL930X_VLAN_PROFILE_SET(profile) + 8);
255 sw_w32(p[3], RTL930X_VLAN_PROFILE_SET(profile) + 12);
256 sw_w32(p[4], RTL930X_VLAN_PROFILE_SET(profile) + 16);
257 pr_info("Leaving %s\n", __func__);
258 }
259
260 static void rtl930x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
261 {
262 int i;
263 u32 cmd = 1 << 17 /* Execute cmd */
264 | 0 << 16 /* Read */
265 | 4 << 12 /* Table type 0b10 */
266 | (msti & 0xfff);
267 priv->r->exec_tbl0_cmd(cmd);
268
269 for (i = 0; i < 2; i++)
270 port_state[i] = sw_r32(RTL930X_TBL_ACCESS_DATA_0(i));
271 pr_debug("MSTI: %d STATE: %08x, %08x\n", msti, port_state[0], port_state[1]);
272 }
273
274 static void rtl930x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
275 {
276 int i;
277 u32 cmd = 1 << 17 /* Execute cmd */
278 | 1 << 16 /* Write */
279 | 4 << 12 /* Table type 4 */
280 | (msti & 0xfff);
281
282 for (i = 0; i < 2; i++)
283 sw_w32(port_state[i], RTL930X_TBL_ACCESS_DATA_0(i));
284 priv->r->exec_tbl0_cmd(cmd);
285 }
286
287 static inline int rtl930x_mac_force_mode_ctrl(int p)
288 {
289 return RTL930X_MAC_FORCE_MODE_CTRL + (p << 2);
290 }
291
292 static inline int rtl930x_mac_port_ctrl(int p)
293 {
294 return RTL930X_MAC_L2_PORT_CTRL(p);
295 }
296
297 static inline int rtl930x_mac_link_spd_sts(int p)
298 {
299 return RTL930X_MAC_LINK_SPD_STS(p);
300 }
301
302 static u64 rtl930x_l2_hash_seed(u64 mac, u32 vid)
303 {
304 u64 v = vid;
305
306 v <<= 48;
307 v |= mac;
308
309 return v;
310 }
311
312 /*
313 * Calculate both the block 0 and the block 1 hash by applyingthe same hash
314 * algorithm as the one used currently by the ASIC to the seed, and return
315 * both hashes in the lower and higher word of the return value since only 12 bit of
316 * the hash are significant
317 */
318 static u32 rtl930x_l2_hash_key(struct rtl838x_switch_priv *priv, u64 seed)
319 {
320 u32 k0, k1, h1, h2, h;
321
322 k0 = (u32) (((seed >> 55) & 0x1f) ^ ((seed >> 44) & 0x7ff)
323 ^ ((seed >> 33) & 0x7ff) ^ ((seed >> 22) & 0x7ff)
324 ^ ((seed >> 11) & 0x7ff) ^ (seed & 0x7ff));
325
326 h1 = (seed >> 11) & 0x7ff;
327 h1 = ((h1 & 0x1f) << 6) | ((h1 >> 5) & 0x3f);
328
329 h2 = (seed >> 33) & 0x7ff;
330 h2 = ((h2 & 0x3f) << 5)| ((h2 >> 6) & 0x3f);
331
332 k1 = (u32) (((seed << 55) & 0x1f) ^ ((seed >> 44) & 0x7ff) ^ h2
333 ^ ((seed >> 22) & 0x7ff) ^ h1
334 ^ (seed & 0x7ff));
335
336 // Algorithm choice for block 0
337 if (sw_r32(RTL930X_L2_CTRL) & BIT(0))
338 h = k1;
339 else
340 h = k0;
341
342 /* Algorithm choice for block 1
343 * Since k0 and k1 are < 2048, adding 2048 will offset the hash into the second
344 * half of hash-space
345 * 2048 is in fact the hash-table size 16384 divided by 4 hashes per bucket
346 * divided by 2 to divide the hash space in 2
347 */
348 if (sw_r32(RTL930X_L2_CTRL) & BIT(1))
349 h |= (k1 + 2048) << 16;
350 else
351 h |= (k0 + 2048) << 16;
352
353 return h;
354 }
355
356 /*
357 * Fills an L2 entry structure from the SoC registers
358 */
359 static void rtl930x_fill_l2_entry(u32 r[], struct rtl838x_l2_entry *e)
360 {
361 pr_debug("In %s valid?\n", __func__);
362 e->valid = !!(r[2] & BIT(31));
363 if (!e->valid)
364 return;
365
366 pr_debug("In %s is valid\n", __func__);
367 e->is_ip_mc = false;
368 e->is_ipv6_mc = false;
369
370 // TODO: Is there not a function to copy directly MAC memory?
371 e->mac[0] = (r[0] >> 24);
372 e->mac[1] = (r[0] >> 16);
373 e->mac[2] = (r[0] >> 8);
374 e->mac[3] = r[0];
375 e->mac[4] = (r[1] >> 24);
376 e->mac[5] = (r[1] >> 16);
377
378 e->next_hop = !!(r[2] & BIT(12));
379 e->rvid = r[1] & 0xfff;
380
381 /* Is it a unicast entry? check multicast bit */
382 if (!(e->mac[0] & 1)) {
383 e->type = L2_UNICAST;
384 e->is_static = !!(r[2] & BIT(14));
385 e->port = (r[2] >> 20) & 0x3ff;
386 // Check for trunk port
387 if (r[2] & BIT(30)) {
388 e->is_trunk = true;
389 e->stack_dev = (e->port >> 9) & 1;
390 e->trunk = e->port & 0x3f;
391 } else {
392 e->is_trunk = false;
393 e->stack_dev = (e->port >> 6) & 0xf;
394 e->port = e->port & 0x3f;
395 }
396
397 e->block_da = !!(r[2] & BIT(15));
398 e->block_sa = !!(r[2] & BIT(16));
399 e->suspended = !!(r[2] & BIT(13));
400 e->age = (r[2] >> 17) & 3;
401 e->valid = true;
402 // the UC_VID field in hardware is used for the VID or for the route id
403 if (e->next_hop) {
404 e->nh_route_id = r[2] & 0xfff;
405 e->vid = 0;
406 } else {
407 e->vid = r[2] & 0xfff;
408 e->nh_route_id = 0;
409 }
410 } else {
411 e->valid = true;
412 e->type = L2_MULTICAST;
413 e->mc_portmask_index = (r[2] >> 16) & 0x3ff;
414 }
415 }
416
417 /*
418 * Fills the 3 SoC table registers r[] with the information of in the rtl838x_l2_entry
419 */
420 static void rtl930x_fill_l2_row(u32 r[], struct rtl838x_l2_entry *e)
421 {
422 u32 port;
423
424 if (!e->valid) {
425 r[0] = r[1] = r[2] = 0;
426 return;
427 }
428
429 r[2] = BIT(31); // Set valid bit
430
431 r[0] = ((u32)e->mac[0]) << 24 | ((u32)e->mac[1]) << 16
432 | ((u32)e->mac[2]) << 8 | ((u32)e->mac[3]);
433 r[1] = ((u32)e->mac[4]) << 24 | ((u32)e->mac[5]) << 16;
434
435 r[2] |= e->next_hop ? BIT(12) : 0;
436
437 if (e->type == L2_UNICAST) {
438 r[2] |= e->is_static ? BIT(14) : 0;
439 r[1] |= e->rvid & 0xfff;
440 r[2] |= (e->port & 0x3ff) << 20;
441 if (e->is_trunk) {
442 r[2] |= BIT(30);
443 port = e->stack_dev << 9 | (e->port & 0x3f);
444 } else {
445 port = (e->stack_dev & 0xf) << 6;
446 port |= e->port & 0x3f;
447 }
448 r[2] |= port << 20;
449 r[2] |= e->block_da ? BIT(15) : 0;
450 r[2] |= e->block_sa ? BIT(17) : 0;
451 r[2] |= e->suspended ? BIT(13) : 0;
452 r[2] |= (e->age & 0x3) << 17;
453 // the UC_VID field in hardware is used for the VID or for the route id
454 if (e->next_hop)
455 r[2] |= e->nh_route_id & 0xfff;
456 else
457 r[2] |= e->vid & 0xfff;
458 } else { // L2_MULTICAST
459 r[2] |= (e->mc_portmask_index & 0x3ff) << 16;
460 r[2] |= e->mc_mac_index & 0x7ff;
461 }
462 }
463
464 /*
465 * Read an L2 UC or MC entry out of a hash bucket of the L2 forwarding table
466 * hash is the id of the bucket and pos is the position of the entry in that bucket
467 * The data read from the SoC is filled into rtl838x_l2_entry
468 */
469 static u64 rtl930x_read_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e)
470 {
471 u32 r[3];
472 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 0);
473 u32 idx;
474 int i;
475 u64 mac;
476 u64 seed;
477
478 pr_debug("%s: hash %08x, pos: %d\n", __func__, hash, pos);
479
480 /* On the RTL93xx, 2 different hash algorithms are used making it a total of
481 * 8 buckets that need to be searched, 4 for each hash-half
482 * Use second hash space when bucket is between 4 and 8 */
483 if (pos >= 4) {
484 pos -= 4;
485 hash >>= 16;
486 } else {
487 hash &= 0xffff;
488 }
489
490 idx = (0 << 14) | (hash << 2) | pos; // Search SRAM, with hash and at pos in bucket
491 pr_debug("%s: NOW hash %08x, pos: %d\n", __func__, hash, pos);
492
493 rtl_table_read(q, idx);
494 for (i = 0; i < 3; i++)
495 r[i] = sw_r32(rtl_table_data(q, i));
496
497 rtl_table_release(q);
498
499 rtl930x_fill_l2_entry(r, e);
500
501 pr_debug("%s: valid: %d, nh: %d\n", __func__, e->valid, e->next_hop);
502 if (!e->valid)
503 return 0;
504
505 mac = ((u64)e->mac[0]) << 40 | ((u64)e->mac[1]) << 32 | ((u64)e->mac[2]) << 24
506 | ((u64)e->mac[3]) << 16 | ((u64)e->mac[4]) << 8 | ((u64)e->mac[5]);
507
508 seed = rtl930x_l2_hash_seed(mac, e->rvid);
509 pr_debug("%s: mac %016llx, seed %016llx\n", __func__, mac, seed);
510 // return vid with concatenated mac as unique id
511 return seed;
512 }
513
514 static void rtl930x_write_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e)
515 {
516 u32 r[3];
517 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 0);
518 u32 idx = (0 << 14) | (hash << 2) | pos; // Access SRAM, with hash and at pos in bucket
519 int i;
520
521 pr_info("%s: hash %d, pos %d\n", __func__, hash, pos);
522 pr_info("%s: index %d -> mac %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, idx,
523 e->mac[0], e->mac[1], e->mac[2], e->mac[3],e->mac[4],e->mac[5]);
524
525 rtl930x_fill_l2_row(r, e);
526
527 for (i= 0; i < 3; i++)
528 sw_w32(r[i], rtl_table_data(q, i));
529
530 rtl_table_write(q, idx);
531 rtl_table_release(q);
532 }
533
534 static u64 rtl930x_read_cam(int idx, struct rtl838x_l2_entry *e)
535 {
536 u32 r[3];
537 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 1);
538 int i;
539
540 rtl_table_read(q, idx);
541 for (i= 0; i < 3; i++)
542 r[i] = sw_r32(rtl_table_data(q, i));
543
544 rtl_table_release(q);
545
546 rtl930x_fill_l2_entry(r, e);
547 if (!e->valid)
548 return 0;
549
550 // return mac with concatenated vid as unique id
551 return ((u64)r[0] << 28) | ((r[1] & 0xffff0000) >> 4) | e->vid;
552 }
553
554 static void rtl930x_write_cam(int idx, struct rtl838x_l2_entry *e)
555 {
556 u32 r[3];
557 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 1); // Access L2 Table 1
558 int i;
559
560 rtl930x_fill_l2_row(r, e);
561
562 for (i= 0; i < 3; i++)
563 sw_w32(r[i], rtl_table_data(q, i));
564
565 rtl_table_write(q, idx);
566 rtl_table_release(q);
567 }
568
569 static void dump_l2_entry(struct rtl838x_l2_entry *e)
570 {
571 pr_info("MAC: %02x:%02x:%02x:%02x:%02x:%02x vid: %d, rvid: %d, port: %d, valid: %d\n",
572 e->mac[0], e->mac[1], e->mac[2], e->mac[3], e->mac[4], e->mac[5],
573 e->vid, e->rvid, e->port, e->valid);
574 pr_info("Type: %d, is_static: %d, is_ip_mc: %d, is_ipv6_mc: %d, block_da: %d\n",
575 e->type, e->is_static, e->is_ip_mc, e->is_ipv6_mc, e->block_da);
576 pr_info(" block_sa: %d, suspended: %d, next_hop: %d, age: %d, is_trunk: %d, trunk: %d\n",
577 e->block_sa, e->suspended, e->next_hop, e->age, e->is_trunk, e->trunk);
578 if (e->is_ip_mc || e->is_ipv6_mc)
579 pr_info(" mc_portmask_index: %d, mc_gip: %d, mc_sip: %d\n",
580 e->mc_portmask_index, e->mc_gip, e->mc_sip);
581 pr_info(" stac_dev: %d, nh_route_id: %d, port: %d, dev_id\n",
582 e->stack_dev, e->nh_route_id, e->port);
583 }
584
585 /*
586 * Add an L2 nexthop entry for the L3 routing system in the SoC
587 * Use VID and MAC in rtl838x_l2_entry to identify either a free slot in the L2 hash table
588 * or mark an existing entry as a nexthop by setting it's nexthop bit
589 * Called from the L3 layer
590 * The index in the L2 hash table is filled into nh->l2_id;
591 */
592 static int rtl930x_l2_nexthop_add(struct rtl838x_switch_priv *priv, struct rtl838x_nexthop *nh)
593 {
594 struct rtl838x_l2_entry e;
595 u64 seed = rtl930x_l2_hash_seed(nh->mac, nh->vid);
596 u32 key = rtl930x_l2_hash_key(priv, seed);
597 int i, idx = -1;
598 u64 entry;
599
600 pr_info("%s searching for %08llx vid %d with key %d, seed: %016llx\n",
601 __func__, nh->mac, nh->vid, key, seed);
602
603 e.type = L2_UNICAST;
604 e.rvid = nh->fid; // Verify its the forwarding ID!!! l2_entry.un.unicast.fid
605 u64_to_ether_addr(nh->mac, &e.mac[0]);
606 e.port = RTL930X_PORT_IGNORE;
607
608 // Loop over all entries in the hash-bucket and over the second block on 93xx SoCs
609 for (i = 0; i < priv->l2_bucket_size; i++) {
610 entry = rtl930x_read_l2_entry_using_hash(key, i, &e);
611 pr_info("%s i: %d, entry %016llx, seed %016llx\n", __func__, i, entry, seed);
612 if (e.valid && e.next_hop)
613 continue;
614 if (!e.valid || ((entry & 0x0fffffffffffffffULL) == seed)) {
615 idx = i > 3 ? ((key >> 14) & 0xffff) | i >> 1
616 : ((key << 2) | i) & 0xffff;
617 break;
618 }
619 }
620
621 pr_info("%s: found idx %d and i %d\n", __func__, idx, i);
622
623 if (idx < 0) {
624 pr_err("%s: No more L2 forwarding entries available\n", __func__);
625 return -1;
626 }
627
628 // Found an existing or empty entry, make it a nexthop entry
629 pr_info("%s BEFORE -> key %d, pos: %d, index: %d\n", __func__, key, i, idx);
630 dump_l2_entry(&e);
631 nh->l2_id = idx;
632
633 // Found an existing (e->valid is true) or empty entry, make it a nexthop entry
634 if (e.valid) {
635 nh->port = e.port;
636 nh->fid = e.rvid;
637 nh->vid = e.vid;
638 nh->dev_id = e.stack_dev;
639 } else {
640 e.valid = true;
641 e.is_static = false;
642 e.vid = nh->vid;
643 e.rvid = nh->fid;
644 e.port = RTL930X_PORT_IGNORE;
645 u64_to_ether_addr(nh->mac, &e.mac[0]);
646 }
647 e.next_hop = true;
648 // For nexthop entries, the vid field in the table is used to denote the dest mac_id
649 e.nh_route_id = nh->mac_id;
650 pr_info("%s AFTER\n", __func__);
651 dump_l2_entry(&e);
652
653 rtl930x_write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e);
654
655 // _dal_longan_l2_nexthop_add
656 return 0;
657 }
658
659 static u64 rtl930x_read_mcast_pmask(int idx)
660 {
661 u32 portmask;
662 // Read MC_PORTMASK (2) via register RTL9300_TBL_L2
663 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 2);
664
665 rtl_table_read(q, idx);
666 portmask = sw_r32(rtl_table_data(q, 0));
667 portmask >>= 3;
668 rtl_table_release(q);
669
670 pr_debug("%s: Index idx %d has portmask %08x\n", __func__, idx, portmask);
671 return portmask;
672 }
673
674 static void rtl930x_write_mcast_pmask(int idx, u64 portmask)
675 {
676 u32 pm = portmask;
677
678 // Access MC_PORTMASK (2) via register RTL9300_TBL_L2
679 struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 2);
680
681 pr_debug("%s: Index idx %d has portmask %08x\n", __func__, idx, pm);
682 pm <<= 3;
683 sw_w32(pm, rtl_table_data(q, 0));
684 rtl_table_write(q, idx);
685 rtl_table_release(q);
686 }
687
688 u64 rtl930x_traffic_get(int source)
689 {
690 u32 v;
691 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
692
693 rtl_table_read(r, source);
694 v = sw_r32(rtl_table_data(r, 0));
695 rtl_table_release(r);
696 return v >> 3;
697 }
698
699 /*
700 * Enable traffic between a source port and a destination port matrix
701 */
702 void rtl930x_traffic_set(int source, u64 dest_matrix)
703 {
704 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
705
706 sw_w32((dest_matrix << 3), rtl_table_data(r, 0));
707 rtl_table_write(r, source);
708 rtl_table_release(r);
709 }
710
711 void rtl930x_traffic_enable(int source, int dest)
712 {
713 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
714 rtl_table_read(r, source);
715 sw_w32_mask(0, BIT(dest + 3), rtl_table_data(r, 0));
716 rtl_table_write(r, source);
717 rtl_table_release(r);
718 }
719
720 void rtl930x_traffic_disable(int source, int dest)
721 {
722 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6);
723 rtl_table_read(r, source);
724 sw_w32_mask(BIT(dest + 3), 0, rtl_table_data(r, 0));
725 rtl_table_write(r, source);
726 rtl_table_release(r);
727 }
728
729 void rtl9300_dump_debug(void)
730 {
731 int i;
732 u16 r = RTL930X_STAT_PRVTE_DROP_COUNTER0;
733
734 for (i = 0; i < 10; i ++) {
735 pr_info("# %d %08x %08x %08x %08x %08x %08x %08x %08x\n", i * 8,
736 sw_r32(r), sw_r32(r + 4), sw_r32(r + 8), sw_r32(r + 12),
737 sw_r32(r + 16), sw_r32(r + 20), sw_r32(r + 24), sw_r32(r + 28));
738 r += 32;
739 }
740 pr_info("# %08x %08x %08x %08x %08x\n",
741 sw_r32(r), sw_r32(r + 4), sw_r32(r + 8), sw_r32(r + 12), sw_r32(r + 16));
742 rtl930x_print_matrix();
743 pr_info("RTL930X_L2_PORT_SABLK_CTRL: %08x, RTL930X_L2_PORT_DABLK_CTRL %08x\n",
744 sw_r32(RTL930X_L2_PORT_SABLK_CTRL), sw_r32(RTL930X_L2_PORT_DABLK_CTRL)
745
746 );
747 }
748
749 irqreturn_t rtl930x_switch_irq(int irq, void *dev_id)
750 {
751 struct dsa_switch *ds = dev_id;
752 u32 status = sw_r32(RTL930X_ISR_GLB);
753 u32 ports = sw_r32(RTL930X_ISR_PORT_LINK_STS_CHG);
754 u32 link;
755 int i;
756
757 /* Clear status */
758 sw_w32(ports, RTL930X_ISR_PORT_LINK_STS_CHG);
759 pr_info("RTL9300 Link change: status: %x, ports %x\n", status, ports);
760
761 rtl9300_dump_debug();
762
763 for (i = 0; i < 28; i++) {
764 if (ports & BIT(i)) {
765 /* Read the register twice because of issues with latency at least
766 * with the external RTL8226 PHY on the XGS1210 */
767 link = sw_r32(RTL930X_MAC_LINK_STS);
768 link = sw_r32(RTL930X_MAC_LINK_STS);
769 if (link & BIT(i))
770 dsa_port_phylink_mac_change(ds, i, true);
771 else
772 dsa_port_phylink_mac_change(ds, i, false);
773 }
774 }
775
776 return IRQ_HANDLED;
777 }
778
779 int rtl9300_sds_power(int mac, int val)
780 {
781 int sds_num;
782 u32 mode;
783
784 // TODO: these numbers are hard-coded for the Zyxel XGS1210 12 Switch
785 pr_info("SerDes: %s %d\n", __func__, mac);
786 switch (mac) {
787 case 24:
788 sds_num = 6;
789 mode = 0x12; // HISGMII
790 break;
791 case 25:
792 sds_num = 7;
793 mode = 0x12; // HISGMII
794 break;
795 case 26:
796 sds_num = 8;
797 mode = 0x1b; // 10GR/1000BX auto
798 break;
799 case 27:
800 sds_num = 9;
801 mode = 0x1b; // 10GR/1000BX auto
802 break;
803 default:
804 return -1;
805 }
806 if (!val)
807 mode = 0x1f; // OFF
808
809 rtl9300_sds_rst(sds_num, mode);
810
811 return 0;
812 }
813
814 int rtl930x_write_phy(u32 port, u32 page, u32 reg, u32 val)
815 {
816 u32 v;
817 int err = 0;
818
819 pr_debug("%s: port %d, page: %d, reg: %x, val: %x\n", __func__, port, page, reg, val);
820
821 if (port > 63 || page > 4095 || reg > 31)
822 return -ENOTSUPP;
823
824 val &= 0xffff;
825 mutex_lock(&smi_lock);
826
827 sw_w32(BIT(port), RTL930X_SMI_ACCESS_PHY_CTRL_0);
828 sw_w32_mask(0xffff << 16, val << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2);
829 v = reg << 20 | page << 3 | 0x1f << 15 | BIT(2) | BIT(0);
830 sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1);
831
832 do {
833 v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1);
834 } while (v & 0x1);
835
836 if (v & 0x2)
837 err = -EIO;
838
839 mutex_unlock(&smi_lock);
840
841 return err;
842 }
843
844 int rtl930x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
845 {
846 u32 v;
847 int err = 0;
848
849 if (port > 63 || page > 4095 || reg > 31)
850 return -ENOTSUPP;
851
852 mutex_lock(&smi_lock);
853
854 sw_w32_mask(0xffff << 16, port << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2);
855 v = reg << 20 | page << 3 | 0x1f << 15 | 1;
856 sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1);
857
858 do {
859 v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1);
860 } while ( v & 0x1);
861
862 if (v & BIT(25)) {
863 pr_debug("Error reading phy %d, register %d\n", port, reg);
864 err = -EIO;
865 }
866 *val = (sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_2) & 0xffff);
867
868 pr_debug("%s: port %d, page: %d, reg: %x, val: %x\n", __func__, port, page, reg, *val);
869
870 mutex_unlock(&smi_lock);
871
872 return err;
873 }
874
875 /*
876 * Write to an mmd register of the PHY
877 */
878 int rtl930x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val)
879 {
880 int err = 0;
881 u32 v;
882
883 mutex_lock(&smi_lock);
884
885 // Set PHY to access
886 sw_w32(BIT(port), RTL930X_SMI_ACCESS_PHY_CTRL_0);
887
888 // Set data to write
889 sw_w32_mask(0xffff << 16, val << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2);
890
891 // Set MMD device number and register to write to
892 sw_w32(devnum << 16 | (regnum & 0xffff), RTL930X_SMI_ACCESS_PHY_CTRL_3);
893
894 v = BIT(2) | BIT(1) | BIT(0); // WRITE | MMD-access | EXEC
895 sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1);
896
897 do {
898 v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1);
899 } while (v & BIT(0));
900
901 pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, val, err);
902 mutex_unlock(&smi_lock);
903 return err;
904 }
905
906 /*
907 * Read an mmd register of the PHY
908 */
909 int rtl930x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val)
910 {
911 int err = 0;
912 u32 v;
913
914 mutex_lock(&smi_lock);
915
916 // Set PHY to access
917 sw_w32_mask(0xffff << 16, port << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2);
918
919 // Set MMD device number and register to write to
920 sw_w32(devnum << 16 | (regnum & 0xffff), RTL930X_SMI_ACCESS_PHY_CTRL_3);
921
922 v = BIT(1) | BIT(0); // MMD-access | EXEC
923 sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1);
924
925 do {
926 v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1);
927 } while (v & BIT(0));
928 // There is no error-checking via BIT 25 of v, as it does not seem to be set correctly
929 *val = (sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_2) & 0xffff);
930 pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, *val, err);
931
932 mutex_unlock(&smi_lock);
933
934 return err;
935 }
936
937 /*
938 * Calculate both the block 0 and the block 1 hash, and return in
939 * lower and higher word of the return value since only 12 bit of
940 * the hash are significant
941 */
942 u32 rtl930x_hash(struct rtl838x_switch_priv *priv, u64 seed)
943 {
944 u32 k0, k1, h1, h2, h;
945
946 k0 = (u32) (((seed >> 55) & 0x1f) ^ ((seed >> 44) & 0x7ff)
947 ^ ((seed >> 33) & 0x7ff) ^ ((seed >> 22) & 0x7ff)
948 ^ ((seed >> 11) & 0x7ff) ^ (seed & 0x7ff));
949
950 h1 = (seed >> 11) & 0x7ff;
951 h1 = ((h1 & 0x1f) << 6) | ((h1 >> 5) & 0x3f);
952
953 h2 = (seed >> 33) & 0x7ff;
954 h2 = ((h2 & 0x3f) << 5)| ((h2 >> 6) & 0x3f);
955
956 k1 = (u32) (((seed << 55) & 0x1f) ^ ((seed >> 44) & 0x7ff) ^ h2
957 ^ ((seed >> 22) & 0x7ff) ^ h1
958 ^ (seed & 0x7ff));
959
960 // Algorithm choice for block 0
961 if (sw_r32(RTL930X_L2_CTRL) & BIT(0))
962 h = k1;
963 else
964 h = k0;
965
966 /* Algorithm choice for block 1
967 * Since k0 and k1 are < 2048, adding 2048 will offset the hash into the second
968 * half of hash-space
969 * 2048 is in fact the hash-table size 16384 divided by 4 hashes per bucket
970 * divided by 2 to divide the hash space in 2
971 */
972 if (sw_r32(RTL930X_L2_CTRL) & BIT(1))
973 h |= (k1 + 2048) << 16;
974 else
975 h |= (k0 + 2048) << 16;
976
977 return h;
978 }
979
980 /*
981 * Enables or disables the EEE/EEEP capability of a port
982 */
983 void rtl930x_port_eee_set(struct rtl838x_switch_priv *priv, int port, bool enable)
984 {
985 u32 v;
986
987 // This works only for Ethernet ports, and on the RTL930X, ports from 26 are SFP
988 if (port >= 26)
989 return;
990
991 pr_debug("In %s: setting port %d to %d\n", __func__, port, enable);
992 v = enable ? 0x3f : 0x0;
993
994 // Set EEE/EEEP state for 100, 500, 1000MBit and 2.5, 5 and 10GBit
995 sw_w32_mask(0, v << 10, rtl930x_mac_force_mode_ctrl(port));
996
997 // Set TX/RX EEE state
998 v = enable ? 0x3 : 0x0;
999 sw_w32(v, RTL930X_EEE_CTRL(port));
1000
1001 priv->ports[port].eee_enabled = enable;
1002 }
1003
1004 /*
1005 * Get EEE own capabilities and negotiation result
1006 */
1007 int rtl930x_eee_port_ability(struct rtl838x_switch_priv *priv, struct ethtool_eee *e, int port)
1008 {
1009 u32 link, a;
1010
1011 if (port >= 26)
1012 return -ENOTSUPP;
1013
1014 pr_info("In %s, port %d\n", __func__, port);
1015 link = sw_r32(RTL930X_MAC_LINK_STS);
1016 link = sw_r32(RTL930X_MAC_LINK_STS);
1017 if (!(link & BIT(port)))
1018 return 0;
1019
1020 pr_info("Setting advertised\n");
1021 if (sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(10))
1022 e->advertised |= ADVERTISED_100baseT_Full;
1023
1024 if (sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(12))
1025 e->advertised |= ADVERTISED_1000baseT_Full;
1026
1027 if (priv->ports[port].is2G5 && sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(13)) {
1028 pr_info("ADVERTISING 2.5G EEE\n");
1029 e->advertised |= ADVERTISED_2500baseX_Full;
1030 }
1031
1032 if (priv->ports[port].is10G && sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(15))
1033 e->advertised |= ADVERTISED_10000baseT_Full;
1034
1035 a = sw_r32(RTL930X_MAC_EEE_ABLTY);
1036 a = sw_r32(RTL930X_MAC_EEE_ABLTY);
1037 pr_info("Link partner: %08x\n", a);
1038 if (a & BIT(port)) {
1039 e->lp_advertised = ADVERTISED_100baseT_Full;
1040 e->lp_advertised |= ADVERTISED_1000baseT_Full;
1041 if (priv->ports[port].is2G5)
1042 e->lp_advertised |= ADVERTISED_2500baseX_Full;
1043 if (priv->ports[port].is10G)
1044 e->lp_advertised |= ADVERTISED_10000baseT_Full;
1045 }
1046
1047 // Read 2x to clear latched state
1048 a = sw_r32(RTL930X_EEEP_PORT_CTRL(port));
1049 a = sw_r32(RTL930X_EEEP_PORT_CTRL(port));
1050 pr_info("%s RTL930X_EEEP_PORT_CTRL: %08x\n", __func__, a);
1051
1052 return 0;
1053 }
1054
1055 static void rtl930x_init_eee(struct rtl838x_switch_priv *priv, bool enable)
1056 {
1057 int i;
1058
1059 pr_info("Setting up EEE, state: %d\n", enable);
1060
1061 // Setup EEE on all ports
1062 for (i = 0; i < priv->cpu_port; i++) {
1063 if (priv->ports[i].phy)
1064 rtl930x_port_eee_set(priv, i, enable);
1065 }
1066
1067 priv->eee_enabled = enable;
1068 }
1069
1070 static void rtl930x_pie_lookup_enable(struct rtl838x_switch_priv *priv, int index)
1071 {
1072 int block = index / PIE_BLOCK_SIZE;
1073
1074 sw_w32_mask(0, BIT(block), RTL930X_PIE_BLK_LOOKUP_CTRL);
1075 }
1076
1077 /*
1078 * Reads the intermediate representation of the templated match-fields of the
1079 * PIE rule in the pie_rule structure and fills in the raw data fields in the
1080 * raw register space r[].
1081 * The register space configuration size is identical for the RTL8380/90 and RTL9300,
1082 * however the RTL9310 has 2 more registers / fields and the physical field-ids are different
1083 * on all SoCs
1084 * On the RTL9300 the mask fields are not word-aligend!
1085 */
1086 static void rtl930x_write_pie_templated(u32 r[], struct pie_rule *pr, enum template_field_id t[])
1087 {
1088 int i;
1089 enum template_field_id field_type;
1090 u16 data, data_m;
1091
1092 for (i = 0; i < N_FIXED_FIELDS; i++) {
1093 field_type = t[i];
1094 data = data_m = 0;
1095
1096 switch (field_type) {
1097 case TEMPLATE_FIELD_SPM0:
1098 data = pr->spm;
1099 data_m = pr->spm_m;
1100 break;
1101 case TEMPLATE_FIELD_SPM1:
1102 data = pr->spm >> 16;
1103 data_m = pr->spm_m >> 16;
1104 break;
1105 case TEMPLATE_FIELD_OTAG:
1106 data = pr->otag;
1107 data_m = pr->otag_m;
1108 break;
1109 case TEMPLATE_FIELD_SMAC0:
1110 data = pr->smac[4];
1111 data = (data << 8) | pr->smac[5];
1112 data_m = pr->smac_m[4];
1113 data_m = (data_m << 8) | pr->smac_m[5];
1114 break;
1115 case TEMPLATE_FIELD_SMAC1:
1116 data = pr->smac[2];
1117 data = (data << 8) | pr->smac[3];
1118 data_m = pr->smac_m[2];
1119 data_m = (data_m << 8) | pr->smac_m[3];
1120 break;
1121 case TEMPLATE_FIELD_SMAC2:
1122 data = pr->smac[0];
1123 data = (data << 8) | pr->smac[1];
1124 data_m = pr->smac_m[0];
1125 data_m = (data_m << 8) | pr->smac_m[1];
1126 break;
1127 case TEMPLATE_FIELD_DMAC0:
1128 data = pr->dmac[4];
1129 data = (data << 8) | pr->dmac[5];
1130 data_m = pr->dmac_m[4];
1131 data_m = (data_m << 8) | pr->dmac_m[5];
1132 break;
1133 case TEMPLATE_FIELD_DMAC1:
1134 data = pr->dmac[2];
1135 data = (data << 8) | pr->dmac[3];
1136 data_m = pr->dmac_m[2];
1137 data_m = (data_m << 8) | pr->dmac_m[3];
1138 break;
1139 case TEMPLATE_FIELD_DMAC2:
1140 data = pr->dmac[0];
1141 data = (data << 8) | pr->dmac[1];
1142 data_m = pr->dmac_m[0];
1143 data_m = (data_m << 8) | pr->dmac_m[1];
1144 break;
1145 case TEMPLATE_FIELD_ETHERTYPE:
1146 data = pr->ethertype;
1147 data_m = pr->ethertype_m;
1148 break;
1149 case TEMPLATE_FIELD_ITAG:
1150 data = pr->itag;
1151 data_m = pr->itag_m;
1152 break;
1153 case TEMPLATE_FIELD_SIP0:
1154 if (pr->is_ipv6) {
1155 data = pr->sip6.s6_addr16[7];
1156 data_m = pr->sip6_m.s6_addr16[7];
1157 } else {
1158 data = pr->sip;
1159 data_m = pr->sip_m;
1160 }
1161 break;
1162 case TEMPLATE_FIELD_SIP1:
1163 if (pr->is_ipv6) {
1164 data = pr->sip6.s6_addr16[6];
1165 data_m = pr->sip6_m.s6_addr16[6];
1166 } else {
1167 data = pr->sip >> 16;
1168 data_m = pr->sip_m >> 16;
1169 }
1170 break;
1171
1172 case TEMPLATE_FIELD_SIP2:
1173 case TEMPLATE_FIELD_SIP3:
1174 case TEMPLATE_FIELD_SIP4:
1175 case TEMPLATE_FIELD_SIP5:
1176 case TEMPLATE_FIELD_SIP6:
1177 case TEMPLATE_FIELD_SIP7:
1178 data = pr->sip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)];
1179 data_m = pr->sip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)];
1180 break;
1181
1182 case TEMPLATE_FIELD_DIP0:
1183 if (pr->is_ipv6) {
1184 data = pr->dip6.s6_addr16[7];
1185 data_m = pr->dip6_m.s6_addr16[7];
1186 } else {
1187 data = pr->dip;
1188 data_m = pr->dip_m;
1189 }
1190 break;
1191
1192 case TEMPLATE_FIELD_DIP1:
1193 if (pr->is_ipv6) {
1194 data = pr->dip6.s6_addr16[6];
1195 data_m = pr->dip6_m.s6_addr16[6];
1196 } else {
1197 data = pr->dip >> 16;
1198 data_m = pr->dip_m >> 16;
1199 }
1200 break;
1201
1202 case TEMPLATE_FIELD_DIP2:
1203 case TEMPLATE_FIELD_DIP3:
1204 case TEMPLATE_FIELD_DIP4:
1205 case TEMPLATE_FIELD_DIP5:
1206 case TEMPLATE_FIELD_DIP6:
1207 case TEMPLATE_FIELD_DIP7:
1208 data = pr->dip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)];
1209 data_m = pr->dip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)];
1210 break;
1211
1212 case TEMPLATE_FIELD_IP_TOS_PROTO:
1213 data = pr->tos_proto;
1214 data_m = pr->tos_proto_m;
1215 break;
1216 case TEMPLATE_FIELD_L4_SPORT:
1217 data = pr->sport;
1218 data_m = pr->sport_m;
1219 break;
1220 case TEMPLATE_FIELD_L4_DPORT:
1221 data = pr->dport;
1222 data_m = pr->dport_m;
1223 break;
1224 case TEMPLATE_FIELD_DSAP_SSAP:
1225 data = pr->dsap_ssap;
1226 data_m = pr->dsap_ssap_m;
1227 break;
1228 case TEMPLATE_FIELD_TCP_INFO:
1229 data = pr->tcp_info;
1230 data_m = pr->tcp_info_m;
1231 break;
1232 case TEMPLATE_FIELD_RANGE_CHK:
1233 pr_warn("Warning: TEMPLATE_FIELD_RANGE_CHK: not configured\n");
1234 break;
1235 default:
1236 pr_info("%s: unknown field %d\n", __func__, field_type);
1237 }
1238
1239 // On the RTL9300, the mask fields are not word aligned!
1240 if (!(i % 2)) {
1241 r[5 - i / 2] = data;
1242 r[12 - i / 2] |= ((u32)data_m << 8);
1243 } else {
1244 r[5 - i / 2] |= ((u32)data) << 16;
1245 r[12 - i / 2] |= ((u32)data_m) << 24;
1246 r[11 - i / 2] |= ((u32)data_m) >> 8;
1247 }
1248 }
1249 }
1250
1251 static void rtl930x_read_pie_fixed_fields(u32 r[], struct pie_rule *pr)
1252 {
1253 pr->stacking_port = r[6] & BIT(31);
1254 pr->spn = (r[6] >> 24) & 0x7f;
1255 pr->mgnt_vlan = r[6] & BIT(23);
1256 if (pr->phase == PHASE_IACL)
1257 pr->dmac_hit_sw = r[6] & BIT(22);
1258 else
1259 pr->content_too_deep = r[6] & BIT(22);
1260 pr->not_first_frag = r[6] & BIT(21);
1261 pr->frame_type_l4 = (r[6] >> 18) & 7;
1262 pr->frame_type = (r[6] >> 16) & 3;
1263 pr->otag_fmt = (r[6] >> 15) & 1;
1264 pr->itag_fmt = (r[6] >> 14) & 1;
1265 pr->otag_exist = (r[6] >> 13) & 1;
1266 pr->itag_exist = (r[6] >> 12) & 1;
1267 pr->frame_type_l2 = (r[6] >> 10) & 3;
1268 pr->igr_normal_port = (r[6] >> 9) & 1;
1269 pr->tid = (r[6] >> 8) & 1;
1270
1271 pr->stacking_port_m = r[12] & BIT(7);
1272 pr->spn_m = r[12] & 0x7f;
1273 pr->mgnt_vlan_m = r[13] & BIT(31);
1274 if (pr->phase == PHASE_IACL)
1275 pr->dmac_hit_sw_m = r[13] & BIT(30);
1276 else
1277 pr->content_too_deep_m = r[13] & BIT(30);
1278 pr->not_first_frag_m = r[13] & BIT(29);
1279 pr->frame_type_l4_m = (r[13] >> 26) & 7;
1280 pr->frame_type_m = (r[13] >> 24) & 3;
1281 pr->otag_fmt_m = r[13] & BIT(23);
1282 pr->itag_fmt_m = r[13] & BIT(22);
1283 pr->otag_exist_m = r[13] & BIT(21);
1284 pr->itag_exist_m = r[13] & BIT (20);
1285 pr->frame_type_l2_m = (r[13] >> 18) & 3;
1286 pr->igr_normal_port_m = r[13] & BIT(17);
1287 pr->tid_m = (r[13] >> 16) & 1;
1288
1289 pr->valid = r[13] & BIT(15);
1290 pr->cond_not = r[13] & BIT(14);
1291 pr->cond_and1 = r[13] & BIT(13);
1292 pr->cond_and2 = r[13] & BIT(12);
1293 }
1294
1295 static void rtl930x_write_pie_fixed_fields(u32 r[], struct pie_rule *pr)
1296 {
1297 r[6] = pr->stacking_port ? BIT(31) : 0;
1298 r[6] |= ((u32) (pr->spn & 0x7f)) << 24;
1299 r[6] |= pr->mgnt_vlan ? BIT(23) : 0;
1300 if (pr->phase == PHASE_IACL)
1301 r[6] |= pr->dmac_hit_sw ? BIT(22) : 0;
1302 else
1303 r[6] |= pr->content_too_deep ? BIT(22) : 0;
1304 r[6] |= pr->not_first_frag ? BIT(21) : 0;
1305 r[6] |= ((u32) (pr->frame_type_l4 & 0x7)) << 18;
1306 r[6] |= ((u32) (pr->frame_type & 0x3)) << 16;
1307 r[6] |= pr->otag_fmt ? BIT(15) : 0;
1308 r[6] |= pr->itag_fmt ? BIT(14) : 0;
1309 r[6] |= pr->otag_exist ? BIT(13) : 0;
1310 r[6] |= pr->itag_exist ? BIT(12) : 0;
1311 r[6] |= ((u32) (pr->frame_type_l2 & 0x3)) << 10;
1312 r[6] |= pr->igr_normal_port ? BIT(9) : 0;
1313 r[6] |= ((u32) (pr->tid & 0x1)) << 8;
1314
1315 r[12] |= pr->stacking_port_m ? BIT(7) : 0;
1316 r[12] |= (u32) (pr->spn_m & 0x7f);
1317 r[13] |= pr->mgnt_vlan_m ? BIT(31) : 0;
1318 if (pr->phase == PHASE_IACL)
1319 r[13] |= pr->dmac_hit_sw_m ? BIT(30) : 0;
1320 else
1321 r[13] |= pr->content_too_deep_m ? BIT(30) : 0;
1322 r[13] |= pr->not_first_frag_m ? BIT(29) : 0;
1323 r[13] |= ((u32) (pr->frame_type_l4_m & 0x7)) << 26;
1324 r[13] |= ((u32) (pr->frame_type_m & 0x3)) << 24;
1325 r[13] |= pr->otag_fmt_m ? BIT(23) : 0;
1326 r[13] |= pr->itag_fmt_m ? BIT(22) : 0;
1327 r[13] |= pr->otag_exist_m ? BIT(21) : 0;
1328 r[13] |= pr->itag_exist_m ? BIT(20) : 0;
1329 r[13] |= ((u32) (pr->frame_type_l2_m & 0x3)) << 18;
1330 r[13] |= pr->igr_normal_port_m ? BIT(17) : 0;
1331 r[13] |= ((u32) (pr->tid_m & 0x1)) << 16;
1332
1333 r[13] |= pr->valid ? BIT(15) : 0;
1334 r[13] |= pr->cond_not ? BIT(14) : 0;
1335 r[13] |= pr->cond_and1 ? BIT(13) : 0;
1336 r[13] |= pr->cond_and2 ? BIT(12) : 0;
1337 }
1338
1339 static void rtl930x_write_pie_action(u32 r[], struct pie_rule *pr)
1340 {
1341 // Either drop or forward
1342 if (pr->drop) {
1343 r[14] |= BIT(24) | BIT(25) | BIT(26); // Do Green, Yellow and Red drops
1344 // Actually DROP, not PERMIT in Green / Yellow / Red
1345 r[14] |= BIT(23) | BIT(22) | BIT(20);
1346 } else {
1347 r[14] |= pr->fwd_sel ? BIT(27) : 0;
1348 r[14] |= pr->fwd_act << 18;
1349 r[14] |= BIT(14); // We overwrite any drop
1350 }
1351 if (pr->phase == PHASE_VACL)
1352 r[14] |= pr->fwd_sa_lrn ? BIT(15) : 0;
1353 r[13] |= pr->bypass_sel ? BIT(5) : 0;
1354 r[13] |= pr->nopri_sel ? BIT(4) : 0;
1355 r[13] |= pr->tagst_sel ? BIT(3) : 0;
1356 r[13] |= pr->ovid_sel ? BIT(1) : 0;
1357 r[14] |= pr->ivid_sel ? BIT(31) : 0;
1358 r[14] |= pr->meter_sel ? BIT(30) : 0;
1359 r[14] |= pr->mir_sel ? BIT(29) : 0;
1360 r[14] |= pr->log_sel ? BIT(28) : 0;
1361
1362 r[14] |= ((u32)(pr->fwd_data & 0x3fff)) << 3;
1363 r[15] |= pr->log_octets ? BIT(31) : 0;
1364 r[15] |= (u32)(pr->meter_data) << 23;
1365
1366 r[15] |= ((u32)(pr->ivid_act) << 21) & 0x3;
1367 r[15] |= ((u32)(pr->ivid_data) << 9) & 0xfff;
1368 r[16] |= ((u32)(pr->ovid_act) << 30) & 0x3;
1369 r[16] |= ((u32)(pr->ovid_data) & 0xfff) << 16;
1370 r[16] |= (pr->mir_data & 0x3) << 6;
1371 r[17] |= ((u32)(pr->tagst_data) & 0xf) << 28;
1372 r[17] |= ((u32)(pr->nopri_data) & 0x7) << 25;
1373 r[17] |= pr->bypass_ibc_sc ? BIT(16) : 0;
1374 }
1375
1376 void rtl930x_pie_rule_dump_raw(u32 r[])
1377 {
1378 pr_info("Raw IACL table entry:\n");
1379 pr_info("r 0 - 7: %08x %08x %08x %08x %08x %08x %08x %08x\n",
1380 r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]);
1381 pr_info("r 8 - 15: %08x %08x %08x %08x %08x %08x %08x %08x\n",
1382 r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]);
1383 pr_info("r 16 - 18: %08x %08x %08x\n", r[16], r[17], r[18]);
1384 pr_info("Match : %08x %08x %08x %08x %08x %08x\n", r[0], r[1], r[2], r[3], r[4], r[5]);
1385 pr_info("Fixed : %06x\n", r[6] >> 8);
1386 pr_info("Match M: %08x %08x %08x %08x %08x %08x\n",
1387 (r[6] << 24) | (r[7] >> 8), (r[7] << 24) | (r[8] >> 8), (r[8] << 24) | (r[9] >> 8),
1388 (r[9] << 24) | (r[10] >> 8), (r[10] << 24) | (r[11] >> 8),
1389 (r[11] << 24) | (r[12] >> 8));
1390 pr_info("R[13]: %08x\n", r[13]);
1391 pr_info("Fixed M: %06x\n", ((r[12] << 16) | (r[13] >> 16)) & 0xffffff);
1392 pr_info("Valid / not / and1 / and2 : %1x\n", (r[13] >> 12) & 0xf);
1393 pr_info("r 13-16: %08x %08x %08x %08x\n", r[13], r[14], r[15], r[16]);
1394 }
1395
1396 static int rtl930x_pie_rule_write(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr)
1397 {
1398 // Access IACL table (2) via register 0
1399 struct table_reg *q = rtl_table_get(RTL9300_TBL_0, 2);
1400 u32 r[19];
1401 int i;
1402 int block = idx / PIE_BLOCK_SIZE;
1403 u32 t_select = sw_r32(RTL930X_PIE_BLK_TMPLTE_CTRL(block));
1404
1405 pr_debug("%s: %d, t_select: %08x\n", __func__, idx, t_select);
1406
1407 for (i = 0; i < 19; i++)
1408 r[i] = 0;
1409
1410 if (!pr->valid) {
1411 rtl_table_write(q, idx);
1412 rtl_table_release(q);
1413 return 0;
1414 }
1415 rtl930x_write_pie_fixed_fields(r, pr);
1416
1417 pr_debug("%s: template %d\n", __func__, (t_select >> (pr->tid * 4)) & 0xf);
1418 rtl930x_write_pie_templated(r, pr, fixed_templates[(t_select >> (pr->tid * 4)) & 0xf]);
1419
1420 rtl930x_write_pie_action(r, pr);
1421
1422 // rtl930x_pie_rule_dump_raw(r);
1423
1424 for (i = 0; i < 19; i++)
1425 sw_w32(r[i], rtl_table_data(q, i));
1426
1427 rtl_table_write(q, idx);
1428 rtl_table_release(q);
1429
1430 return 0;
1431 }
1432
1433 static bool rtl930x_pie_templ_has(int t, enum template_field_id field_type)
1434 {
1435 int i;
1436 enum template_field_id ft;
1437
1438 for (i = 0; i < N_FIXED_FIELDS; i++) {
1439 ft = fixed_templates[t][i];
1440 if (field_type == ft)
1441 return true;
1442 }
1443
1444 return false;
1445 }
1446
1447 /*
1448 * Verify that the rule pr is compatible with a given template t in block block
1449 * Note that this function is SoC specific since the values of e.g. TEMPLATE_FIELD_SIP0
1450 * depend on the SoC
1451 */
1452 static int rtl930x_pie_verify_template(struct rtl838x_switch_priv *priv,
1453 struct pie_rule *pr, int t, int block)
1454 {
1455 int i;
1456
1457 if (!pr->is_ipv6 && pr->sip_m && !rtl930x_pie_templ_has(t, TEMPLATE_FIELD_SIP0))
1458 return -1;
1459
1460 if (!pr->is_ipv6 && pr->dip_m && !rtl930x_pie_templ_has(t, TEMPLATE_FIELD_DIP0))
1461 return -1;
1462
1463 if (pr->is_ipv6) {
1464 if ((pr->sip6_m.s6_addr32[0] || pr->sip6_m.s6_addr32[1]
1465 || pr->sip6_m.s6_addr32[2] || pr->sip6_m.s6_addr32[3])
1466 && !rtl930x_pie_templ_has(t, TEMPLATE_FIELD_SIP2))
1467 return -1;
1468 if ((pr->dip6_m.s6_addr32[0] || pr->dip6_m.s6_addr32[1]
1469 || pr->dip6_m.s6_addr32[2] || pr->dip6_m.s6_addr32[3])
1470 && !rtl930x_pie_templ_has(t, TEMPLATE_FIELD_DIP2))
1471 return -1;
1472 }
1473
1474 if (ether_addr_to_u64(pr->smac) && !rtl930x_pie_templ_has(t, TEMPLATE_FIELD_SMAC0))
1475 return -1;
1476
1477 if (ether_addr_to_u64(pr->dmac) && !rtl930x_pie_templ_has(t, TEMPLATE_FIELD_DMAC0))
1478 return -1;
1479
1480 // TODO: Check more
1481
1482 i = find_first_zero_bit(&priv->pie_use_bm[block * 4], PIE_BLOCK_SIZE);
1483
1484 if (i >= PIE_BLOCK_SIZE)
1485 return -1;
1486
1487 return i + PIE_BLOCK_SIZE * block;
1488 }
1489
1490 static int rtl930x_pie_rule_add(struct rtl838x_switch_priv *priv, struct pie_rule *pr)
1491 {
1492 int idx, block, j, t;
1493 int min_block = 0;
1494 int max_block = priv->n_pie_blocks / 2;
1495
1496 if (pr->is_egress) {
1497 min_block = max_block;
1498 max_block = priv->n_pie_blocks;
1499 }
1500 pr_debug("In %s\n", __func__);
1501
1502 mutex_lock(&priv->pie_mutex);
1503
1504 for (block = min_block; block < max_block; block++) {
1505 for (j = 0; j < 2; j++) {
1506 t = (sw_r32(RTL930X_PIE_BLK_TMPLTE_CTRL(block)) >> (j * 4)) & 0xf;
1507 pr_debug("Testing block %d, template %d, template id %d\n", block, j, t);
1508 pr_debug("%s: %08x\n",
1509 __func__, sw_r32(RTL930X_PIE_BLK_TMPLTE_CTRL(block)));
1510 idx = rtl930x_pie_verify_template(priv, pr, t, block);
1511 if (idx >= 0)
1512 break;
1513 }
1514 if (j < 2)
1515 break;
1516 }
1517
1518 if (block >= priv->n_pie_blocks) {
1519 mutex_unlock(&priv->pie_mutex);
1520 return -EOPNOTSUPP;
1521 }
1522
1523 pr_debug("Using block: %d, index %d, template-id %d\n", block, idx, j);
1524 set_bit(idx, priv->pie_use_bm);
1525
1526 pr->valid = true;
1527 pr->tid = j; // Mapped to template number
1528 pr->tid_m = 0x1;
1529 pr->id = idx;
1530
1531 rtl930x_pie_lookup_enable(priv, idx);
1532 rtl930x_pie_rule_write(priv, idx, pr);
1533
1534 mutex_unlock(&priv->pie_mutex);
1535 return 0;
1536 }
1537
1538 /*
1539 * Delete a range of Packet Inspection Engine rules
1540 */
1541 static int rtl930x_pie_rule_del(struct rtl838x_switch_priv *priv, int index_from, int index_to)
1542 {
1543 u32 v = (index_from << 1)| (index_to << 12 ) | BIT(0);
1544
1545 pr_debug("%s: from %d to %d\n", __func__, index_from, index_to);
1546 mutex_lock(&priv->reg_mutex);
1547
1548 // Write from-to and execute bit into control register
1549 sw_w32(v, RTL930X_PIE_CLR_CTRL);
1550
1551 // Wait until command has completed
1552 do {
1553 } while (sw_r32(RTL930X_PIE_CLR_CTRL) & BIT(0));
1554
1555 mutex_unlock(&priv->reg_mutex);
1556 return 0;
1557 }
1558
1559 static void rtl930x_pie_rule_rm(struct rtl838x_switch_priv *priv, struct pie_rule *pr)
1560 {
1561 int idx = pr->id;
1562
1563 rtl930x_pie_rule_del(priv, idx, idx);
1564 clear_bit(idx, priv->pie_use_bm);
1565 }
1566
1567 static void rtl930x_pie_init(struct rtl838x_switch_priv *priv)
1568 {
1569 int i;
1570 u32 template_selectors;
1571
1572 mutex_init(&priv->pie_mutex);
1573
1574 pr_info("%s\n", __func__);
1575 // Enable ACL lookup on all ports, including CPU_PORT
1576 for (i = 0; i <= priv->cpu_port; i++)
1577 sw_w32(1, RTL930X_ACL_PORT_LOOKUP_CTRL(i));
1578
1579 // Include IPG in metering
1580 sw_w32_mask(0, 1, RTL930X_METER_GLB_CTRL);
1581
1582 // Delete all present rules, block size is 128 on all SoC families
1583 rtl930x_pie_rule_del(priv, 0, priv->n_pie_blocks * 128 - 1);
1584
1585 // Assign blocks 0-7 to VACL phase (bit = 0), blocks 8-15 to IACL (bit = 1)
1586 sw_w32(0xff00, RTL930X_PIE_BLK_PHASE_CTRL);
1587
1588 // Enable predefined templates 0, 1 for first quarter of all blocks
1589 template_selectors = 0 | (1 << 4);
1590 for (i = 0; i < priv->n_pie_blocks / 4; i++)
1591 sw_w32(template_selectors, RTL930X_PIE_BLK_TMPLTE_CTRL(i));
1592
1593 // Enable predefined templates 2, 3 for second quarter of all blocks
1594 template_selectors = 2 | (3 << 4);
1595 for (i = priv->n_pie_blocks / 4; i < priv->n_pie_blocks / 2; i++)
1596 sw_w32(template_selectors, RTL930X_PIE_BLK_TMPLTE_CTRL(i));
1597
1598 // Enable predefined templates 0, 1 for third half of all blocks
1599 template_selectors = 0 | (1 << 4);
1600 for (i = priv->n_pie_blocks / 2; i < priv->n_pie_blocks * 3 / 4; i++)
1601 sw_w32(template_selectors, RTL930X_PIE_BLK_TMPLTE_CTRL(i));
1602
1603 // Enable predefined templates 2, 3 for fourth quater of all blocks
1604 template_selectors = 2 | (3 << 4);
1605 for (i = priv->n_pie_blocks * 3 / 4; i < priv->n_pie_blocks; i++)
1606 sw_w32(template_selectors, RTL930X_PIE_BLK_TMPLTE_CTRL(i));
1607
1608 }
1609
1610 static u32 rtl930x_packet_cntr_read(int counter)
1611 {
1612 u32 v;
1613
1614 // Read LOG table (3) via register RTL9300_TBL_0
1615 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 3);
1616
1617 pr_debug("In %s, id %d\n", __func__, counter);
1618 rtl_table_read(r, counter / 2);
1619
1620 pr_debug("Registers: %08x %08x\n",
1621 sw_r32(rtl_table_data(r, 0)), sw_r32(rtl_table_data(r, 1)));
1622 // The table has a size of 2 registers
1623 if (counter % 2)
1624 v = sw_r32(rtl_table_data(r, 0));
1625 else
1626 v = sw_r32(rtl_table_data(r, 1));
1627
1628 rtl_table_release(r);
1629
1630 return v;
1631 }
1632
1633 static void rtl930x_packet_cntr_clear(int counter)
1634 {
1635 // Access LOG table (3) via register RTL9300_TBL_0
1636 struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 3);
1637
1638 pr_info("In %s, id %d\n", __func__, counter);
1639 // The table has a size of 2 registers
1640 if (counter % 2)
1641 sw_w32(0, rtl_table_data(r, 0));
1642 else
1643 sw_w32(0, rtl_table_data(r, 1));
1644
1645 rtl_table_write(r, counter / 2);
1646
1647 rtl_table_release(r);
1648 }
1649
1650 const struct rtl838x_reg rtl930x_reg = {
1651 .mask_port_reg_be = rtl838x_mask_port_reg,
1652 .set_port_reg_be = rtl838x_set_port_reg,
1653 .get_port_reg_be = rtl838x_get_port_reg,
1654 .mask_port_reg_le = rtl838x_mask_port_reg,
1655 .set_port_reg_le = rtl838x_set_port_reg,
1656 .get_port_reg_le = rtl838x_get_port_reg,
1657 .stat_port_rst = RTL930X_STAT_PORT_RST,
1658 .stat_rst = RTL930X_STAT_RST,
1659 .stat_port_std_mib = RTL930X_STAT_PORT_MIB_CNTR,
1660 .traffic_enable = rtl930x_traffic_enable,
1661 .traffic_disable = rtl930x_traffic_disable,
1662 .traffic_get = rtl930x_traffic_get,
1663 .traffic_set = rtl930x_traffic_set,
1664 .l2_ctrl_0 = RTL930X_L2_CTRL,
1665 .l2_ctrl_1 = RTL930X_L2_AGE_CTRL,
1666 .l2_port_aging_out = RTL930X_L2_PORT_AGE_CTRL,
1667 .smi_poll_ctrl = RTL930X_SMI_POLL_CTRL, // TODO: Difference to RTL9300_SMI_PRVTE_POLLING_CTRL
1668 .l2_tbl_flush_ctrl = RTL930X_L2_TBL_FLUSH_CTRL,
1669 .exec_tbl0_cmd = rtl930x_exec_tbl0_cmd,
1670 .exec_tbl1_cmd = rtl930x_exec_tbl1_cmd,
1671 .tbl_access_data_0 = rtl930x_tbl_access_data_0,
1672 .isr_glb_src = RTL930X_ISR_GLB,
1673 .isr_port_link_sts_chg = RTL930X_ISR_PORT_LINK_STS_CHG,
1674 .imr_port_link_sts_chg = RTL930X_IMR_PORT_LINK_STS_CHG,
1675 .imr_glb = RTL930X_IMR_GLB,
1676 .vlan_tables_read = rtl930x_vlan_tables_read,
1677 .vlan_set_tagged = rtl930x_vlan_set_tagged,
1678 .vlan_set_untagged = rtl930x_vlan_set_untagged,
1679 .vlan_profile_dump = rtl930x_vlan_profile_dump,
1680 .vlan_profile_setup = rtl930x_vlan_profile_setup,
1681 .vlan_fwd_on_inner = rtl930x_vlan_fwd_on_inner,
1682 .stp_get = rtl930x_stp_get,
1683 .stp_set = rtl930x_stp_set,
1684 .mac_force_mode_ctrl = rtl930x_mac_force_mode_ctrl,
1685 .mac_port_ctrl = rtl930x_mac_port_ctrl,
1686 .l2_port_new_salrn = rtl930x_l2_port_new_salrn,
1687 .l2_port_new_sa_fwd = rtl930x_l2_port_new_sa_fwd,
1688 .mir_ctrl = RTL930X_MIR_CTRL,
1689 .mir_dpm = RTL930X_MIR_DPM_CTRL,
1690 .mir_spm = RTL930X_MIR_SPM_CTRL,
1691 .mac_link_sts = RTL930X_MAC_LINK_STS,
1692 .mac_link_dup_sts = RTL930X_MAC_LINK_DUP_STS,
1693 .mac_link_spd_sts = rtl930x_mac_link_spd_sts,
1694 .mac_rx_pause_sts = RTL930X_MAC_RX_PAUSE_STS,
1695 .mac_tx_pause_sts = RTL930X_MAC_TX_PAUSE_STS,
1696 .read_l2_entry_using_hash = rtl930x_read_l2_entry_using_hash,
1697 .write_l2_entry_using_hash = rtl930x_write_l2_entry_using_hash,
1698 .read_cam = rtl930x_read_cam,
1699 .write_cam = rtl930x_write_cam,
1700 .vlan_port_egr_filter = RTL930X_VLAN_PORT_EGR_FLTR,
1701 .vlan_port_igr_filter = RTL930X_VLAN_PORT_IGR_FLTR(0),
1702 .vlan_port_pb = RTL930X_VLAN_PORT_PB_VLAN,
1703 .vlan_port_tag_sts_ctrl = RTL930X_VLAN_PORT_TAG_STS_CTRL,
1704 .trk_mbr_ctr = rtl930x_trk_mbr_ctr,
1705 .rma_bpdu_fld_pmask = RTL930X_RMA_BPDU_FLD_PMSK,
1706 .init_eee = rtl930x_init_eee,
1707 .port_eee_set = rtl930x_port_eee_set,
1708 .eee_port_ability = rtl930x_eee_port_ability,
1709 .read_mcast_pmask = rtl930x_read_mcast_pmask,
1710 .write_mcast_pmask = rtl930x_write_mcast_pmask,
1711 .pie_init = rtl930x_pie_init,
1712 .pie_rule_write = rtl930x_pie_rule_write,
1713 .pie_rule_add = rtl930x_pie_rule_add,
1714 .pie_rule_rm = rtl930x_pie_rule_rm,
1715 .packet_cntr_read = rtl930x_packet_cntr_read,
1716 .packet_cntr_clear = rtl930x_packet_cntr_clear,
1717 };