blob: 5b99b351af9a847247129053942f1423f8344363 [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001/*
2* switch_fun.c: switch function sets
3*/
4#include <stdio.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <string.h>
8#include <stdbool.h>
9#include <sys/ioctl.h>
10#include <sys/socket.h>
11#include <linux/if.h>
12#include <stdbool.h>
13#include <time.h>
developer997ed6b2024-03-26 14:03:42 +080014#include <errno.h>
developerfd40db22021-04-29 10:08:25 +080015
16#include "switch_extend.h"
17#include "switch_netlink.h"
18#include "switch_ioctl.h"
19#include "switch_fun.h"
20
21#define leaky_bucket 0
22
developerbe40a9e2024-03-07 21:44:26 +080023struct switch_func_s mt753x_switch_func = {
24 .pf_table_dump = table_dump,
25 .pf_table_clear = table_clear,
26 .pf_switch_reset = switch_reset,
27 .pf_doArlAging = doArlAging,
28 .pf_read_mib_counters = read_mib_counters,
29 .pf_clear_mib_counters = clear_mib_counters,
30 .pf_read_output_queue_counters = read_output_queue_counters,
31 .pf_read_free_page_counters = read_free_page_counters,
32 .pf_rate_control = rate_control,
33 .pf_igress_rate_set = ingress_rate_set,
34 .pf_egress_rate_set = egress_rate_set,
35 .pf_table_add = table_add,
36 .pf_table_del_fid = table_del_fid,
37 .pf_table_del_vid = table_del_vid,
38 .pf_table_search_mac_fid = table_search_mac_fid,
39 .pf_table_search_mac_vid = table_search_mac_vid,
40 .pf_global_set_mac_fc = global_set_mac_fc,
41 .pf_set_mac_pfc = set_mac_pfc,
42 .pf_qos_sch_select = qos_sch_select,
43 .pf_qos_set_base = qos_set_base,
44 .pf_qos_wfq_set_weight = qos_wfq_set_weight,
45 .pf_qos_set_portpri = qos_set_portpri,
46 .pf_qos_set_dscppri = qos_set_dscppri,
47 .pf_qos_pri_mapping_queue = qos_pri_mapping_queue,
48 .pf_doStp = doStp,
49 .pf_sip_dump = sip_dump,
50 .pf_sip_add = sip_add,
51 .pf_sip_del = sip_del,
52 .pf_sip_clear = sip_clear,
53 .pf_dip_dump = dip_dump,
54 .pf_dip_add = dip_add,
55 .pf_dip_del = dip_del,
56 .pf_dip_clear = dip_clear,
57 .pf_set_mirror_to = set_mirror_to,
58 .pf_set_mirror_from = set_mirror_from,
59 .pf_doMirrorEn = doMirrorEn,
60 .pf_doMirrorPortBased = doMirrorPortBased,
61 .pf_acl_dip_add = acl_dip_add,
62 .pf_acl_dip_modify = acl_dip_modify,
63 .pf_acl_dip_pppoe = acl_dip_pppoe,
64 .pf_acl_dip_trtcm = acl_dip_trtcm,
65 .pf_acl_dip_meter = acl_dip_meter,
66 .pf_acl_mac_add = acl_mac_add,
67 .pf_acl_ethertype = acl_ethertype,
68 .pf_acl_sp_add = acl_sp_add,
69 .pf_acl_l4_add = acl_l4_add,
70 .pf_acl_port_enable = acl_port_enable,
71 .pf_acl_table_add = acl_table_add,
72 .pf_acl_mask_table_add = acl_mask_table_add,
73 .pf_acl_rule_table_add = acl_rule_table_add,
74 .pf_acl_rate_table_add = acl_rate_table_add,
75 .pf_vlan_dump = vlan_dump,
76 .pf_vlan_set = vlan_set,
77 .pf_vlan_clear = vlan_clear,
78 .pf_doVlanSetVid = doVlanSetVid,
79 .pf_doVlanSetPvid = doVlanSetPvid,
80 .pf_doVlanSetAccFrm = doVlanSetAccFrm,
81 .pf_doVlanSetPortAttr = doVlanSetPortAttr,
82 .pf_doVlanSetPortMode = doVlanSetPortMode,
83 .pf_doVlanSetEgressTagPCR = doVlanSetEgressTagPCR,
84 .pf_doVlanSetEgressTagPVC = doVlanSetEgressTagPVC,
85 .pf_igmp_on = igmp_on,
86 .pf_igmp_off = igmp_off,
87 .pf_igmp_enable = igmp_enable,
88 .pf_igmp_disable = igmp_disable,
89 .pf_collision_pool_enable = collision_pool_enable,
90 .pf_collision_pool_mac_dump = collision_pool_mac_dump,
91 .pf_collision_pool_dip_dump = collision_pool_dip_dump,
92 .pf_collision_pool_sip_dump = collision_pool_sip_dump,
93 .pf_pfc_get_rx_counter = pfc_get_rx_counter,
94 .pf_pfc_get_tx_counter = pfc_get_tx_counter,
95 .pf_eee_enable = eee_enable,
96 .pf_eee_dump = eee_dump,
97};
98
developerfd40db22021-04-29 10:08:25 +080099static int getnext(char *src, int separator, char *dest)
100{
101 char *c;
102 int len;
103
104 if ((src == NULL) || (dest == NULL))
105 return -1;
106
107 c = strchr(src, separator);
108 if (c == NULL)
109 return -1;
110
111 len = c - src;
112 strncpy(dest, src, len);
113 dest[len] = '\0';
114 return len + 1;
115}
116
117static int str_to_ip(unsigned int *ip, char *str)
118{
119 int i;
120 int len;
121 char *ptr = str;
122 char buf[128];
123 unsigned char c[4];
124
125 for (i = 0; i < 3; ++i) {
126 if ((len = getnext(ptr, '.', buf)) == -1)
127 return 1;
128 c[i] = atoi(buf);
129 ptr += len;
130 }
131 c[3] = atoi(ptr);
132 *ip = (c[0] << 24) + (c[1] << 16) + (c[2] << 8) + c[3];
133 return 0;
134}
135
136/*convert IP address from number to string */
developer546b2792024-06-15 20:31:38 +0800137static void ip_to_str(char *str, size_t size, unsigned int ip)
developerfd40db22021-04-29 10:08:25 +0800138{
139 unsigned char *ptr = (unsigned char *)&ip;
140 unsigned char c[4];
developer546b2792024-06-15 20:31:38 +0800141 int ret;
142
143 if (str == NULL || size == 0) {
144 printf("convert IP address failed\n");
145 return;
146 }
developerfd40db22021-04-29 10:08:25 +0800147
148 c[0] = *(ptr);
149 c[1] = *(ptr + 1);
150 c[2] = *(ptr + 2);
151 c[3] = *(ptr + 3);
developer546b2792024-06-15 20:31:38 +0800152
153 ret = snprintf(str, size, "%d.%d.%d.%d", c[3], c[2], c[1], c[0]);
154 if (ret < 0) {
155 printf("Encoding error in snprintf\n");
156 return;
157 } else if ((size_t)ret >= size) {
158 printf("Required size %d, provided size %zu\n", ret, size);
159 return;
160 }
developerfd40db22021-04-29 10:08:25 +0800161}
162
163int reg_read(unsigned int offset, unsigned int *value)
164{
165 int ret = -1;
166
167 if (nl_init_flag == true) {
168 ret = reg_read_netlink(attres, offset, value);
169 } else {
170 if (attres->dev_id == -1)
171 ret = reg_read_ioctl(offset, value);
172 }
173 if (ret < 0) {
174 printf("Read fail\n");
175 *value = 0;
176 return ret;
177 }
178
179 return 0;
180}
181
182int reg_write(unsigned int offset, unsigned int value)
183{
184 int ret = -1;
185
186 if (nl_init_flag == true) {
187 ret = reg_write_netlink(attres, offset, value);
188 } else {
189 if (attres->dev_id == -1)
190 ret = reg_write_ioctl(offset, value);
191 }
192 if (ret < 0) {
193 printf("Write fail\n");
194 exit_free();
195 exit(0);
196 }
197 return 0;
198}
199
200int mii_mgr_read(unsigned int port_num, unsigned int reg, unsigned int *value)
201{
202 int ret;
203
204 if (port_num > 31) {
205 printf("Invalid Port or PHY addr \n");
206 return -1;
207 }
208
209 if (nl_init_flag == true)
210 ret = phy_cl22_read_netlink(attres, port_num, reg, value);
211 else
212 ret = mii_mgr_cl22_read_ioctl(port_num, reg, value);
213
214 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800215 printf("Phy cl22 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800216 exit_free();
217 exit(0);
218 }
219
220 return 0;
221}
222
223int mii_mgr_write(unsigned int port_num, unsigned int reg, unsigned int value)
224{
225 int ret;
226
227 if (port_num > 31) {
228 printf("Invalid Port or PHY addr \n");
229 return -1;
230 }
231
232 if (nl_init_flag == true)
233 ret = phy_cl22_write_netlink(attres, port_num, reg, value);
234 else
235 ret = mii_mgr_cl22_write_ioctl(port_num, reg, value);
236
237 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800238 printf("Phy cl22 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800239 exit_free();
240 exit(0);
241 }
242
243 return 0;
244}
245
developerbe40a9e2024-03-07 21:44:26 +0800246int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg,
247 unsigned int *value)
developerfd40db22021-04-29 10:08:25 +0800248{
249 int ret;
250
251 if (port_num > 31) {
252 printf("Invalid Port or PHY addr \n");
253 return -1;
254 }
255
256 if (nl_init_flag == true)
257 ret = phy_cl45_read_netlink(attres, port_num, dev, reg, value);
258 else
259 ret = mii_mgr_cl45_read_ioctl(port_num, dev, reg, value);
260
261 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800262 printf("Phy cl45 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800263 exit_free();
264 exit(0);
265 }
266
267 return 0;
268}
269
developerbe40a9e2024-03-07 21:44:26 +0800270int mii_mgr_c45_write(unsigned int port_num, unsigned int dev, unsigned int reg,
271 unsigned int value)
developerfd40db22021-04-29 10:08:25 +0800272{
273 int ret;
274
275 if (port_num > 31) {
276 printf("Invalid Port or PHY addr \n");
277 return -1;
278 }
279
280 if (nl_init_flag == true)
281 ret = phy_cl45_write_netlink(attres, port_num, dev, reg, value);
282 else
283 ret = mii_mgr_cl45_write_ioctl(port_num, dev, reg, value);
284
285 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800286 printf("Phy cl45 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800287 exit_free();
288 exit(0);
289 }
290
291 return 0;
292}
293
developerfd40db22021-04-29 10:08:25 +0800294int phy_dump(int phy_addr)
295{
296 int ret;
297
298 if (nl_init_flag == true)
299 ret = phy_dump_netlink(attres, phy_addr);
300 else
301 ret = phy_dump_ioctl(phy_addr);
302
303 if (ret < 0) {
304 printf("Phy dump fail\n");
305 exit_free();
306 exit(0);
307 }
308
309 return 0;
310}
311
312void phy_crossover(int argc, char *argv[])
313{
314 unsigned int port_num = strtoul(argv[2], NULL, 10);
developerbe40a9e2024-03-07 21:44:26 +0800315 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +0800316 int ret;
317
318 if (port_num > 4) {
319 printf("invaild value, port_name:0~4\n");
320 return;
321 }
322
323 if (nl_init_flag == true)
developerbe40a9e2024-03-07 21:44:26 +0800324 ret =
325 phy_cl45_read_netlink(attres, port_num, 0x1E,
326 MT7530_T10_TEST_CONTROL, &value);
developerfd40db22021-04-29 10:08:25 +0800327 else
developerbe40a9e2024-03-07 21:44:26 +0800328 ret =
329 mii_mgr_cl45_read_ioctl(port_num, 0x1E,
330 MT7530_T10_TEST_CONTROL, &value);
developerfd40db22021-04-29 10:08:25 +0800331 if (ret < 0) {
332 printf("phy_cl45 read fail\n");
333 exit_free();
334 exit(0);
335 }
336
337 printf("mii_mgr_cl45:");
developerbe40a9e2024-03-07 21:44:26 +0800338 printf("Read: port#=%d, device=0x%x, reg=0x%x, value=0x%x\n", port_num,
339 0x1E, MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800340
developerbe40a9e2024-03-07 21:44:26 +0800341 if (!strncmp(argv[3], "auto", 5)) {
developerfd40db22021-04-29 10:08:25 +0800342 value &= (~(0x3 << 3));
343 } else if (!strncmp(argv[3], "mdi", 4)) {
344 value &= (~(0x3 << 3));
345 value |= (0x2 << 3);
346 } else if (!strncmp(argv[3], "mdix", 5)) {
347 value |= (0x3 << 3);
348 } else {
349 printf("invaild parameter\n");
350 return;
351 }
developerbe40a9e2024-03-07 21:44:26 +0800352 printf("Write: port#=%d, device=0x%x, reg=0x%x. value=0x%x\n", port_num,
353 0x1E, MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800354
355 if (nl_init_flag == true)
developerbe40a9e2024-03-07 21:44:26 +0800356 ret =
357 phy_cl45_write_netlink(attres, port_num, 0x1E,
358 MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800359 else
developerbe40a9e2024-03-07 21:44:26 +0800360 ret =
361 mii_mgr_cl45_write_ioctl(port_num, 0x1E,
362 MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800363
364 if (ret < 0) {
365 printf("phy_cl45 write fail\n");
366 exit_free();
367 exit(0);
368 }
369}
370
371int rw_phy_token_ring(int argc, char *argv[])
372{
373 int ch_addr, node_addr, data_addr;
374 unsigned int tr_reg_control;
375 unsigned int val_l = 0;
376 unsigned int val_h = 0;
377 unsigned int port_num;
developer2fdae312024-06-15 20:36:12 +0800378 char *endptr;
developerfd40db22021-04-29 10:08:25 +0800379
380 if (argc < 4)
381 return -1;
382
383 if (argv[2][0] == 'r') {
384 if (argc != 7)
385 return -1;
developerbe40a9e2024-03-07 21:44:26 +0800386 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
developer2fdae312024-06-15 20:36:12 +0800387
388 errno = 0;
389 port_num = strtoul(argv[3], &endptr, 10);
390 if (errno != 0 || *endptr != '\0' || port_num > MAX_PORT) {
developerfd40db22021-04-29 10:08:25 +0800391 printf("Illegal port index and port:0~6\n");
392 return -1;
393 }
developer2fdae312024-06-15 20:36:12 +0800394
395 errno = 0;
396 ch_addr = strtoul(argv[4], &endptr, 10);
397 if (errno != 0 || *endptr != '\0')
398 goto error;
399
400 errno = 0;
401 node_addr = strtoul(argv[5], &endptr, 16);
402 if (errno != 0 || *endptr != '\0')
403 goto error;
404
405 errno = 0;
406 data_addr = strtoul(argv[6], &endptr, 16);
407 if (errno != 0 || *endptr != '\0')
408 goto error;
409
developerbe40a9e2024-03-07 21:44:26 +0800410 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n",
411 port_num, ch_addr, node_addr, data_addr);
412 tr_reg_control =
413 (1 << 15) | (1 << 13) | (ch_addr << 11) | (node_addr << 7) |
414 (data_addr << 1);
415 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
developerfd40db22021-04-29 10:08:25 +0800416 mii_mgr_read(port_num, 17, &val_l);
417 mii_mgr_read(port_num, 18, &val_h);
developerbe40a9e2024-03-07 21:44:26 +0800418 printf
419 ("switch trreg read tr_reg_control=%x, value_H=%x, value_L=%x\n",
420 tr_reg_control, val_h, val_l);
developerfd40db22021-04-29 10:08:25 +0800421 } else if (argv[2][0] == 'w') {
422 if (argc != 9)
423 return -1;
developerbe40a9e2024-03-07 21:44:26 +0800424 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
developer2fdae312024-06-15 20:36:12 +0800425
426 errno = 0;
427 port_num = strtoul(argv[3], &endptr, 10);
428 if (errno != 0 || *endptr != '\0' || port_num > MAX_PORT) {
429 printf("Illegal port index and port:0~6\n");
developerfd40db22021-04-29 10:08:25 +0800430 return -1;
431 }
developer2fdae312024-06-15 20:36:12 +0800432
433 errno = 0;
434 ch_addr = strtoul(argv[4], &endptr, 10);
435 if (errno != 0 || *endptr != '\0')
436 goto error;
437
438 errno = 0;
439 node_addr = strtoul(argv[5], &endptr, 16);
440 if (errno != 0 || *endptr != '\0')
441 goto error;
442
443 errno = 0;
444 data_addr = strtoul(argv[6], &endptr, 16);
445 if (errno != 0 || *endptr != '\0')
446 goto error;
447
448 errno = 0;
449 val_h = strtoul(argv[7], &endptr, 16);
450 if (errno != 0 || *endptr != '\0')
451 goto error;
452
453 errno = 0;
454 val_l = strtoul(argv[8], &endptr, 16);
455 if (errno != 0 || *endptr != '\0')
456 goto error;
457
developerbe40a9e2024-03-07 21:44:26 +0800458 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n",
459 port_num, ch_addr, node_addr, data_addr);
460 tr_reg_control =
461 (1 << 15) | (0 << 13) | (ch_addr << 11) | (node_addr << 7) |
462 (data_addr << 1);
developerfd40db22021-04-29 10:08:25 +0800463 mii_mgr_write(port_num, 17, val_l);
464 mii_mgr_write(port_num, 18, val_h);
developerbe40a9e2024-03-07 21:44:26 +0800465 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
466 printf
467 ("switch trreg Write tr_reg_control=%x, value_H=%x, value_L=%x\n",
468 tr_reg_control, val_h, val_l);
developerfd40db22021-04-29 10:08:25 +0800469 } else
470 return -1;
developer2fdae312024-06-15 20:36:12 +0800471
developerfd40db22021-04-29 10:08:25 +0800472 return 0;
developer2fdae312024-06-15 20:36:12 +0800473
474error:
475 printf("\n**Illegal parameters\n");
476 return -1;
developerfd40db22021-04-29 10:08:25 +0800477}
478
developerbe40a9e2024-03-07 21:44:26 +0800479void write_acl_table(unsigned char tbl_idx, unsigned int vawd1,
480 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800481{
developerbe40a9e2024-03-07 21:44:26 +0800482 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800483 unsigned int max_index;
484
developer8c3871b2022-07-01 14:07:53 +0800485 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800486 max_index = 256;
487 else
488 max_index = 64;
489
490 printf("Pattern_acl_tbl_idx:%d\n", tbl_idx);
491
492 if (tbl_idx >= max_index) {
493 printf(HELP_ACL_ACL_TBL_ADD);
494 return;
495 }
496
497 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800498 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800499 reg_read(reg, &value);
500 if ((value & REG_VTCR_BUSY_MASK) == 0) {
501 break;
502 }
503 }
504 reg_write(REG_VAWD1_ADDR, vawd1);
505 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
506 reg_write(REG_VAWD2_ADDR, vawd2);
507 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
508 reg = REG_VTCR_ADDR;
509 value = REG_VTCR_BUSY_MASK | (0x05 << REG_VTCR_FUNC_OFFT) | tbl_idx;
510 reg_write(reg, value);
511 printf("write reg: %x, value: %x\n", reg, value);
512
developerbe40a9e2024-03-07 21:44:26 +0800513 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800514 reg_read(reg, &value);
515 if ((value & REG_VTCR_BUSY_MASK) == 0)
516 break;
517 }
518}
519
520void acl_table_add(int argc, char *argv[])
521{
developerbe40a9e2024-03-07 21:44:26 +0800522 unsigned int vawd1 = 0, vawd2 = 0;
523 unsigned char tbl_idx = 0;
developer546b2792024-06-15 20:31:38 +0800524 char *endptr;
developerfd40db22021-04-29 10:08:25 +0800525
developer546b2792024-06-15 20:31:38 +0800526 errno = 0;
527 tbl_idx = strtoul(argv[3], &endptr, 10);
528 if (errno != 0 || *endptr != '\0') {
529 printf("Error: wrong ACL rule table index\n");
530 return;
531 }
532
533 errno = 0;
534 vawd1 = strtoul(argv[4], &endptr, 16);
535 if (errno != 0 || *endptr != '\0') {
536 printf("Error: wrong ACL rule table write data 1\n");
537 return;
538 }
539
540 errno = 0;
541 vawd2 = strtoul(argv[5], &endptr, 16);
542 if (errno != 0 || *endptr != '\0') {
543 printf("Error: wrong ACL rule table write data 2\n");
544 return;
545 }
546
developerfd40db22021-04-29 10:08:25 +0800547 write_acl_table(tbl_idx, vawd1, vawd2);
548}
549
developerbe40a9e2024-03-07 21:44:26 +0800550void write_acl_mask_table(unsigned char tbl_idx, unsigned int vawd1,
551 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800552{
developerbe40a9e2024-03-07 21:44:26 +0800553 unsigned int value = 0, reg = 0;
554 unsigned int max_index = 0;
developerfd40db22021-04-29 10:08:25 +0800555
developer8c3871b2022-07-01 14:07:53 +0800556 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800557 max_index = 128;
558 else
559 max_index = 32;
560
561 printf("Rule_mask_tbl_idx:%d\n", tbl_idx);
562
563 if (tbl_idx >= max_index) {
564 printf(HELP_ACL_MASK_TBL_ADD);
565 return;
566 }
567 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800568 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800569 reg_read(reg, &value);
570 if ((value & REG_VTCR_BUSY_MASK) == 0)
571 break;
572 }
573 reg_write(REG_VAWD1_ADDR, vawd1);
574 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
575 reg_write(REG_VAWD2_ADDR, vawd2);
576 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
577 reg = REG_VTCR_ADDR;
578 value = REG_VTCR_BUSY_MASK | (0x09 << REG_VTCR_FUNC_OFFT) | tbl_idx;
579 reg_write(reg, value);
580 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +0800581 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800582 reg_read(reg, &value);
583 if ((value & REG_VTCR_BUSY_MASK) == 0)
584 break;
585 }
586}
587
588void acl_mask_table_add(int argc, char *argv[])
589{
developerbe40a9e2024-03-07 21:44:26 +0800590 unsigned int vawd1 = 0, vawd2 = 0;
591 unsigned char tbl_idx = 0;
developer546b2792024-06-15 20:31:38 +0800592 char *endptr;
developerfd40db22021-04-29 10:08:25 +0800593
developer546b2792024-06-15 20:31:38 +0800594 errno = 0;
595 tbl_idx = strtoul(argv[3], &endptr, 10);
596 if (errno != 0 || *endptr != '\0') {
597 printf("Error: wrong ACL mask table index\n");
598 return;
599 }
600
601 errno = 0;
602 vawd1 = strtoul(argv[4], &endptr, 16);
603 if (errno != 0 || *endptr != '\0') {
604 printf("Error: wrong ACL mask table write data 1\n");
605 return;
606 }
607
608 errno = 0;
609 vawd2 = strtoul(argv[5], &endptr, 16);
610 if (errno != 0 || *endptr != '\0') {
611 printf("Error: wrong ACL mask table write data 2\n");
612 return;
613 }
614
developerfd40db22021-04-29 10:08:25 +0800615 write_acl_mask_table(tbl_idx, vawd1, vawd2);
616}
617
developerbe40a9e2024-03-07 21:44:26 +0800618void write_acl_rule_table(unsigned char tbl_idx, unsigned int vawd1,
619 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800620{
developerbe40a9e2024-03-07 21:44:26 +0800621 unsigned int value = 0, reg = 0;
622 unsigned int max_index = 0;
developerfd40db22021-04-29 10:08:25 +0800623
developer8c3871b2022-07-01 14:07:53 +0800624 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800625 max_index = 128;
626 else
627 max_index = 32;
628
629 printf("Rule_control_tbl_idx:%d\n", tbl_idx);
630
developerbe40a9e2024-03-07 21:44:26 +0800631 if (tbl_idx >= max_index) { /* Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +0800632 printf(HELP_ACL_RULE_TBL_ADD);
633 return;
634 }
635 reg = REG_VTCR_ADDR;
636
developerbe40a9e2024-03-07 21:44:26 +0800637 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800638 reg_read(reg, &value);
639 if ((value & REG_VTCR_BUSY_MASK) == 0) {
640 break;
641 }
642 }
643 reg_write(REG_VAWD1_ADDR, vawd1);
644 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
645 reg_write(REG_VAWD2_ADDR, vawd2);
646 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
647 reg = REG_VTCR_ADDR;
648 value = REG_VTCR_BUSY_MASK | (0x0B << REG_VTCR_FUNC_OFFT) | tbl_idx;
649 reg_write(reg, value);
650 printf("write reg: %x, value: %x\n", reg, value);
651
developerbe40a9e2024-03-07 21:44:26 +0800652 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800653 reg_read(reg, &value);
654 if ((value & REG_VTCR_BUSY_MASK) == 0) {
655 break;
656 }
657 }
658}
659
660void acl_rule_table_add(int argc, char *argv[])
661{
developerbe40a9e2024-03-07 21:44:26 +0800662 unsigned int vawd1 = 0, vawd2 = 0;
663 unsigned char tbl_idx = 0;
developer546b2792024-06-15 20:31:38 +0800664 char *endptr;
665
666 errno = 0;
667 tbl_idx = strtoul(argv[3], &endptr, 10);
668 if (errno != 0 || *endptr != '\0') {
669 printf("Error: wrong ACL rule control table index\n");
670 return;
671 }
672
673 errno = 0;
674 vawd1 = strtoul(argv[4], &endptr, 16);
675 if (errno != 0 || *endptr != '\0') {
676 printf("Error: wrong ACL rule control table write data 1\n");
677 return;
678 }
679
680 errno = 0;
681 vawd2 = strtoul(argv[5], &endptr, 16);
682 if (errno != 0 || *endptr != '\0') {
683 printf("Error: wrong ACL rule control table write data 2\n");
684 return;
685 }
developerfd40db22021-04-29 10:08:25 +0800686
developerfd40db22021-04-29 10:08:25 +0800687 write_acl_rule_table(tbl_idx, vawd1, vawd2);
688}
689
developerbe40a9e2024-03-07 21:44:26 +0800690void write_rate_table(unsigned char tbl_idx, unsigned int vawd1,
691 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800692{
developerbe40a9e2024-03-07 21:44:26 +0800693 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800694 unsigned int max_index = 32;
695
696 printf("Rule_action_tbl_idx:%d\n", tbl_idx);
697
698 if (tbl_idx >= max_index) {
699 printf(HELP_ACL_RATE_TBL_ADD);
700 return;
701 }
702
703 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800704 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800705 reg_read(reg, &value);
706 if ((value & REG_VTCR_BUSY_MASK) == 0)
707 break;
708 }
709
710 reg_write(REG_VAWD1_ADDR, vawd1);
711 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
712 reg_write(REG_VAWD2_ADDR, vawd2);
713 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
714 reg = REG_VTCR_ADDR;
715 value = REG_VTCR_BUSY_MASK | (0x0D << REG_VTCR_FUNC_OFFT) | tbl_idx;
716 reg_write(reg, value);
717 printf("write reg: %x, value: %x\n", reg, value);
718
developerbe40a9e2024-03-07 21:44:26 +0800719 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800720 reg_read(reg, &value);
721 if ((value & REG_VTCR_BUSY_MASK) == 0)
722 break;
723 }
724}
725
726void acl_rate_table_add(int argc, char *argv[])
727{
developerbe40a9e2024-03-07 21:44:26 +0800728 unsigned int vawd1 = 0, vawd2 = 0;
729 unsigned char tbl_idx = 0;
developer546b2792024-06-15 20:31:38 +0800730 char *endptr;
developerfd40db22021-04-29 10:08:25 +0800731
developer546b2792024-06-15 20:31:38 +0800732 errno = 0;
733 tbl_idx = strtoul(argv[3], &endptr, 10);
734 if (errno != 0 || *endptr != '\0') {
735 printf("Error: wrong ACL rate control table index\n");
736 return;
737 }
738
739 errno = 0;
740 vawd1 = strtoul(argv[4], &endptr, 16);
741 if (errno != 0 || *endptr != '\0') {
742 printf("Error: wrong ACL rate control table write data 1\n");
743 return;
744 }
745
746 errno = 0;
747 vawd2 = strtoul(argv[5], &endptr, 16);
748 if (errno != 0 || *endptr != '\0') {
749 printf("Error: wrong ACL rate control table write data 2\n");
750 return;
751 }
developerfd40db22021-04-29 10:08:25 +0800752
753 write_rate_table(tbl_idx, vawd1, vawd2);
754}
755
developerbe40a9e2024-03-07 21:44:26 +0800756void write_trTCM_table(unsigned char tbl_idx, unsigned int vawd1,
757 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800758{
developerbe40a9e2024-03-07 21:44:26 +0800759 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800760 unsigned int max_index = 32;
761
762 printf("trTCM_tbl_idx:%d\n", tbl_idx);
763
764 if (tbl_idx >= max_index) {
765 printf(HELP_ACL_TRTCM_TBL_ADD);
766 return;
767 }
768
769 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800770 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800771 reg_read(reg, &value);
772 if ((value & REG_VTCR_BUSY_MASK) == 0)
773 break;
774 }
775
776 reg_write(REG_VAWD1_ADDR, vawd1);
777 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
778 reg_write(REG_VAWD2_ADDR, vawd2);
779 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
780 reg = REG_VTCR_ADDR;
781 value = REG_VTCR_BUSY_MASK | (0x07 << REG_VTCR_FUNC_OFFT) | tbl_idx;
782 reg_write(reg, value);
783 printf("write reg: %x, value: %x\n", reg, value);
784
developerbe40a9e2024-03-07 21:44:26 +0800785 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800786 reg_read(reg, &value);
787 if ((value & REG_VTCR_BUSY_MASK) == 0)
788 break;
789 }
790}
791
developerbe40a9e2024-03-07 21:44:26 +0800792int acl_parameters_pre_del(int len1, int len2, int argc, char *argv[],
793 int *port)
developerfd40db22021-04-29 10:08:25 +0800794{
developerbe40a9e2024-03-07 21:44:26 +0800795 int i = 0;
developerfd40db22021-04-29 10:08:25 +0800796
797 *port = 0;
798 if (argc < len1) {
799 printf("insufficient arguments!\n");
800 return -1;
801 }
802
developerbe40a9e2024-03-07 21:44:26 +0800803 if (len2 == 12) {
developerfd40db22021-04-29 10:08:25 +0800804 if (!argv[4] || strlen(argv[4]) != len2) {
developerbe40a9e2024-03-07 21:44:26 +0800805 printf
806 ("The [%s] format error, should be of length %d\n",
807 argv[4], len2);
developerfd40db22021-04-29 10:08:25 +0800808 return -1;
809 }
810 }
811
812 if (!argv[5] || strlen(argv[5]) != 8) {
813 printf("portsmap format error, should be of length 7\n");
814 return -1;
815 }
816
817 for (i = 0; i < 7; i++) {
818 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +0800819 printf
820 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +0800821 return -1;
822 }
823 *port += (argv[5][i] - '0') * (1 << i);
824 }
825 return 0;
826}
827
developerbe40a9e2024-03-07 21:44:26 +0800828void acl_compare_pattern(int ports, int comparion, int base, int word,
829 unsigned char table_index)
developerfd40db22021-04-29 10:08:25 +0800830{
developerbe40a9e2024-03-07 21:44:26 +0800831 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +0800832
developerbe40a9e2024-03-07 21:44:26 +0800833 comparion |= 0xffff0000; //compare mask
developerfd40db22021-04-29 10:08:25 +0800834
developerbe40a9e2024-03-07 21:44:26 +0800835 value = ports << 8; //w_port_map
836 value |= 0x1 << 19; //enable
837 value |= base << 16; //mac header
838 value |= word << 1; //word offset
developerfd40db22021-04-29 10:08:25 +0800839
840 write_acl_table(table_index, comparion, value);
841}
842
843void acl_mac_add(int argc, char *argv[])
844{
developerbe40a9e2024-03-07 21:44:26 +0800845 unsigned int value = 0;
846 int ports = 0;
developerfd40db22021-04-29 10:08:25 +0800847 char tmpstr[5];
848 int ret;
developer546b2792024-06-15 20:31:38 +0800849 char *endptr;
developerfd40db22021-04-29 10:08:25 +0800850
851 ret = acl_parameters_pre_del(6, 12, argc, argv, &ports);
852 if (ret < 0)
853 return;
developerbe40a9e2024-03-07 21:44:26 +0800854 /* Set pattern */
developerfd40db22021-04-29 10:08:25 +0800855 strncpy(tmpstr, argv[4], 4);
856 tmpstr[4] = '\0';
developer546b2792024-06-15 20:31:38 +0800857 errno = 0;
858 value = strtoul(tmpstr, &endptr, 16);
859 if (errno != 0 || *endptr != '\0')
860 goto error;
861
developerfd40db22021-04-29 10:08:25 +0800862 acl_compare_pattern(ports, value, 0x0, 0, 0);
863
864 strncpy(tmpstr, argv[4] + 4, 4);
865 tmpstr[4] = '\0';
developer546b2792024-06-15 20:31:38 +0800866 errno = 0;
867 value = strtoul(tmpstr, &endptr, 16);
868 if (errno != 0 || *endptr != '\0')
869 goto error;
developerfd40db22021-04-29 10:08:25 +0800870 acl_compare_pattern(ports, value, 0x0, 1, 1);
871
872 strncpy(tmpstr, argv[4] + 8, 4);
873 tmpstr[4] = '\0';
developer546b2792024-06-15 20:31:38 +0800874 errno = 0;
875 value = strtoul(tmpstr, &endptr, 16);
876 if (errno != 0 || *endptr != '\0')
877 goto error;
developerfd40db22021-04-29 10:08:25 +0800878 acl_compare_pattern(ports, value, 0x0, 2, 2);
879
880 //set mask
developerbe40a9e2024-03-07 21:44:26 +0800881 write_acl_mask_table(0, 0x7, 0);
developerfd40db22021-04-29 10:08:25 +0800882
883 //set action
developerbe40a9e2024-03-07 21:44:26 +0800884 value = 0x7; //drop
885 value |= 1 << 28; //acl intterupt enable
886 value |= 1 << 27; //acl hit count
887 value |= 2 << 24; //acl hit count group index (0~3)
888 write_acl_rule_table(0, value, 0);
developer546b2792024-06-15 20:31:38 +0800889 return;
890
891error:
892 printf("Error: string converting\n");
893 return;
developerfd40db22021-04-29 10:08:25 +0800894}
895
896void acl_dip_meter(int argc, char *argv[])
897{
developerbe40a9e2024-03-07 21:44:26 +0800898 unsigned int value = 0, ip_value = 0, meter = 0;
899 int ports = 0;
developerfd40db22021-04-29 10:08:25 +0800900 int ret;
901
902 ip_value = 0;
903 ret = acl_parameters_pre_del(7, -1, argc, argv, &ports);
904 if (ret < 0)
905 return;
906
907 str_to_ip(&ip_value, argv[4]);
908 //set pattern
909 value = (ip_value >> 16);
910 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
911
912 //set pattern
913 value = (ip_value & 0xffff);
914 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
915
916 //set mask
developerbe40a9e2024-03-07 21:44:26 +0800917 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800918
919 //set action
920 meter = strtoul(argv[6], NULL, 0);
921 if (((chip_name == 0x7530) && (meter > 1000000)) ||
developerbe40a9e2024-03-07 21:44:26 +0800922 ((chip_name == 0x7531) && (meter > 2500000)) ||
923 ((chip_name == 0x7988) && (meter > 4000000))) {
developer8c3871b2022-07-01 14:07:53 +0800924 printf("\n**Illegal meter input, and 7530: 0~1000000Kpbs, 7531: 0~2500000Kpbs, 7988: 0~4000000Kpbs**\n");
developerfd40db22021-04-29 10:08:25 +0800925 return;
926 }
developer8c3871b2022-07-01 14:07:53 +0800927 if (((chip_name == 0x7531 || chip_name == 0x7988) && (meter > 1000000))) {
developerbe40a9e2024-03-07 21:44:26 +0800928 reg_read(0xc, &value);
developerfd40db22021-04-29 10:08:25 +0800929 value |= 0x1 << 30;
developerbe40a9e2024-03-07 21:44:26 +0800930 reg_write(0xC, value);
931 printf("AGC: 0x%x\n", value);
932 value = meter / 1000; //uint is 1Mbps
developerfd40db22021-04-29 10:08:25 +0800933 } else {
developerbe40a9e2024-03-07 21:44:26 +0800934 reg_read(0xc, &value);
developerfd40db22021-04-29 10:08:25 +0800935 value &= ~(0x1 << 30);
developerbe40a9e2024-03-07 21:44:26 +0800936 reg_write(0xC, value);
937 printf("AGC: 0x%x\n", value);
938 value = meter >> 6; //uint is 64Kbps
developerfd40db22021-04-29 10:08:25 +0800939 }
developerbe40a9e2024-03-07 21:44:26 +0800940 value |= 0x1 << 15; //enable rate control
941 printf("Acl rate control:0x%x\n", value);
developerfd40db22021-04-29 10:08:25 +0800942 write_rate_table(0, value, 0);
943}
944
945void acl_dip_trtcm(int argc, char *argv[])
946{
947 unsigned int value, value2, ip_value;
948 unsigned int CIR, CBS, PIR, PBS;
949 int ports;
950 int ret;
951
952 ip_value = 0;
953 ret = acl_parameters_pre_del(10, -1, argc, argv, &ports);
954 if (ret < 0)
955 return;
956
957 str_to_ip(&ip_value, argv[4]);
958 //set pattern
959 value = (ip_value >> 16);
960 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
961
962 //set pattern
963 value = (ip_value & 0xffff);
964 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
965
966 //set CBS PBS
967 CIR = strtoul(argv[6], NULL, 0);
968 CBS = strtoul(argv[7], NULL, 0);
969 PIR = strtoul(argv[8], NULL, 0);
970 PBS = strtoul(argv[9], NULL, 0);
971
developerbe40a9e2024-03-07 21:44:26 +0800972 if (CIR > 65535 * 64 || CBS > 65535 || PIR > 65535 * 64 || PBS > 65535) {
developerfd40db22021-04-29 10:08:25 +0800973 printf("\n**Illegal input parameters**\n");
974 return;
975 }
976
developerbe40a9e2024-03-07 21:44:26 +0800977 value = CBS << 16; //bit16~31
978 value |= PBS; //bit0~15
979 //value |= 1;//valid
developerfd40db22021-04-29 10:08:25 +0800980 CIR = CIR >> 6;
981 PIR = PIR >> 6;
982
developerbe40a9e2024-03-07 21:44:26 +0800983 value2 = CIR << 16; //bit16~31
984 value2 |= PIR; //bit0~15
985 write_trTCM_table(0, value, value2);
developerfd40db22021-04-29 10:08:25 +0800986
987 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800988 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800989
990 //set action
developerbe40a9e2024-03-07 21:44:26 +0800991 value = 0x1 << (11 + 1); //TrTCM green meter#0 Low drop
992 value |= 0x2 << (8 + 1); //TrTCM yellow meter#0 Med drop
993 value |= 0x3 << (5 + 1); //TrTCM red meter#0 Hig drop
994 value |= 0x1 << 0; //TrTCM drop pcd select
995 write_acl_rule_table(0, 0, value);
developerfd40db22021-04-29 10:08:25 +0800996}
997
998void acl_ethertype(int argc, char *argv[])
999{
1000 unsigned int value, ethertype;
1001 int ports;
1002 int ret;
1003
1004 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1005 if (ret < 0)
1006 return;
developerbe40a9e2024-03-07 21:44:26 +08001007 printf("ports:0x%x\n", ports);
developerfd40db22021-04-29 10:08:25 +08001008 ethertype = strtoul(argv[4], NULL, 16);
1009 //set pattern
1010 value = ethertype;
1011 acl_compare_pattern(ports, value, 0x0, 0x6, 0);
1012
1013 //set pattern
developerbe40a9e2024-03-07 21:44:26 +08001014 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +08001015
1016 //set action(drop)
developerbe40a9e2024-03-07 21:44:26 +08001017 value = 0x7; //default. Nodrop
1018 value |= 1 << 28; //acl intterupt enable
1019 value |= 1 << 27; //acl hit count
developerfd40db22021-04-29 10:08:25 +08001020
developerbe40a9e2024-03-07 21:44:26 +08001021 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001022}
1023
1024void acl_dip_modify(int argc, char *argv[])
1025{
1026 unsigned int value, ip_value;
1027 int ports;
1028 int priority;
1029 int ret;
1030
1031 ip_value = 0;
1032 priority = strtoul(argv[6], NULL, 16);
1033 if (priority < 0 || priority > 7) {
1034 printf("\n**Illegal priority value!**\n");
1035 return;
1036 }
1037
1038 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1039 if (ret < 0)
1040 return;
1041
1042 str_to_ip(&ip_value, argv[4]);
1043 //set pattern
1044 value = (ip_value >> 16);
1045 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
1046
1047 //set pattern
1048 value = (ip_value & 0xffff);
1049 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
1050
1051 //set pattern
developerbe40a9e2024-03-07 21:44:26 +08001052 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +08001053
1054 //set action
developerbe40a9e2024-03-07 21:44:26 +08001055 value = 0x0; //default. Nodrop
1056 value |= 1 << 28; //acl intterupt enable
1057 value |= 1 << 27; //acl hit count
1058 value |= priority << 4; //acl UP
1059 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001060}
1061
1062void acl_dip_pppoe(int argc, char *argv[])
1063{
1064 unsigned int value, ip_value;
1065 int ports;
1066 int ret;
1067
1068 ip_value = 0;
1069 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1070 if (ret < 0)
1071 return;
1072
1073 str_to_ip(&ip_value, argv[4]);
1074 //set pattern
1075 value = (ip_value >> 16);
1076 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
1077
1078 //set pattern
1079 value = (ip_value & 0xffff);
1080 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
1081
1082 //set pattern
developerbe40a9e2024-03-07 21:44:26 +08001083 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +08001084
1085 //set action
developerbe40a9e2024-03-07 21:44:26 +08001086 value = 0x0; //default. Nodrop
1087 value |= 1 << 28; //acl intterupt enable
1088 value |= 1 << 27; //acl hit count
1089 value |= 1 << 20; //pppoe header remove
1090 value |= 1 << 21; //SA MAC SWAP
1091 value |= 1 << 22; //DA MAC SWAP
1092 write_acl_rule_table(0, value, 7);
developerfd40db22021-04-29 10:08:25 +08001093}
1094
1095void acl_dip_add(int argc, char *argv[])
1096{
1097 unsigned int value, ip_value;
1098 int ports;
1099 int ret;
1100
1101 ip_value = 0;
1102 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1103 if (ret < 0)
1104 return;
1105
1106 str_to_ip(&ip_value, argv[4]);
1107 //set pattern
1108 value = (ip_value >> 16);
1109 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
1110
1111 //set pattern
1112 value = (ip_value & 0xffff);
1113 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
1114
1115 //set pattern
developerbe40a9e2024-03-07 21:44:26 +08001116 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +08001117
1118 //set action
1119 //value = 0x0; //default
developerbe40a9e2024-03-07 21:44:26 +08001120 value = 0x7; //drop
1121 value |= 1 << 28; //acl intterupt enable
1122 value |= 1 << 27; //acl hit count
1123 value |= 2 << 24; //acl hit count group index (0~3)
1124 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001125}
1126
1127void acl_l4_add(int argc, char *argv[])
1128{
developerbe40a9e2024-03-07 21:44:26 +08001129 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001130 int ports;
1131 int ret;
1132
1133 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1134 if (ret < 0)
1135 return;
1136
1137 //set pattern
1138 value = strtoul(argv[4], NULL, 16);
1139 acl_compare_pattern(ports, value, 0x5, 0x0, 0);
1140
1141 //set rue mask
developerbe40a9e2024-03-07 21:44:26 +08001142 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +08001143 //set action
developerbe40a9e2024-03-07 21:44:26 +08001144 value = 0x7; //drop
1145 //value |= 1;//valid
1146 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001147}
1148
1149void acl_sp_add(int argc, char *argv[])
1150{
developerbe40a9e2024-03-07 21:44:26 +08001151 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001152 int ports;
1153 int ret;
1154
1155 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1156 if (ret < 0)
1157 return;
1158 //set pattern
1159 value = strtoul(argv[4], NULL, 0);
1160 acl_compare_pattern(ports, value, 0x4, 0x0, 0);
1161
1162 //set rue mask
developerbe40a9e2024-03-07 21:44:26 +08001163 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +08001164
1165 //set action
developerbe40a9e2024-03-07 21:44:26 +08001166 value = 0x7; //drop
1167 //value |= 1;//valid
1168 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001169}
1170
1171void acl_port_enable(int argc, char *argv[])
1172{
developerbe40a9e2024-03-07 21:44:26 +08001173 unsigned int value = 0, reg = 0;
1174 unsigned char acl_port = 0, acl_en = 0;
developer546b2792024-06-15 20:31:38 +08001175 char *endptr;
developerfd40db22021-04-29 10:08:25 +08001176
developer546b2792024-06-15 20:31:38 +08001177 errno = 0;
1178 acl_port = strtoul(argv[3], &endptr, 10);
1179 if (errno != 0 || *endptr != '\0' || acl_port > MAX_PORT) {
1180 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
1181 return;
1182 }
developerfd40db22021-04-29 10:08:25 +08001183
developer546b2792024-06-15 20:31:38 +08001184 errno = 0;
1185 acl_en = strtoul(argv[4], &endptr, 10);
1186 if (errno != 0 || *endptr != '\0' || acl_en > 1) {
developerfd40db22021-04-29 10:08:25 +08001187 printf(HELP_ACL_SETPORTEN);
1188 return;
1189 }
1190
developer546b2792024-06-15 20:31:38 +08001191 printf("acl_port:%d, acl_en:%d\n", acl_port, acl_en);
1192
developerbe40a9e2024-03-07 21:44:26 +08001193 reg = REG_PCR_P0_ADDR + (0x100 * acl_port); // 0x2004[10]
developerfd40db22021-04-29 10:08:25 +08001194 reg_read(reg, &value);
1195 value &= (~REG_PORT_ACL_EN_MASK);
1196 value |= (acl_en << REG_PORT_ACL_EN_OFFT);
1197
1198 printf("write reg: %x, value: %x\n", reg, value);
1199 reg_write(reg, value);
1200}
1201
1202static void dip_dump_internal(int type)
1203{
1204 unsigned int i, j, value, mac, mac2, value2;
developerbe40a9e2024-03-07 21:44:26 +08001205 char tmpstr[16] = { 0 };
developerfd40db22021-04-29 10:08:25 +08001206 int table_size = 0;
1207 int hit_value1 = 0;
1208 int hit_value2 = 0;
1209
developerbe40a9e2024-03-07 21:44:26 +08001210 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001211 table_size = 0x800;
developerbe40a9e2024-03-07 21:44:26 +08001212 reg_write(REG_ATC_ADDR, 0x8104); //dip search command
1213 } else {
developerfd40db22021-04-29 10:08:25 +08001214 table_size = 0x40;
developerbe40a9e2024-03-07 21:44:26 +08001215 reg_write(REG_ATC_ADDR, 0x811c); //dip search command
developerfd40db22021-04-29 10:08:25 +08001216 }
developerbe40a9e2024-03-07 21:44:26 +08001217 printf
1218 ("hash port(0:6) rsp_cnt flag timer dip-address ATRD\n");
developerfd40db22021-04-29 10:08:25 +08001219 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001220 while (1) {
developerfd40db22021-04-29 10:08:25 +08001221 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001222 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001223 hit_value1 = value & (0x1 << 13);
1224 hit_value2 = 1;
developerbe40a9e2024-03-07 21:44:26 +08001225 } else {
developerfd40db22021-04-29 10:08:25 +08001226 hit_value1 = value & (0x1 << 13);
1227 hit_value2 = value & (0x1 << 28);
1228 }
1229
developerbe40a9e2024-03-07 21:44:26 +08001230 if (hit_value1 && hit_value2) { //search_rdy
developerfd40db22021-04-29 10:08:25 +08001231 reg_read(REG_ATRD_ADDR, &value2);
1232 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1233
developerbe40a9e2024-03-07 21:44:26 +08001234 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1235 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001236 printf("%c", (j & 0x01) ? '1' : '-');
1237 printf("%c", (j & 0x02) ? '1' : '-');
1238 printf("%c", (j & 0x04) ? '1' : '-');
1239 printf("%c ", (j & 0x08) ? '1' : '-');
1240 printf("%c", (j & 0x10) ? '1' : '-');
1241 printf("%c", (j & 0x20) ? '1' : '-');
1242 printf("%c", (j & 0x40) ? '1' : '-');
1243
1244 reg_read(REG_TSRA2_ADDR, &mac2);
1245
developerbe40a9e2024-03-07 21:44:26 +08001246 printf(" 0x%4x", (mac2 & 0xffff)); //RESP_CNT
1247 printf(" 0x%2x", ((mac2 >> 16) & 0xff)); //RESP_FLAG
1248 printf(" %3d", ((mac2 >> 24) & 0xff)); //RESP_TIMER
1249 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001250 reg_read(REG_TSRA1_ADDR, &mac);
developer546b2792024-06-15 20:31:38 +08001251 ip_to_str(tmpstr, sizeof(tmpstr), mac);
developerfd40db22021-04-29 10:08:25 +08001252 printf(" %s", tmpstr);
developerbe40a9e2024-03-07 21:44:26 +08001253 printf(" 0x%8x\n", value2); //ATRD
1254 //printf("%04x", ((mac2 >> 16) & 0xffff));
1255 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
developerfd40db22021-04-29 10:08:25 +08001256 if (value & 0x4000) {
1257 printf("end of table %d\n", i);
1258 return;
1259 }
1260 break;
developerbe40a9e2024-03-07 21:44:26 +08001261 } else if (value & 0x4000) { //at_table_end
1262 printf("found the last entry %d (not ready)\n",
1263 i);
developerfd40db22021-04-29 10:08:25 +08001264 return;
1265 }
1266 usleep(5000);
1267 }
1268
developerbe40a9e2024-03-07 21:44:26 +08001269 if (type == GENERAL_TABLE)
1270 reg_write(REG_ATC_ADDR, 0x8105); //search for next dip address
developerfd40db22021-04-29 10:08:25 +08001271 else
developerbe40a9e2024-03-07 21:44:26 +08001272 reg_write(REG_ATC_ADDR, 0x811d); //search for next dip address
developerfd40db22021-04-29 10:08:25 +08001273 usleep(5000);
1274 }
1275}
1276
developerbe40a9e2024-03-07 21:44:26 +08001277void dip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001278{
1279 dip_dump_internal(GENERAL_TABLE);
1280
1281}
1282
1283void dip_add(int argc, char *argv[])
1284{
1285 unsigned int value = 0;
developerbe40a9e2024-03-07 21:44:26 +08001286 unsigned int i = 0, j = 0;
developerfd40db22021-04-29 10:08:25 +08001287
1288 value = 0;
1289
1290 str_to_ip(&value, argv[3]);
1291
1292 reg_write(REG_ATA1_ADDR, value);
1293 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1294
1295#if 0
1296 reg_write(REG_ATA2_ADDR, value);
1297 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1298#endif
1299 if (!argv[4] || strlen(argv[4]) != 8) {
1300 printf("portmap format error, should be of length 7\n");
1301 return;
1302 }
1303 j = 0;
1304 for (i = 0; i < 7; i++) {
1305 if (argv[4][i] != '0' && argv[4][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001306 printf
1307 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001308 return;
1309 }
1310 j += (argv[4][i] - '0') * (1 << i);
1311 }
developerbe40a9e2024-03-07 21:44:26 +08001312 value = j << 4; //w_port_map
1313 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001314
1315 reg_write(REG_ATWD_ADDR, value);
1316
1317 usleep(5000);
1318 reg_read(REG_ATWD_ADDR, &value);
1319 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1320
developerbe40a9e2024-03-07 21:44:26 +08001321 value = 0x8011; //single w_dip_cmd
developerfd40db22021-04-29 10:08:25 +08001322 reg_write(REG_ATC_ADDR, value);
1323
1324 usleep(1000);
1325
1326 for (i = 0; i < 20; i++) {
1327 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001328 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001329 printf("done.\n");
1330 return;
1331 }
1332 usleep(1000);
1333 }
1334 if (i == 20)
1335 printf("timeout.\n");
1336}
1337
1338void dip_del(int argc, char *argv[])
1339{
1340 unsigned int i, value;
1341
1342 value = 0;
1343 str_to_ip(&value, argv[3]);
1344
1345 reg_write(REG_ATA1_ADDR, value);
1346
1347 value = 0;
1348 reg_write(REG_ATA2_ADDR, value);
1349
developerbe40a9e2024-03-07 21:44:26 +08001350 value = 0; //STATUS=0, delete dip
developerfd40db22021-04-29 10:08:25 +08001351 reg_write(REG_ATWD_ADDR, value);
1352
developerbe40a9e2024-03-07 21:44:26 +08001353 value = 0x8011; //w_dip_cmd
developerfd40db22021-04-29 10:08:25 +08001354 reg_write(REG_ATC_ADDR, value);
1355
1356 for (i = 0; i < 20; i++) {
1357 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001358 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001359 if (argv[1] != NULL)
1360 printf("done.\n");
1361 return;
1362 }
1363 usleep(1000);
1364 }
1365 if (i == 20)
1366 printf("timeout.\n");
1367}
1368
developerbe40a9e2024-03-07 21:44:26 +08001369void dip_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001370{
1371
developerbe40a9e2024-03-07 21:44:26 +08001372 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001373
developerbe40a9e2024-03-07 21:44:26 +08001374 reg_write(REG_ATC_ADDR, 0x8102); //clear all dip
developerfd40db22021-04-29 10:08:25 +08001375 usleep(5000);
1376 reg_read(REG_ATC_ADDR, &value);
1377 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1378}
1379
1380static void sip_dump_internal(int type)
1381{
developerbe40a9e2024-03-07 21:44:26 +08001382 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001383 int table_size = 0;
1384 int hit_value1 = 0;
1385 int hit_value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08001386 char tmpstr[16] = { 0 };
developerfd40db22021-04-29 10:08:25 +08001387
1388 if (type == GENERAL_TABLE) {
1389 table_size = 0x800;
developerbe40a9e2024-03-07 21:44:26 +08001390 reg_write(REG_ATC_ADDR, 0x8204); //sip search command
1391 } else {
developerfd40db22021-04-29 10:08:25 +08001392 table_size = 0x40;
developerbe40a9e2024-03-07 21:44:26 +08001393 reg_write(REG_ATC_ADDR, 0x822c); //sip search command
developerfd40db22021-04-29 10:08:25 +08001394 }
1395 printf("hash port(0:6) dip-address sip-address ATRD\n");
1396 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001397 while (1) {
developerfd40db22021-04-29 10:08:25 +08001398 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001399 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001400 hit_value1 = value & (0x1 << 13);
1401 hit_value2 = 1;
1402 } else {
1403 hit_value1 = value & (0x1 << 13);
1404 hit_value2 = value & (0x1 << 28);
1405 }
1406
developerbe40a9e2024-03-07 21:44:26 +08001407 if (hit_value1 && hit_value2) { //search_rdy
developerfd40db22021-04-29 10:08:25 +08001408 reg_read(REG_ATRD_ADDR, &value2);
1409 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1410
developerbe40a9e2024-03-07 21:44:26 +08001411 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1412 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001413 printf("%c", (j & 0x01) ? '1' : '-');
1414 printf("%c", (j & 0x02) ? '1' : '-');
1415 printf("%c", (j & 0x04) ? '1' : '-');
1416 printf("%c", (j & 0x08) ? '1' : '-');
1417 printf(" %c", (j & 0x10) ? '1' : '-');
1418 printf("%c", (j & 0x20) ? '1' : '-');
1419 printf("%c", (j & 0x40) ? '1' : '-');
1420
1421 reg_read(REG_TSRA2_ADDR, &mac2);
1422
developer546b2792024-06-15 20:31:38 +08001423 ip_to_str(tmpstr, sizeof(tmpstr), mac2);
developerfd40db22021-04-29 10:08:25 +08001424 printf(" %s", tmpstr);
1425
1426 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
1427 reg_read(REG_TSRA1_ADDR, &mac);
developer546b2792024-06-15 20:31:38 +08001428 ip_to_str(tmpstr, sizeof(tmpstr), mac);
developerfd40db22021-04-29 10:08:25 +08001429 printf(" %s", tmpstr);
1430 printf(" 0x%x\n", value2);
1431 //printf("%04x", ((mac2 >> 16) & 0xffff));
1432 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
1433 if (value & 0x4000) {
1434 printf("end of table %d\n", i);
1435 return;
1436 }
1437 break;
developerbe40a9e2024-03-07 21:44:26 +08001438 } else if (value & 0x4000) { //at_table_end
1439 printf("found the last entry %d (not ready)\n",
1440 i);
developerfd40db22021-04-29 10:08:25 +08001441 return;
1442 }
1443 usleep(5000);
1444 }
1445
developerbe40a9e2024-03-07 21:44:26 +08001446 if (type == GENERAL_TABLE)
1447 reg_write(REG_ATC_ADDR, 0x8205); //search for next sip address
1448 else
1449 reg_write(REG_ATC_ADDR, 0x822d); //search for next sip address
1450 usleep(5000);
developerfd40db22021-04-29 10:08:25 +08001451 }
1452}
1453
developerbe40a9e2024-03-07 21:44:26 +08001454void sip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001455{
1456
1457 sip_dump_internal(GENERAL_TABLE);
1458
1459}
1460
developerfd40db22021-04-29 10:08:25 +08001461void sip_add(int argc, char *argv[])
1462{
developerbe40a9e2024-03-07 21:44:26 +08001463 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001464
1465 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08001466 str_to_ip(&value, argv[3]); //SIP
developerfd40db22021-04-29 10:08:25 +08001467
1468 reg_write(REG_ATA2_ADDR, value);
1469 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1470
1471 value = 0;
1472
developerbe40a9e2024-03-07 21:44:26 +08001473 str_to_ip(&value, argv[4]); //DIP
developerfd40db22021-04-29 10:08:25 +08001474 reg_write(REG_ATA1_ADDR, value);
1475 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1476
1477 if (!argv[5] || strlen(argv[5]) != 8) {
1478 printf("portmap format error, should be of length 7\n");
1479 return;
1480 }
1481 j = 0;
1482 for (i = 0; i < 7; i++) {
1483 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001484 printf
1485 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001486 return;
1487 }
1488 j += (argv[5][i] - '0') * (1 << i);
1489 }
developerbe40a9e2024-03-07 21:44:26 +08001490 value = j << 4; //w_port_map
1491 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001492
1493 reg_write(REG_ATWD_ADDR, value);
1494
1495 usleep(5000);
1496 reg_read(REG_ATWD_ADDR, &value);
1497 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1498
developerbe40a9e2024-03-07 21:44:26 +08001499 value = 0x8021; //single w_sip_cmd
developerfd40db22021-04-29 10:08:25 +08001500 reg_write(REG_ATC_ADDR, value);
1501
1502 usleep(1000);
1503
1504 for (i = 0; i < 20; i++) {
1505 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001506 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001507 printf("done.\n");
1508 return;
1509 }
1510 usleep(1000);
1511 }
1512 if (i == 20)
1513 printf("timeout.\n");
1514}
1515
1516void sip_del(int argc, char *argv[])
1517{
developerbe40a9e2024-03-07 21:44:26 +08001518 unsigned int i = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001519
1520 value = 0;
1521 str_to_ip(&value, argv[3]);
1522
developerbe40a9e2024-03-07 21:44:26 +08001523 reg_write(REG_ATA2_ADDR, value); //SIP
developerfd40db22021-04-29 10:08:25 +08001524
1525 str_to_ip(&value, argv[4]);
developerbe40a9e2024-03-07 21:44:26 +08001526 reg_write(REG_ATA1_ADDR, value); //DIP
developerfd40db22021-04-29 10:08:25 +08001527
developerbe40a9e2024-03-07 21:44:26 +08001528 value = 0; //STATUS=0, delete sip
developerfd40db22021-04-29 10:08:25 +08001529 reg_write(REG_ATWD_ADDR, value);
1530
developerbe40a9e2024-03-07 21:44:26 +08001531 value = 0x8021; //w_sip_cmd
developerfd40db22021-04-29 10:08:25 +08001532 reg_write(REG_ATC_ADDR, value);
1533
1534 for (i = 0; i < 20; i++) {
1535 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001536 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001537 if (argv[1] != NULL)
1538 printf("done.\n");
1539 return;
1540 }
1541 usleep(1000);
1542 }
1543 if (i == 20)
1544 printf("timeout.\n");
1545}
1546
developerbe40a9e2024-03-07 21:44:26 +08001547void sip_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001548{
developerbe40a9e2024-03-07 21:44:26 +08001549 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001550
developerbe40a9e2024-03-07 21:44:26 +08001551 reg_write(REG_ATC_ADDR, 0x8202); //clear all sip
developerfd40db22021-04-29 10:08:25 +08001552 usleep(5000);
1553 reg_read(REG_ATC_ADDR, &value);
1554 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1555}
1556
1557static void table_dump_internal(int type)
1558{
developerbe40a9e2024-03-07 21:44:26 +08001559 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001560 int table_size = 0;
1561 int table_end = 0;
1562 int hit_value1 = 0;
1563 int hit_value2 = 0;
1564
developerbe40a9e2024-03-07 21:44:26 +08001565 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001566 table_size = 0x800;
1567 table_end = 0x7FF;
1568 reg_write(REG_ATC_ADDR, 0x8004);
1569 } else {
1570 table_size = 0x40;
1571 table_end = 0x3F;
1572 reg_write(REG_ATC_ADDR, 0x800C);
1573 }
developerbe40a9e2024-03-07 21:44:26 +08001574 printf
1575 ("hash port(0:6) fid vid age(s) mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001576 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001577 while (1) {
developerfd40db22021-04-29 10:08:25 +08001578 reg_read(REG_ATC_ADDR, &value);
1579 //printf("ATC = 0x%x\n", value);
developerbe40a9e2024-03-07 21:44:26 +08001580 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001581 hit_value1 = value & (0x1 << 13);
1582 hit_value2 = 1;
1583 } else {
1584 hit_value1 = value & (0x1 << 13);
1585 hit_value2 = value & (0x1 << 28);
1586 }
1587
developerbe40a9e2024-03-07 21:44:26 +08001588 if (hit_value1 && hit_value2
1589 && (((value >> 15) & 0x1) == 0)) {
developerfd40db22021-04-29 10:08:25 +08001590 printf("%03x: ", (value >> 16) & 0xfff);
1591 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001592 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001593 printf("%c", (j & 0x01) ? '1' : '-');
1594 printf("%c", (j & 0x02) ? '1' : '-');
1595 printf("%c", (j & 0x04) ? '1' : '-');
1596 printf("%c", (j & 0x08) ? '1' : '-');
1597 printf("%c", (j & 0x10) ? '1' : '-');
1598 printf("%c", (j & 0x20) ? '1' : '-');
1599 printf("%c", (j & 0x40) ? '1' : '-');
1600 printf("%c", (j & 0x80) ? '1' : '-');
1601
1602 reg_read(REG_TSRA2_ADDR, &mac2);
1603
developerbe40a9e2024-03-07 21:44:26 +08001604 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001605 printf(" %4d", (mac2 & 0xfff));
1606 if (((value2 >> 24) & 0xff) == 0xFF)
developerbe40a9e2024-03-07 21:44:26 +08001607 printf(" --- "); //r_age_field:static
developerfd40db22021-04-29 10:08:25 +08001608 else
developerbe40a9e2024-03-07 21:44:26 +08001609 printf(" %5d ", (((value2 >> 24) & 0xff) + 1) * 2); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001610 reg_read(REG_TSRA1_ADDR, &mac);
1611 printf(" %08x", mac);
1612 printf("%04x", ((mac2 >> 16) & 0xffff));
developerbe40a9e2024-03-07 21:44:26 +08001613 printf(" %c",
1614 (((value2 >> 20) & 0x03) ==
1615 0x03) ? 'y' : '-');
1616 printf(" %c\n",
1617 (((value2 >> 23) & 0x01) ==
1618 0x01) ? 'y' : '-');
1619 if ((value & 0x4000)
1620 && (((value >> 16) & 0xfff) == table_end)) {
developerfd40db22021-04-29 10:08:25 +08001621 printf("end of table %d\n", i);
1622 return;
1623 }
1624 break;
developerbe40a9e2024-03-07 21:44:26 +08001625 } else if ((value & 0x4000) && (((value >> 15) & 0x1) == 0) && (((value >> 16) & 0xfff) == table_end)) { //at_table_end
1626 printf("found the last entry %d (not ready)\n",
1627 i);
developerfd40db22021-04-29 10:08:25 +08001628 return;
developerbe40a9e2024-03-07 21:44:26 +08001629 } else
developerfd40db22021-04-29 10:08:25 +08001630 usleep(5);
1631 }
1632
developerbe40a9e2024-03-07 21:44:26 +08001633 if (type == GENERAL_TABLE)
1634 reg_write(REG_ATC_ADDR, 0x8005); //search for next address
1635 else
1636 reg_write(REG_ATC_ADDR, 0x800d); //search for next address
developerfd40db22021-04-29 10:08:25 +08001637 usleep(5);
1638 }
1639}
1640
developerbe40a9e2024-03-07 21:44:26 +08001641void table_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001642{
1643 table_dump_internal(GENERAL_TABLE);
1644
1645}
1646
developerfd40db22021-04-29 10:08:25 +08001647void table_add(int argc, char *argv[])
1648{
developerbe40a9e2024-03-07 21:44:26 +08001649 unsigned int i = 0, j = 0, value = 0, is_filter = 0, is_mymac = 0;
developerfd40db22021-04-29 10:08:25 +08001650 char tmpstr[9];
1651
1652 is_filter = (argv[1][0] == 'f') ? 1 : 0;
1653 is_mymac = (argv[1][0] == 'm') ? 1 : 0;
1654 if (!argv[2] || strlen(argv[2]) != 12) {
1655 printf("MAC address format error, should be of length 12\n");
1656 return;
1657 }
1658 strncpy(tmpstr, argv[2], 8);
1659 tmpstr[8] = '\0';
1660 value = strtoul(tmpstr, NULL, 16);
1661 reg_write(REG_ATA1_ADDR, value);
1662 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1663
1664 strncpy(tmpstr, argv[2] + 8, 4);
1665 tmpstr[4] = '\0';
1666
1667 value = strtoul(tmpstr, NULL, 16);
1668 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001669 value |= (1 << 15); //IVL=1
developerfd40db22021-04-29 10:08:25 +08001670
1671 if (argc > 4) {
1672 j = strtoul(argv[4], NULL, 0);
1673 if (4095 < j) {
1674 printf("wrong vid range, should be within 0~4095\n");
1675 return;
1676 }
developerbe40a9e2024-03-07 21:44:26 +08001677 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001678 }
1679
1680 reg_write(REG_ATA2_ADDR, value);
1681 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1682
1683 if (!argv[3] || strlen(argv[3]) != 8) {
1684 if (is_filter)
1685 argv[3] = "11111111";
1686 else {
1687 printf("portmap format error, should be of length 8\n");
1688 return;
1689 }
1690 }
1691 j = 0;
1692 for (i = 0; i < 7; i++) {
1693 if (argv[3][i] != '0' && argv[3][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001694 printf
1695 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001696 return;
1697 }
1698 j += (argv[3][i] - '0') * (1 << i);
1699 }
developerbe40a9e2024-03-07 21:44:26 +08001700 value = j << 4; //w_port_map
developerfd40db22021-04-29 10:08:25 +08001701
1702 if (argc > 5) {
1703 j = strtoul(argv[5], NULL, 0);
1704 if (j < 1 || 255 < j) {
1705 printf("wrong age range, should be within 1~255\n");
1706 return;
1707 }
developerbe40a9e2024-03-07 21:44:26 +08001708 value |= (j << 24); //w_age_field
1709 value |= (0x1 << 2); //dynamic
developerfd40db22021-04-29 10:08:25 +08001710 } else {
developerbe40a9e2024-03-07 21:44:26 +08001711 value |= (0xff << 24); //w_age_field
1712 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001713 }
1714
1715 if (argc > 6) {
1716 j = strtoul(argv[6], NULL, 0);
1717 if (7 < j) {
1718 printf("wrong eg-tag range, should be within 0~7\n");
1719 return;
1720 }
developerbe40a9e2024-03-07 21:44:26 +08001721 value |= (j << 13); //EG_TAG
developerfd40db22021-04-29 10:08:25 +08001722 }
1723
1724 if (is_filter)
developerbe40a9e2024-03-07 21:44:26 +08001725 value |= (7 << 20); //sa_filter
developerfd40db22021-04-29 10:08:25 +08001726
1727 if (is_mymac)
1728 value |= (1 << 23);
1729
1730 reg_write(REG_ATWD_ADDR, value);
1731
1732 usleep(5000);
1733 reg_read(REG_ATWD_ADDR, &value);
1734 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1735
developerbe40a9e2024-03-07 21:44:26 +08001736 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001737 reg_write(REG_ATC_ADDR, value);
1738
1739 usleep(1000);
1740
1741 for (i = 0; i < 20; i++) {
1742 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001743 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001744 printf("done.\n");
1745 return;
1746 }
1747 usleep(1000);
1748 }
1749 if (i == 20)
1750 printf("timeout.\n");
1751}
1752
1753void table_search_mac_vid(int argc, char *argv[])
1754{
developerbe40a9e2024-03-07 21:44:26 +08001755 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001756 char tmpstr[9];
1757
1758 if (!argv[3] || strlen(argv[3]) != 12) {
1759 printf("MAC address format error, should be of length 12\n");
1760 return;
1761 }
1762 strncpy(tmpstr, argv[3], 8);
1763 tmpstr[8] = '\0';
1764 value = strtoul(tmpstr, NULL, 16);
1765 reg_write(REG_ATA1_ADDR, value);
1766 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1767
1768 strncpy(tmpstr, argv[3] + 8, 4);
1769 tmpstr[4] = '\0';
1770
1771 value = strtoul(tmpstr, NULL, 16);
1772 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001773 value |= (1 << 15); //IVL=1
developerfd40db22021-04-29 10:08:25 +08001774
1775 j = strtoul(argv[5], NULL, 0);
1776 if (4095 < j) {
1777 printf("wrong vid range, should be within 0~4095\n");
1778 return;
1779 }
developerbe40a9e2024-03-07 21:44:26 +08001780 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001781
1782 reg_write(REG_ATA2_ADDR, value);
1783 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1784
developerbe40a9e2024-03-07 21:44:26 +08001785 value = 0x8000; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001786 reg_write(REG_ATC_ADDR, value);
1787
1788 usleep(1000);
1789
1790 for (i = 0; i < 20; i++) {
1791 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001792 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001793 break;
1794 }
1795 usleep(1000);
1796 }
1797 if (i == 20) {
1798 printf("search timeout.\n");
1799 return;
1800 }
1801
1802 if (value & 0x1000) {
1803 printf("search no entry.\n");
1804 return;
1805 }
1806
1807 printf("search done.\n");
developerbe40a9e2024-03-07 21:44:26 +08001808 printf
1809 ("hash port(0:6) fid vid age mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001810
developerbe40a9e2024-03-07 21:44:26 +08001811 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
developerfd40db22021-04-29 10:08:25 +08001812 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001813 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001814 printf("%c", (j & 0x01) ? '1' : '-');
1815 printf("%c", (j & 0x02) ? '1' : '-');
1816 printf("%c", (j & 0x04) ? '1' : '-');
1817 printf("%c ", (j & 0x08) ? '1' : '-');
1818 printf("%c", (j & 0x10) ? '1' : '-');
1819 printf("%c", (j & 0x20) ? '1' : '-');
1820 printf("%c", (j & 0x40) ? '1' : '-');
1821 printf("%c", (j & 0x80) ? '1' : '-');
1822
1823 reg_read(REG_TSRA2_ADDR, &mac2);
1824
developerbe40a9e2024-03-07 21:44:26 +08001825 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001826 printf(" %4d", (mac2 & 0xfff));
developerbe40a9e2024-03-07 21:44:26 +08001827 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001828 reg_read(REG_TSRA1_ADDR, &mac);
1829 printf(" %08x", mac);
1830 printf("%04x", ((mac2 >> 16) & 0xffff));
1831 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1832 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1833}
1834
1835void table_search_mac_fid(int argc, char *argv[])
1836{
developerbe40a9e2024-03-07 21:44:26 +08001837 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001838 char tmpstr[9];
1839
1840 if (!argv[3] || strlen(argv[3]) != 12) {
1841 printf("MAC address format error, should be of length 12\n");
1842 return;
1843 }
1844 strncpy(tmpstr, argv[3], 8);
1845 tmpstr[8] = '\0';
1846 value = strtoul(tmpstr, NULL, 16);
1847 reg_write(REG_ATA1_ADDR, value);
1848 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1849
1850 strncpy(tmpstr, argv[3] + 8, 4);
1851 tmpstr[4] = '\0';
1852
1853 value = strtoul(tmpstr, NULL, 16);
1854 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001855 value &= ~(1 << 15); //IVL=0
developerfd40db22021-04-29 10:08:25 +08001856
1857 j = strtoul(argv[5], NULL, 0);
1858 if (7 < j) {
1859 printf("wrong fid range, should be within 0~7\n");
1860 return;
1861 }
developerbe40a9e2024-03-07 21:44:26 +08001862 value |= (j << 12); //vid
developerfd40db22021-04-29 10:08:25 +08001863
1864 reg_write(REG_ATA2_ADDR, value);
1865 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1866
developerbe40a9e2024-03-07 21:44:26 +08001867 value = 0x8000; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001868 reg_write(REG_ATC_ADDR, value);
1869
1870 usleep(1000);
1871
1872 for (i = 0; i < 20; i++) {
1873 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001874 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001875 break;
1876 }
1877 usleep(1000);
1878 }
1879 if (i == 20) {
1880 printf("search timeout.\n");
1881 return;
1882 }
1883
1884 if (value & 0x1000) {
1885 printf("search no entry.\n");
1886 return;
1887 }
1888
1889 printf("search done.\n");
developerbe40a9e2024-03-07 21:44:26 +08001890 printf
1891 ("hash port(0:6) fid vid age mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001892
developerbe40a9e2024-03-07 21:44:26 +08001893 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
developerfd40db22021-04-29 10:08:25 +08001894 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001895 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001896 printf("%c", (j & 0x01) ? '1' : '-');
1897 printf("%c", (j & 0x02) ? '1' : '-');
1898 printf("%c", (j & 0x04) ? '1' : '-');
1899 printf("%c ", (j & 0x08) ? '1' : '-');
1900 printf("%c", (j & 0x10) ? '1' : '-');
1901 printf("%c", (j & 0x20) ? '1' : '-');
1902 printf("%c", (j & 0x40) ? '1' : '-');
1903 printf("%c", (j & 0x80) ? '1' : '-');
1904
1905 reg_read(REG_TSRA2_ADDR, &mac2);
1906
developerbe40a9e2024-03-07 21:44:26 +08001907 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001908 printf(" %4d", (mac2 & 0xfff));
developerbe40a9e2024-03-07 21:44:26 +08001909 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001910 reg_read(REG_TSRA1_ADDR, &mac);
1911 printf(" %08x", mac);
1912 printf("%04x", ((mac2 >> 16) & 0xffff));
1913 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1914 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1915}
1916
1917void table_del_fid(int argc, char *argv[])
1918{
developerbe40a9e2024-03-07 21:44:26 +08001919 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001920 char tmpstr[9];
1921
1922 if (!argv[3] || strlen(argv[3]) != 12) {
1923 printf("MAC address format error, should be of length 12\n");
1924 return;
1925 }
1926 strncpy(tmpstr, argv[3], 8);
1927 tmpstr[8] = '\0';
1928 value = strtoul(tmpstr, NULL, 16);
1929 reg_write(REG_ATA1_ADDR, value);
1930 strncpy(tmpstr, argv[3] + 8, 4);
1931 tmpstr[4] = '\0';
1932 value = strtoul(tmpstr, NULL, 16);
1933 value = (value << 16);
1934
1935 if (argc > 5) {
1936 j = strtoul(argv[5], NULL, 0);
1937 if (j > 7) {
1938 printf("wrong fid range, should be within 0~7\n");
1939 return;
1940 }
developerbe40a9e2024-03-07 21:44:26 +08001941 value |= (j << 12); /* fid */
developerfd40db22021-04-29 10:08:25 +08001942 }
1943
1944 reg_write(REG_ATA2_ADDR, value);
1945
developerbe40a9e2024-03-07 21:44:26 +08001946 value = 0; /* STATUS=0, delete mac */
developerfd40db22021-04-29 10:08:25 +08001947 reg_write(REG_ATWD_ADDR, value);
1948
developerbe40a9e2024-03-07 21:44:26 +08001949 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001950 reg_write(REG_ATC_ADDR, value);
1951
1952 for (i = 0; i < 20; i++) {
1953 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001954 if ((value & 0x8000) == 0) { /* mac address busy */
developerfd40db22021-04-29 10:08:25 +08001955 if (argv[1] != NULL)
1956 printf("done.\n");
1957 return;
1958 }
1959 usleep(1000);
1960 }
1961 if (i == 20)
1962 printf("timeout.\n");
1963}
1964
1965void table_del_vid(int argc, char *argv[])
1966{
developerbe40a9e2024-03-07 21:44:26 +08001967 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001968 char tmpstr[9];
1969
1970 if (!argv[3] || strlen(argv[3]) != 12) {
1971 printf("MAC address format error, should be of length 12\n");
1972 return;
1973 }
1974 strncpy(tmpstr, argv[3], 8);
1975 tmpstr[8] = '\0';
1976 value = strtoul(tmpstr, NULL, 16);
1977 reg_write(REG_ATA1_ADDR, value);
1978
1979 strncpy(tmpstr, argv[3] + 8, 4);
1980 tmpstr[4] = '\0';
1981 value = strtoul(tmpstr, NULL, 16);
1982 value = (value << 16);
1983
1984 j = strtoul(argv[5], NULL, 0);
1985 if (j > 4095) {
1986 printf("wrong fid range, should be within 0~4095\n");
1987 return;
1988 }
developerbe40a9e2024-03-07 21:44:26 +08001989 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001990 value |= 1 << 15;
1991 reg_write(REG_ATA2_ADDR, value);
1992
developerbe40a9e2024-03-07 21:44:26 +08001993 value = 0; //STATUS=0, delete mac
developerfd40db22021-04-29 10:08:25 +08001994 reg_write(REG_ATWD_ADDR, value);
1995
developerbe40a9e2024-03-07 21:44:26 +08001996 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001997 reg_write(REG_ATC_ADDR, value);
1998
1999 for (i = 0; i < 20; i++) {
2000 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002001 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08002002 if (argv[1] != NULL)
2003 printf("done.\n");
2004 return;
2005 }
2006 usleep(1000);
2007 }
2008 if (i == 20)
2009 printf("timeout.\n");
2010}
2011
developerbe40a9e2024-03-07 21:44:26 +08002012void table_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002013{
developerbe40a9e2024-03-07 21:44:26 +08002014 unsigned int value = 0;
2015
developerfd40db22021-04-29 10:08:25 +08002016 reg_write(REG_ATC_ADDR, 0x8002);
2017 usleep(5000);
2018 reg_read(REG_ATC_ADDR, &value);
2019
2020 printf("REG_ATC_ADDR is 0x%x\n\r", value);
2021}
2022
2023void set_mirror_to(int argc, char *argv[])
2024{
developerbe40a9e2024-03-07 21:44:26 +08002025 unsigned int value = 0;
2026 int idx = 0;
developerfd40db22021-04-29 10:08:25 +08002027
2028 idx = strtoul(argv[3], NULL, 0);
2029 if (idx < 0 || MAX_PORT < idx) {
2030 printf("wrong port member, should be within 0~%d\n", MAX_PORT);
2031 return;
2032 }
2033 if (chip_name == 0x7530) {
2034
2035 reg_read(REG_MFC_ADDR, &value);
2036 value |= 0x1 << 3;
2037 value &= 0xfffffff8;
2038 value |= idx << 0;
2039
2040 reg_write(REG_MFC_ADDR, value);
2041 } else {
2042
2043 reg_read(REG_CFC_ADDR, &value);
2044 value &= (~REG_CFC_MIRROR_EN_MASK);
2045 value |= (1 << REG_CFC_MIRROR_EN_OFFT);
2046 value &= (~REG_CFC_MIRROR_PORT_MASK);
2047 value |= (idx << REG_CFC_MIRROR_PORT_OFFT);
2048 reg_write(REG_CFC_ADDR, value);
2049 }
2050}
2051
2052void set_mirror_from(int argc, char *argv[])
2053{
developerbe40a9e2024-03-07 21:44:26 +08002054 unsigned int offset = 0, value = 0;
developer546b2792024-06-15 20:31:38 +08002055 unsigned int idx = 0, mirror = 0;
2056 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002057
developer546b2792024-06-15 20:31:38 +08002058 errno = 0;
2059 idx = strtoul(argv[3], &endptr, 0);
2060 if (errno != 0 || *endptr != '\0' || idx > MAX_PORT) {
2061 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
developerfd40db22021-04-29 10:08:25 +08002062 return;
2063 }
2064
developer546b2792024-06-15 20:31:38 +08002065 errno = 0;
2066 mirror = strtoul(argv[4], &endptr, 0);
2067
2068 if (errno != 0 || *endptr != '\0' || mirror > 3) {
developerfd40db22021-04-29 10:08:25 +08002069 printf("wrong mirror setting, should be within 0~3\n");
2070 return;
2071 }
2072
2073 offset = (0x2004 | (idx << 8));
2074 reg_read(offset, &value);
2075
2076 value &= 0xfffffcff;
2077 value |= mirror << 8;
2078
2079 reg_write(offset, value);
2080}
2081
2082void vlan_dump(int argc, char *argv[])
2083{
developerbe40a9e2024-03-07 21:44:26 +08002084 unsigned int i = 0, j = 0, value = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08002085 int eg_tag = 0;
2086
2087 if (argc == 4) {
2088 if (!strncmp(argv[3], "egtag", 6))
2089 eg_tag = 1;
2090 }
2091
2092 if (eg_tag)
developerbe40a9e2024-03-07 21:44:26 +08002093 printf
2094 (" vid fid portmap s-tag\teg_tag(0:untagged 2:tagged)\n");
developerfd40db22021-04-29 10:08:25 +08002095 else
2096 printf(" vid fid portmap s-tag\n");
2097
2098 for (i = 1; i < 4095; i++) {
developerbe40a9e2024-03-07 21:44:26 +08002099 value = (0x80000000 + i); //r_vid_cmd
developerfd40db22021-04-29 10:08:25 +08002100 reg_write(REG_VTCR_ADDR, value);
2101
2102 for (j = 0; j < 20; j++) {
2103 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002104 if ((value & 0x80000000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08002105 break;
2106 }
2107 usleep(1000);
2108 }
2109 if (j == 20)
2110 printf("timeout.\n");
2111
2112 reg_read(REG_VAWD1_ADDR, &value);
2113 reg_read(REG_VAWD2_ADDR, &value2);
2114 //printf("REG_VAWD1_ADDR value%d is 0x%x\n\r", i, value);
2115 //printf("REG_VAWD2_ADDR value%d is 0x%x\n\r", i, value2);
2116
2117 if ((value & 0x01) != 0) {
2118 printf(" %4d ", i);
2119 printf(" %2d ", ((value & 0xe) >> 1));
2120 printf(" %c", (value & 0x00010000) ? '1' : '-');
2121 printf("%c", (value & 0x00020000) ? '1' : '-');
2122 printf("%c", (value & 0x00040000) ? '1' : '-');
2123 printf("%c", (value & 0x00080000) ? '1' : '-');
2124 printf("%c", (value & 0x00100000) ? '1' : '-');
2125 printf("%c", (value & 0x00200000) ? '1' : '-');
2126 printf("%c", (value & 0x00400000) ? '1' : '-');
2127 printf("%c", (value & 0x00800000) ? '1' : '-');
2128 printf(" %4d", ((value & 0xfff0) >> 4));
2129 if (eg_tag) {
2130 printf("\t");
2131 if ((value & (0x3 << 28)) == (0x3 << 28)) {
2132 /* VTAG_EN=1 and EG_CON=1 */
2133 printf("CONSISTENT");
2134 } else if (value & (0x1 << 28)) {
2135 /* VTAG_EN=1 */
2136 printf("%d", (value2 & 0x0003) >> 0);
2137 printf("%d", (value2 & 0x000c) >> 2);
2138 printf("%d", (value2 & 0x0030) >> 4);
2139 printf("%d", (value2 & 0x00c0) >> 6);
2140 printf("%d", (value2 & 0x0300) >> 8);
2141 printf("%d", (value2 & 0x0c00) >> 10);
2142 printf("%d", (value2 & 0x3000) >> 12);
2143 printf("%d", (value2 & 0xc000) >> 14);
2144 } else {
2145 /* VTAG_EN=0 */
2146 printf("DISABLED");
2147 }
2148 }
2149 printf("\n");
2150 } else {
developerbe40a9e2024-03-07 21:44:26 +08002151 /*print 16 vid for reference information */
developerfd40db22021-04-29 10:08:25 +08002152 if (i <= 16) {
2153 printf(" %4d ", i);
2154 printf(" %2d ", ((value & 0xe) >> 1));
2155 printf(" invalid\n");
2156 }
2157 }
2158 }
2159}
2160
developerfd40db22021-04-29 10:08:25 +08002161static long timespec_diff_us(struct timespec start, struct timespec end)
2162{
2163 struct timespec temp;
2164 unsigned long duration = 0;
2165
2166 if ((end.tv_nsec - start.tv_nsec) < 0) {
2167 temp.tv_sec = end.tv_sec - start.tv_sec - 1;
2168 temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
2169 } else {
2170 temp.tv_sec = end.tv_sec - start.tv_sec;
2171 temp.tv_nsec = end.tv_nsec - start.tv_nsec;
2172 }
developerbe40a9e2024-03-07 21:44:26 +08002173 /* calculate second part */
developerfd40db22021-04-29 10:08:25 +08002174 duration += temp.tv_sec * 1000000;
developerbe40a9e2024-03-07 21:44:26 +08002175 /* calculate ns part */
developerfd40db22021-04-29 10:08:25 +08002176 duration += temp.tv_nsec >> 10;
2177
2178 return duration;
2179}
2180
developerfd40db22021-04-29 10:08:25 +08002181void vlan_clear(int argc, char *argv[])
2182{
developerbe40a9e2024-03-07 21:44:26 +08002183 unsigned int value = 0;
2184 int vid = 0;
developerfd40db22021-04-29 10:08:25 +08002185 unsigned long duration_us = 0;
2186 struct timespec start, end;
2187
2188 for (vid = 0; vid < 4096; vid++) {
2189 clock_gettime(CLOCK_REALTIME, &start);
developerbe40a9e2024-03-07 21:44:26 +08002190 value = 0; //invalid
developerfd40db22021-04-29 10:08:25 +08002191 reg_write(REG_VAWD1_ADDR, value);
2192
developerbe40a9e2024-03-07 21:44:26 +08002193 value = (0x80001000 + vid); //w_vid_cmd
developerfd40db22021-04-29 10:08:25 +08002194 reg_write(REG_VTCR_ADDR, value);
2195 while (duration_us <= 1000) {
2196 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002197 if ((value & 0x80000000) == 0) { //table busy
developerfd40db22021-04-29 10:08:25 +08002198 break;
2199 }
2200 clock_gettime(CLOCK_REALTIME, &end);
2201 duration_us = timespec_diff_us(start, end);
2202 }
2203 if (duration_us > 1000)
2204 printf("config vlan timeout: %ld.\n", duration_us);
2205 }
2206}
2207
2208void vlan_set(int argc, char *argv[])
2209{
2210 unsigned int vlan_mem = 0;
2211 unsigned int value = 0;
2212 unsigned int value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08002213 int i = 0, vid = 0, fid = 0;
developerfd40db22021-04-29 10:08:25 +08002214 int stag = 0;
2215 unsigned long eg_con = 0;
2216 unsigned int eg_tag = 0;
2217
2218 if (argc < 5) {
2219 printf("insufficient arguments!\n");
2220 return;
2221 }
2222
2223 fid = strtoul(argv[3], NULL, 0);
2224 if (fid < 0 || fid > 7) {
2225 printf("wrong filtering db id range, should be within 0~7\n");
2226 return;
2227 }
2228 value |= (fid << 1);
2229
2230 vid = strtoul(argv[4], NULL, 0);
2231 if (vid < 0 || 0xfff < vid) {
2232 printf("wrong vlan id range, should be within 0~4095\n");
2233 return;
2234 }
2235
2236 if (strlen(argv[5]) != 8) {
2237 printf("portmap format error, should be of length 7\n");
2238 return;
2239 }
2240
2241 vlan_mem = 0;
2242 for (i = 0; i < 8; i++) {
2243 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08002244 printf
2245 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08002246 return;
2247 }
2248 vlan_mem += (argv[5][i] - '0') * (1 << i);
2249 }
2250
2251 /* VLAN stag */
2252 if (argc > 6) {
2253 stag = strtoul(argv[6], NULL, 16);
2254 if (stag < 0 || 0xfff < stag) {
developerbe40a9e2024-03-07 21:44:26 +08002255 printf
2256 ("wrong stag id range, should be within 0~4095\n");
developerfd40db22021-04-29 10:08:25 +08002257 return;
2258 }
2259 //printf("STAG is 0x%x\n", stag);
2260 }
2261
2262 /* set vlan member */
2263 value |= (vlan_mem << 16);
developerbe40a9e2024-03-07 21:44:26 +08002264 value |= (1 << 30); //IVL=1
2265 value |= ((stag & 0xfff) << 4); //stag
2266 value |= 1; //valid
developerfd40db22021-04-29 10:08:25 +08002267
2268 if (argc > 7) {
2269 eg_con = strtoul(argv[7], NULL, 2);
2270 eg_con = !!eg_con;
developerbe40a9e2024-03-07 21:44:26 +08002271 value |= (eg_con << 29); //eg_con
2272 value |= (1 << 28); //eg tag control enable
developerfd40db22021-04-29 10:08:25 +08002273 }
2274
2275 if (argc > 8 && !eg_con) {
2276 if (strlen(argv[8]) != 8) {
developerbe40a9e2024-03-07 21:44:26 +08002277 printf
2278 ("egtag portmap format error, should be of length 7\n");
developerfd40db22021-04-29 10:08:25 +08002279 return;
2280 }
2281
2282 for (i = 0; i < 8; i++) {
2283 if (argv[8][i] < '0' || argv[8][i] > '3') {
developerbe40a9e2024-03-07 21:44:26 +08002284 printf
2285 ("egtag portmap format error, should be of combination of 0 or 3\n");
developerfd40db22021-04-29 10:08:25 +08002286 return;
2287 }
2288 //eg_tag += (argv[8][i] - '0') * (1 << i * 2);
2289 eg_tag |= (argv[8][i] - '0') << (i * 2);
2290 }
2291
developerbe40a9e2024-03-07 21:44:26 +08002292 value |= (1 << 28); //eg tag control enable
developerfd40db22021-04-29 10:08:25 +08002293 value2 &= ~(0xffff);
2294 value2 |= eg_tag;
2295 }
2296 reg_write(REG_VAWD1_ADDR, value);
2297 reg_write(REG_VAWD2_ADDR, value2);
2298 //printf("VAWD1=0x%08x VAWD2=0x%08x ", value, value2);
2299
developerbe40a9e2024-03-07 21:44:26 +08002300 value = (0x80001000 + vid); //w_vid_cmd
developerfd40db22021-04-29 10:08:25 +08002301 reg_write(REG_VTCR_ADDR, value);
2302 //printf("VTCR=0x%08x\n", value);
2303
2304 for (i = 0; i < 300; i++) {
2305 usleep(1000);
2306 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002307 if ((value & 0x80000000) == 0) //table busy
developerfd40db22021-04-29 10:08:25 +08002308 break;
2309 }
2310
2311 if (i == 300)
2312 printf("config vlan timeout.\n");
2313}
2314
2315void igmp_on(int argc, char *argv[])
2316{
2317 unsigned int leaky_en = 0;
2318 unsigned int wan_num = 4;
developerbe40a9e2024-03-07 21:44:26 +08002319 unsigned int port = 0, offset = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002320 char cmd[80];
2321 int ret;
developer2fdae312024-06-15 20:36:12 +08002322 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002323
developer2fdae312024-06-15 20:36:12 +08002324 if (argc > 3) {
2325 errno = 0;
2326 leaky_en = strtoul(argv[3], &endptr, 10);
2327 if (errno != 0 || *endptr != '\0') {
2328 printf("Error: string converting\n");
2329 return;
2330 }
2331 }
2332 if (argc > 4) {
2333 errno = 0;
2334 wan_num = strtoul(argv[4], &endptr, 10);
2335 if (errno != 0 || *endptr != '\0') {
2336 printf("Error: string converting\n");
2337 return;
2338 }
2339 }
developerfd40db22021-04-29 10:08:25 +08002340
2341 if (leaky_en == 1) {
2342 if (wan_num == 4) {
2343 /* reg_write(0x2410, 0x810000c8); */
2344 reg_read(0x2410, &value);
2345 reg_write(0x2410, value | (1 << 3));
2346 /* reg_write(0x2010, 0x810000c0); */
2347 reg_read(0x2010, &value);
2348 reg_write(0x2010, value & (~(1 << 3)));
2349 reg_write(REG_ISC_ADDR, 0x10027d10);
2350 } else {
2351 /* reg_write(0x2010, 0x810000c8); */
2352 reg_read(0x2010, &value);
2353 reg_write(0x2010, value | (1 << 3));
2354 /* reg_write(0x2410, 0x810000c0); */
2355 reg_read(0x2410, &value);
2356 reg_write(0x2410, value & (~(1 << 3)));
2357 reg_write(REG_ISC_ADDR, 0x01027d01);
2358 }
developerbe40a9e2024-03-07 21:44:26 +08002359 } else
developerfd40db22021-04-29 10:08:25 +08002360 reg_write(REG_ISC_ADDR, 0x10027d60);
2361
2362 reg_write(0x1c, 0x08100810);
2363 reg_write(0x2008, 0xb3ff);
2364 reg_write(0x2108, 0xb3ff);
2365 reg_write(0x2208, 0xb3ff);
2366 reg_write(0x2308, 0xb3ff);
2367 reg_write(0x2408, 0xb3ff);
2368 reg_write(0x2608, 0xb3ff);
2369 /* Enable Port ACL
developerbe40a9e2024-03-07 21:44:26 +08002370 * reg_write(0x2P04, 0xff0403);
2371 */
developerfd40db22021-04-29 10:08:25 +08002372 for (port = 0; port <= 6; port++) {
2373 offset = 0x2004 + port * 0x100;
2374 reg_read(offset, &value);
2375 reg_write(offset, value | (1 << 10));
2376 }
2377
developerbe40a9e2024-03-07 21:44:26 +08002378 /*IGMP query only p4 -> p5 */
developerfd40db22021-04-29 10:08:25 +08002379 reg_write(0x94, 0x00ff0002);
2380 if (wan_num == 4)
2381 reg_write(0x98, 0x000a1008);
2382 else
2383 reg_write(0x98, 0x000a0108);
2384 reg_write(0x90, 0x80005000);
2385 reg_write(0x94, 0xff001100);
2386 if (wan_num == 4)
2387 reg_write(0x98, 0x000B1000);
2388 else
2389 reg_write(0x98, 0x000B0100);
2390 reg_write(0x90, 0x80005001);
2391 reg_write(0x94, 0x3);
2392 reg_write(0x98, 0x0);
2393 reg_write(0x90, 0x80009000);
2394 reg_write(0x94, 0x1a002080);
2395 reg_write(0x98, 0x0);
2396 reg_write(0x90, 0x8000b000);
2397
developerbe40a9e2024-03-07 21:44:26 +08002398 /*IGMP p5 -> p4 */
developerfd40db22021-04-29 10:08:25 +08002399 reg_write(0x94, 0x00ff0002);
2400 reg_write(0x98, 0x000a2008);
2401 reg_write(0x90, 0x80005002);
2402 reg_write(0x94, 0x4);
2403 reg_write(0x98, 0x0);
2404 reg_write(0x90, 0x80009001);
2405 if (wan_num == 4)
2406 reg_write(0x94, 0x1a001080);
2407 else
2408 reg_write(0x94, 0x1a000180);
2409 reg_write(0x98, 0x0);
2410 reg_write(0x90, 0x8000b001);
2411
developerbe40a9e2024-03-07 21:44:26 +08002412 /*IGMP p0~p3 -> p6 */
developerfd40db22021-04-29 10:08:25 +08002413 reg_write(0x94, 0x00ff0002);
2414 if (wan_num == 4)
2415 reg_write(0x98, 0x000a0f08);
2416 else
2417 reg_write(0x98, 0x000a1e08);
2418 reg_write(0x90, 0x80005003);
2419 reg_write(0x94, 0x8);
2420 reg_write(0x98, 0x0);
2421 reg_write(0x90, 0x80009002);
2422 reg_write(0x94, 0x1a004080);
2423 reg_write(0x98, 0x0);
2424 reg_write(0x90, 0x8000b002);
2425
developerbe40a9e2024-03-07 21:44:26 +08002426 /*IGMP query only p6 -> p0~p3 */
developerfd40db22021-04-29 10:08:25 +08002427 reg_write(0x94, 0x00ff0002);
2428 reg_write(0x98, 0x000a4008);
2429 reg_write(0x90, 0x80005004);
2430 reg_write(0x94, 0xff001100);
2431 reg_write(0x98, 0x000B4000);
2432 reg_write(0x90, 0x80005005);
2433 reg_write(0x94, 0x30);
2434 reg_write(0x98, 0x0);
2435 reg_write(0x90, 0x80009003);
2436 if (wan_num == 4)
2437 reg_write(0x94, 0x1a000f80);
2438 else
2439 reg_write(0x94, 0x1a001e80);
2440 reg_write(0x98, 0x0);
2441 reg_write(0x90, 0x8000b003);
2442
developerbe40a9e2024-03-07 21:44:26 +08002443 /*Force eth2 to receive all igmp packets */
developer2fdae312024-06-15 20:36:12 +08002444 ret = snprintf(cmd, sizeof(cmd),
developerbe40a9e2024-03-07 21:44:26 +08002445 "echo 2 > /sys/devices/virtual/net/%s/brif/%s/multicast_router",
2446 BR_DEVNAME, ETH_DEVNAME);
developer2fdae312024-06-15 20:36:12 +08002447
2448 if (ret < 0 || ret >= sizeof(cmd))
2449 goto error;
2450
developerfd40db22021-04-29 10:08:25 +08002451 ret = system(cmd);
2452 if (ret)
developer2fdae312024-06-15 20:36:12 +08002453 goto error;
2454
2455 return;
2456
2457error:
2458 printf("Failed to set /sys/devices/virtual/net/%s/brif/%s/multicast_router\n",
2459 BR_DEVNAME, ETH_DEVNAME);
developerfd40db22021-04-29 10:08:25 +08002460}
2461
2462void igmp_disable(int argc, char *argv[])
2463{
developerbe40a9e2024-03-07 21:44:26 +08002464 unsigned int reg_offset = 0, value = 0;
2465 int port_num = 0;
developerfd40db22021-04-29 10:08:25 +08002466
2467 if (argc < 4) {
2468 printf("insufficient arguments!\n");
2469 return;
2470 }
2471 port_num = strtoul(argv[3], NULL, 0);
2472 if (port_num < 0 || 6 < port_num) {
2473 printf("wrong port range, should be within 0~6\n");
2474 return;
2475 }
developerfd40db22021-04-29 10:08:25 +08002476 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2477 reg_offset = 0x2008;
2478 reg_offset |= (port_num << 8);
2479 value = 0x8000;
2480
2481 reg_write(reg_offset, value);
2482}
2483
2484void igmp_enable(int argc, char *argv[])
2485{
developerbe40a9e2024-03-07 21:44:26 +08002486 unsigned int reg_offset = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002487 int port_num;
2488
2489 if (argc < 4) {
2490 printf("insufficient arguments!\n");
2491 return;
2492 }
2493 port_num = strtoul(argv[3], NULL, 0);
2494 if (port_num < 0 || 6 < port_num) {
2495 printf("wrong port range, should be within 0~6\n");
2496 return;
2497 }
developerfd40db22021-04-29 10:08:25 +08002498 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2499 reg_offset = 0x2008;
2500 reg_offset |= (port_num << 8);
2501 value = 0x9755;
2502 reg_write(reg_offset, value);
2503}
2504
developerbe40a9e2024-03-07 21:44:26 +08002505void igmp_off(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002506{
developerbe40a9e2024-03-07 21:44:26 +08002507 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08002508 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2509 reg_read(REG_ISC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002510 value &= ~(1 << 18); //disable
developerfd40db22021-04-29 10:08:25 +08002511 reg_write(REG_ISC_ADDR, value);
2512
developerbe40a9e2024-03-07 21:44:26 +08002513 /*restore wan port multicast leaky vlan function: default disabled */
developerfd40db22021-04-29 10:08:25 +08002514 reg_read(0x2010, &value);
2515 reg_write(0x2010, value & (~(1 << 3)));
2516 reg_read(0x2410, &value);
2517 reg_write(0x2410, value & (~(1 << 3)));
2518
2519 printf("config igmpsnoop off.\n");
2520}
2521
developerbe40a9e2024-03-07 21:44:26 +08002522void switch_reset(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002523{
developer8c3871b2022-07-01 14:07:53 +08002524 if (chip_name == 0x7988)
developerbe40a9e2024-03-07 21:44:26 +08002525 return;
developer8c3871b2022-07-01 14:07:53 +08002526
developerfd40db22021-04-29 10:08:25 +08002527 unsigned int value = 0;
2528 /*Software Register Reset and Software System Reset */
2529 reg_write(0x7000, 0x3);
2530 reg_read(0x7000, &value);
2531 printf("SYS_CTRL(0x7000) register value =0x%x \n", value);
2532 if (chip_name == 0x7531) {
2533 reg_write(0x7c0c, 0x11111111);
2534 reg_read(0x7c0c, &value);
2535 printf("GPIO Mode (0x7c0c) select value =0x%x \n", value);
2536 }
2537 printf("Switch Software Reset !!! \n");
2538}
2539
developerbe40a9e2024-03-07 21:44:26 +08002540void phy_set_fc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002541{
developerbe40a9e2024-03-07 21:44:26 +08002542 unsigned int port = 0, pause_capable = 0;
2543 unsigned int phy_value = 0;
developer3a780bf2024-06-15 20:34:27 +08002544 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002545
developer3a780bf2024-06-15 20:34:27 +08002546 errno = 0;
2547 port = strtoul(argv[3], &endptr, 10);
2548 if (errno != 0 || *endptr != '\0' || port > MAX_PORT - 2) {
2549 printf("Error: wrong PHY port number, should be within 0~4\n");
2550 return;
2551 }
developerfd40db22021-04-29 10:08:25 +08002552
developer3a780bf2024-06-15 20:34:27 +08002553 errno = 0;
2554 pause_capable = strtoul(argv[4], &endptr, 10);
2555 if (errno != 0 || *endptr != '\0' || pause_capable > 1) {
2556 printf("Illegal parameter, full_duplex_pause_capable:0|1\n");
developerbe40a9e2024-03-07 21:44:26 +08002557 return;
developerfd40db22021-04-29 10:08:25 +08002558 }
developer3a780bf2024-06-15 20:34:27 +08002559
developerfd40db22021-04-29 10:08:25 +08002560 printf("port=%d, full_duplex_pause_capable:%d\n", port, pause_capable);
developerbe40a9e2024-03-07 21:44:26 +08002561
developerfd40db22021-04-29 10:08:25 +08002562 mii_mgr_read(port, 4, &phy_value);
2563 printf("read phy_value:0x%x\r\n", phy_value);
2564 phy_value &= (~(0x1 << 10));
2565 phy_value &= (~(0x1 << 11));
2566 if (pause_capable == 1) {
2567 phy_value |= (0x1 << 10);
2568 phy_value |= (0x1 << 11);
2569 }
2570 mii_mgr_write(port, 4, phy_value);
2571 printf("write phy_value:0x%x\r\n", phy_value);
developerbe40a9e2024-03-07 21:44:26 +08002572 return;
2573} /*end phy_set_fc */
developerfd40db22021-04-29 10:08:25 +08002574
developerbe40a9e2024-03-07 21:44:26 +08002575void phy_set_an(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002576{
developerbe40a9e2024-03-07 21:44:26 +08002577 unsigned int port = 0, auto_negotiation_en = 0;
2578 unsigned int phy_value = 0;
developer3a780bf2024-06-15 20:34:27 +08002579 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002580
developer3a780bf2024-06-15 20:34:27 +08002581 errno = 0;
2582 port = strtoul(argv[3], &endptr, 10);
2583 if (errno != 0 || *endptr != '\0' || port > MAX_PORT - 2) {
2584 printf("Error: wrong PHY port number, should be within 0~4\n");
2585 return;
2586 }
developerfd40db22021-04-29 10:08:25 +08002587
developer3a780bf2024-06-15 20:34:27 +08002588 errno = 0;
2589 auto_negotiation_en = strtoul(argv[4], &endptr, 10);
2590 if (errno != 0 || *endptr != '\0' || auto_negotiation_en > 1) {
2591 printf("Illegal parameter, auto_negotiation_en:0|1\n");
developerbe40a9e2024-03-07 21:44:26 +08002592 return;
developerfd40db22021-04-29 10:08:25 +08002593 }
developer3a780bf2024-06-15 20:34:27 +08002594
developerfd40db22021-04-29 10:08:25 +08002595 printf("port=%d, auto_negotiation_en:%d\n", port, auto_negotiation_en);
developerbe40a9e2024-03-07 21:44:26 +08002596
developerfd40db22021-04-29 10:08:25 +08002597 mii_mgr_read(port, 0, &phy_value);
2598 printf("read phy_value:0x%x\r\n", phy_value);
2599 phy_value &= (~(1 << 12));
2600 phy_value |= (auto_negotiation_en << 12);
2601 mii_mgr_write(port, 0, phy_value);
2602 printf("write phy_value:0x%x\r\n", phy_value);
developerbe40a9e2024-03-07 21:44:26 +08002603} /*end phy_set_an */
developerfd40db22021-04-29 10:08:25 +08002604
developerbe40a9e2024-03-07 21:44:26 +08002605void set_mac_pfc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002606{
developerbe40a9e2024-03-07 21:44:26 +08002607 unsigned int value = 0;
developer546b2792024-06-15 20:31:38 +08002608 unsigned int port, enable = 0;
2609 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002610
developer546b2792024-06-15 20:31:38 +08002611 errno = 0;
2612 port = strtoul(argv[3], &endptr, 10);
2613 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2614 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2615 return;
2616 }
2617
2618 errno = 0;
2619 enable = strtoul(argv[4], &endptr, 10);
2620 if (errno != 0 || *endptr != '\0' || enable > 1) {
2621 printf("Error: Illegal paramete, enable|diable:0|1\n");
developerbe40a9e2024-03-07 21:44:26 +08002622 return;
developerfd40db22021-04-29 10:08:25 +08002623 }
developer546b2792024-06-15 20:31:38 +08002624 printf("enable: %d\n", enable);
2625
developer8c3871b2022-07-01 14:07:53 +08002626 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002627 reg_read(REG_PFC_CTRL_ADDR, &value);
2628 value &= ~(1 << port);
2629 value |= (enable << port);
2630 printf("write reg: %x, value: %x\n", REG_PFC_CTRL_ADDR, value);
2631 reg_write(REG_PFC_CTRL_ADDR, value);
developerbe40a9e2024-03-07 21:44:26 +08002632 } else
developerfd40db22021-04-29 10:08:25 +08002633 printf("\nCommand not support by this chip.\n");
developerfd40db22021-04-29 10:08:25 +08002634}
2635
developerbe40a9e2024-03-07 21:44:26 +08002636void global_set_mac_fc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002637{
2638 unsigned char enable = 0;
developerbe40a9e2024-03-07 21:44:26 +08002639 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08002640
2641 if (chip_name == 0x7530) {
2642 enable = atoi(argv[3]);
2643 printf("enable: %d\n", enable);
2644
developerbe40a9e2024-03-07 21:44:26 +08002645 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002646 if (enable > 1) {
2647 printf(HELP_MACCTL_FC);
developerbe40a9e2024-03-07 21:44:26 +08002648 return;
developerfd40db22021-04-29 10:08:25 +08002649 }
2650 reg_write(0x7000, 0x3);
2651 reg = REG_GFCCR0_ADDR;
2652 reg_read(REG_GFCCR0_ADDR, &value);
2653 value &= (~REG_FC_EN_MASK);
2654 value |= (enable << REG_FC_EN_OFFT);
2655 printf("write reg: %x, value: %x\n", reg, value);
2656 reg_write(REG_GFCCR0_ADDR, value);
2657 } else
2658 printf("\r\nCommand not support by this chip.\n");
developerbe40a9e2024-03-07 21:44:26 +08002659} /*end mac_set_fc */
developerfd40db22021-04-29 10:08:25 +08002660
developerbe40a9e2024-03-07 21:44:26 +08002661void qos_sch_select(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002662{
developerbe40a9e2024-03-07 21:44:26 +08002663 unsigned char port = 0, queue = 0;
developerfd40db22021-04-29 10:08:25 +08002664 unsigned char type = 0;
developerbe40a9e2024-03-07 21:44:26 +08002665 unsigned int value = 0, reg = 0;
developer546b2792024-06-15 20:31:38 +08002666 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002667
2668 if (argc < 7)
developerbe40a9e2024-03-07 21:44:26 +08002669 return;
developerfd40db22021-04-29 10:08:25 +08002670
developer546b2792024-06-15 20:31:38 +08002671 errno = 0;
2672 port = strtoul(argv[3], &endptr, 10);
2673 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2674 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2675 return;
2676 }
developerfd40db22021-04-29 10:08:25 +08002677
developer546b2792024-06-15 20:31:38 +08002678 errno = 0;
2679 queue = strtoul(argv[4], &endptr, 10);
2680 if (errno != 0 || *endptr != '\0' || queue > 7) {
2681 printf("Error: wrong port queue member\n");
developerbe40a9e2024-03-07 21:44:26 +08002682 return;
developerfd40db22021-04-29 10:08:25 +08002683 }
2684
developer546b2792024-06-15 20:31:38 +08002685 errno = 0;
2686 type = strtoul(argv[6], &endptr, 10);
2687 if (errno != 0 || *endptr != '\0' || type > 2) {
developerfd40db22021-04-29 10:08:25 +08002688 printf(HELP_QOS_TYPE);
developerbe40a9e2024-03-07 21:44:26 +08002689 return;
developerfd40db22021-04-29 10:08:25 +08002690 }
2691
developerbe40a9e2024-03-07 21:44:26 +08002692 printf("\r\nswitch qos type: %d.\n", type);
developerfd40db22021-04-29 10:08:25 +08002693
2694 if (!strncmp(argv[5], "min", 4)) {
2695
2696 if (type == 0) {
developerbe40a9e2024-03-07 21:44:26 +08002697 /*min sharper-->round roubin, disable min sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002698 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2699 reg_read(reg, &value);
2700 value = 0x0;
2701 reg_write(reg, value);
2702 } else if (type == 1) {
developerbe40a9e2024-03-07 21:44:26 +08002703 /*min sharper-->sp, disable min sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002704 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2705 reg_read(reg, &value);
2706 value = 0x0;
2707 value |= (1 << 31);
2708 reg_write(reg, value);
2709 } else {
2710 printf("min sharper only support: rr or sp\n");
developerbe40a9e2024-03-07 21:44:26 +08002711 return;
developerfd40db22021-04-29 10:08:25 +08002712 }
2713 } else if (!strncmp(argv[5], "max", 4)) {
2714 if (type == 1) {
developerbe40a9e2024-03-07 21:44:26 +08002715 /*max sharper-->sp, disable max sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002716 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2717 reg_read(reg, &value);
2718 value = 0x0;
2719 value |= (1 << 31);
2720 reg_write(reg, value);
2721 } else if (type == 2) {
developerbe40a9e2024-03-07 21:44:26 +08002722 /*max sharper-->wfq, disable max sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002723 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2724 reg_read(reg, &value);
2725 value = 0x0;
2726 reg_write(reg, value);
2727 } else {
2728 printf("max sharper only support: wfq or sp\n");
developerbe40a9e2024-03-07 21:44:26 +08002729 return;
developerfd40db22021-04-29 10:08:25 +08002730 }
2731 } else {
developerbe40a9e2024-03-07 21:44:26 +08002732 printf("\r\nIllegal sharper:%s\n", argv[5]);
2733 return;
developerfd40db22021-04-29 10:08:25 +08002734 }
developerbe40a9e2024-03-07 21:44:26 +08002735 printf("reg:0x%x--value:0x%x\n", reg, value);
developerfd40db22021-04-29 10:08:25 +08002736}
2737
2738void get_upw(unsigned int *value, unsigned char base)
2739{
2740 *value &= (~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
2741 (0x7 << 16) | (0x7 << 20)));
developerbe40a9e2024-03-07 21:44:26 +08002742 switch (base) {
2743 case 0: /* port-based 0x2x40[18:16] */
2744 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2745 (0x2 << 12) | (0x7 << 16) | (0x2 << 20));
2746 break;
2747 case 1: /* tagged-based 0x2x40[10:8] */
2748 *value |= ((0x2 << 0) | (0x2 << 4) | (0x7 << 8) |
2749 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2750 break;
2751 case 2: /* DSCP-based 0x2x40[14:12] */
2752 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2753 (0x7 << 12) | (0x2 << 16) | (0x2 << 20));
2754 break;
2755 case 3: /* acl-based 0x2x40[2:0] */
2756 *value |= ((0x7 << 0) | (0x2 << 4) | (0x2 << 8) |
2757 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2758 break;
2759 case 4: /* arl-based 0x2x40[22:20] */
2760 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2761 (0x2 << 12) | (0x2 << 16) | (0x7 << 20));
2762 break;
2763 case 5: /* stag-based 0x2x40[6:4] */
2764 *value |= ((0x2 << 0) | (0x7 << 4) | (0x2 << 8) |
2765 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2766 break;
2767 default:
2768 break;
developerfd40db22021-04-29 10:08:25 +08002769 }
2770}
2771
2772void qos_set_base(int argc, char *argv[])
2773{
2774 unsigned char base = 0;
developerbe40a9e2024-03-07 21:44:26 +08002775 unsigned char port = 0;
2776 unsigned int value = 0;
developer546b2792024-06-15 20:31:38 +08002777 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002778
2779 if (argc < 5)
2780 return;
2781
developer546b2792024-06-15 20:31:38 +08002782 errno = 0;
2783 port = strtoul(argv[3], &endptr, 10);
2784 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2785 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
developerfd40db22021-04-29 10:08:25 +08002786 return;
2787 }
2788
developer546b2792024-06-15 20:31:38 +08002789 errno = 0;
2790 base = strtoul(argv[4], &endptr, 10);
2791 if (errno != 0 || *endptr != '\0' || base > 5) {
2792 printf(HELP_QOS_BASE);
developerfd40db22021-04-29 10:08:25 +08002793 return;
2794 }
2795
2796 printf("\r\nswitch qos base : %d. (port-based:0, tag-based:1,\
developerbe40a9e2024-03-07 21:44:26 +08002797 dscp-based:2, acl-based:3, arl-based:4, stag-based:5)\n", base);
developerfd40db22021-04-29 10:08:25 +08002798 if (chip_name == 0x7530) {
2799
2800 reg_read(0x44, &value);
2801 get_upw(&value, base);
2802 reg_write(0x44, value);
2803 printf("reg: 0x44, value: 0x%x\n", value);
2804
developer8c3871b2022-07-01 14:07:53 +08002805 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002806
2807 reg_read(GSW_UPW(port), &value);
2808 get_upw(&value, base);
2809 reg_write(GSW_UPW(port), value);
developerbe40a9e2024-03-07 21:44:26 +08002810 printf("reg:0x%x, value: 0x%x\n", GSW_UPW(port), value);
developerfd40db22021-04-29 10:08:25 +08002811
2812 } else {
2813 printf("unknown switch device");
2814 return;
2815 }
2816}
2817
2818void qos_wfq_set_weight(int argc, char *argv[])
2819{
developerbe40a9e2024-03-07 21:44:26 +08002820 int port = 0, weight[8], i = 0;
2821 unsigned char queue = 0;
2822 unsigned int reg = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002823
2824 port = atoi(argv[3]);
2825
2826 for (i = 0; i < 8; i++) {
2827 weight[i] = atoi(argv[i + 4]);
2828 }
2829
2830 /* MT7530 total 7 port */
2831 if (port < 0 || port > 6) {
2832 printf(HELP_QOS_PORT_WEIGHT);
2833 return;
2834 }
2835
2836 for (i = 0; i < 8; i++) {
2837 if (weight[i] < 1 || weight[i] > 16) {
2838 printf(HELP_QOS_PORT_WEIGHT);
2839 return;
2840 }
2841 }
2842 printf("port: %x, q0: %x, q1: %x, q2: %x, q3: %x, \
developerbe40a9e2024-03-07 21:44:26 +08002843 q4: %x, q5: %x, q6: %x, q7: %x\n", port, weight[0], weight[1], weight[2], weight[3], weight[4], weight[5], weight[6], weight[7]);
developerfd40db22021-04-29 10:08:25 +08002844
2845 for (queue = 0; queue < 8; queue++) {
2846 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2847 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002848 value &= (~(0xf << 24)); //bit24~27
developerfd40db22021-04-29 10:08:25 +08002849 value |= (((weight[queue] - 1) & 0xf) << 24);
2850 printf("reg: %x, value: %x\n", reg, value);
2851 reg_write(reg, value);
2852 }
2853}
2854
2855void qos_set_portpri(int argc, char *argv[])
2856{
developerbe40a9e2024-03-07 21:44:26 +08002857 unsigned char port = 0, prio = 0;
2858 unsigned int value = 0;
developer546b2792024-06-15 20:31:38 +08002859 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002860
developer546b2792024-06-15 20:31:38 +08002861 errno = 0;
2862 port = strtoul(argv[3], &endptr, 10);
2863 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2864 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2865 return;
2866 }
developerfd40db22021-04-29 10:08:25 +08002867
developer546b2792024-06-15 20:31:38 +08002868 errno = 0;
2869 prio = strtoul(argv[4], &endptr, 10);
2870 if (errno != 0 || *endptr != '\0' || prio > 7) {
2871 printf("Error: wrong priority, should be within 0~7\n");
developerfd40db22021-04-29 10:08:25 +08002872 return;
2873 }
2874
2875 reg_read(GSW_PCR(port), &value);
2876 value &= (~(0x7 << 24));
2877 value |= (prio << 24);
2878 reg_write(GSW_PCR(port), value);
2879 printf("write reg: %x, value: %x\n", GSW_PCR(port), value);
2880}
2881
2882void qos_set_dscppri(int argc, char *argv[])
2883{
developerbe40a9e2024-03-07 21:44:26 +08002884 unsigned char prio = 0, dscp = 0, pim_n = 0, pim_offset = 0;
2885 unsigned int value = 0, reg = 0;
developer546b2792024-06-15 20:31:38 +08002886 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002887
developer546b2792024-06-15 20:31:38 +08002888 errno = 0;
2889 dscp = strtoul(argv[3], &endptr, 10);
2890 if (errno != 0 || *endptr != '\0' || dscp > 63) {
2891 printf(HELP_QOS_DSCP_PRIO);
2892 return;
2893 }
developerfd40db22021-04-29 10:08:25 +08002894
developer546b2792024-06-15 20:31:38 +08002895 errno = 0;
2896 prio = strtoul(argv[4], &endptr, 10);
2897 if (errno != 0 || *endptr != '\0' || prio > 7) {
developerfd40db22021-04-29 10:08:25 +08002898 printf(HELP_QOS_DSCP_PRIO);
2899 return;
2900 }
2901
2902 pim_n = dscp / 10;
2903 pim_offset = (dscp - pim_n * 10) * 3;
2904 reg = 0x0058 + pim_n * 4;
2905 reg_read(reg, &value);
2906 value &= (~(0x7 << pim_offset));
2907 value |= ((prio & 0x7) << pim_offset);
2908 reg_write(reg, value);
2909 printf("write reg: %x, value: %x\n", reg, value);
2910}
2911
2912void qos_pri_mapping_queue(int argc, char *argv[])
2913{
developerbe40a9e2024-03-07 21:44:26 +08002914 unsigned char prio = 0, queue = 0, pem_n = 0, port = 0;
2915 unsigned int value = 0, reg = 0;
developer546b2792024-06-15 20:31:38 +08002916 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002917
2918 if (argc < 6)
2919 return;
2920
developer546b2792024-06-15 20:31:38 +08002921 errno = 0;
2922 port = strtoul(argv[3], &endptr, 10);
2923 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2924 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2925 return;
2926 }
2927
2928 errno = 0;
2929 prio = strtoul(argv[4], &endptr, 10);
2930 if (errno != 0 || *endptr != '\0' || prio > 7) {
2931 printf(HELP_QOS_PRIO_QMAP);
2932 return;
2933 }
developerfd40db22021-04-29 10:08:25 +08002934
developer546b2792024-06-15 20:31:38 +08002935 errno = 0;
2936 queue = strtoul(argv[5], &endptr, 10);
2937 if (errno != 0 || *endptr != '\0' || queue > 7) {
developerfd40db22021-04-29 10:08:25 +08002938 printf(HELP_QOS_PRIO_QMAP);
2939 return;
2940 }
developerbe40a9e2024-03-07 21:44:26 +08002941
developerfd40db22021-04-29 10:08:25 +08002942 if (chip_name == 0x7530) {
2943 pem_n = prio / 2;
2944 reg = pem_n * 0x4 + 0x48;
2945 reg_read(reg, &value);
2946 if (prio % 2) {
2947 value &= (~(0x7 << 24));
2948 value |= ((queue & 0x7) << 24);
2949 } else {
2950 value &= (~(0x7 << 8));
2951 value |= ((queue & 0x7) << 8);
2952 }
2953 reg_write(reg, value);
2954 printf("write reg: %x, value: %x\n", reg, value);
developer8c3871b2022-07-01 14:07:53 +08002955 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002956 pem_n = prio / 2;
2957 reg = GSW_PEM(pem_n) + 0x100 * port;
2958 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002959 if (prio % 2) { // 1 1
developerfd40db22021-04-29 10:08:25 +08002960 value &= (~(0x7 << 25));
2961 value |= ((queue & 0x7) << 25);
developerbe40a9e2024-03-07 21:44:26 +08002962 } else { // 0 0
developerfd40db22021-04-29 10:08:25 +08002963 value &= (~(0x7 << 9));
2964 value |= ((queue & 0x7) << 9);
2965 }
2966 reg_write(reg, value);
2967 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +08002968 } else {
developerfd40db22021-04-29 10:08:25 +08002969 printf("unknown switch device");
2970 return;
2971 }
2972}
2973
2974static int macMT753xVlanSetVid(unsigned char index, unsigned char active,
developerbe40a9e2024-03-07 21:44:26 +08002975 unsigned short vid, unsigned char portMap,
2976 unsigned char tagPortMap, unsigned char ivl_en,
2977 unsigned char fid, unsigned short stag)
developerfd40db22021-04-29 10:08:25 +08002978{
2979 unsigned int value = 0;
2980 unsigned int value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08002981 unsigned int reg = 0;
2982 int i = 0;
developerfd40db22021-04-29 10:08:25 +08002983
2984 printf("index: %x, active: %x, vid: %x, portMap: %x, \
developerbe40a9e2024-03-07 21:44:26 +08002985 tagPortMap: %x, ivl_en: %x, fid: %x, stag: %x\n", index, active, vid, portMap, tagPortMap, ivl_en, fid, stag);
developerfd40db22021-04-29 10:08:25 +08002986
2987 value = (portMap << 16);
2988 value |= (stag << 4);
2989 value |= (ivl_en << 30);
2990 value |= (fid << 1);
2991 value |= (active ? 1 : 0);
2992
2993 // total 7 ports
2994 for (i = 0; i < 7; i++) {
2995 if (tagPortMap & (1 << i))
2996 value2 |= 0x2 << (i * 2);
2997 }
2998
2999 if (value2)
developerbe40a9e2024-03-07 21:44:26 +08003000 value |= (1 << 28); // eg_tag
developerfd40db22021-04-29 10:08:25 +08003001
developerbe40a9e2024-03-07 21:44:26 +08003002 reg = 0x98; // VAWD2
developerfd40db22021-04-29 10:08:25 +08003003 reg_write(reg, value2);
3004
developerbe40a9e2024-03-07 21:44:26 +08003005 reg = 0x94; // VAWD1
developerfd40db22021-04-29 10:08:25 +08003006 reg_write(reg, value);
3007
developerbe40a9e2024-03-07 21:44:26 +08003008 reg = 0x90; // VTCR
developerfd40db22021-04-29 10:08:25 +08003009 value = (0x80001000 + vid);
3010 reg_write(reg, value);
3011
developerbe40a9e2024-03-07 21:44:26 +08003012 reg = 0x90; // VTCR
developerfd40db22021-04-29 10:08:25 +08003013 while (1) {
3014 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003015 if ((value & 0x80000000) == 0) //table busy
developerfd40db22021-04-29 10:08:25 +08003016 break;
3017 }
3018
3019 /* switch clear */
3020 reg = 0x80;
3021 reg_write(reg, 0x8002);
3022 usleep(5000);
3023 reg_read(reg, &value);
3024
3025 printf("SetVid: index:%d active:%d vid:%d portMap:%x tagPortMap:%x\r\n",
3026 index, active, vid, portMap, tagPortMap);
3027 return 0;
3028
developerbe40a9e2024-03-07 21:44:26 +08003029} /*end macMT753xVlanSetVid */
developerfd40db22021-04-29 10:08:25 +08003030
3031static int macMT753xVlanSetPvid(unsigned char port, unsigned short pvid)
3032{
developerbe40a9e2024-03-07 21:44:26 +08003033 unsigned int value = 0;
3034 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08003035
developerbe40a9e2024-03-07 21:44:26 +08003036 /*Parameters is error */
developerfd40db22021-04-29 10:08:25 +08003037 if (port > 6)
3038 return -1;
3039
3040 reg = 0x2014 + (port * 0x100);
3041 reg_read(reg, &value);
3042 value &= ~0xfff;
3043 value |= pvid;
3044 reg_write(reg, value);
3045
3046 /* switch clear */
3047 reg = 0x80;
3048 reg_write(reg, 0x8002);
3049 usleep(5000);
3050 reg_read(reg, &value);
3051
3052 printf("SetPVID: port:%d pvid:%d\r\n", port, pvid);
3053 return 0;
3054}
developerfd40db22021-04-29 10:08:25 +08003055
3056void doVlanSetPvid(int argc, char *argv[])
3057{
3058 unsigned char port = 0;
3059 unsigned short pvid = 0;
developer3a780bf2024-06-15 20:34:27 +08003060 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003061
developer3a780bf2024-06-15 20:34:27 +08003062 errno = 0;
3063 port = strtoul(argv[3], &endptr, 10);
3064 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3065 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3066 return;
3067 }
3068
3069 errno = 0;
3070 pvid = strtoul(argv[4], &endptr, 10);
3071 if (errno != 0 || *endptr != '\0' || pvid > MAX_VID_VALUE) {
developerfd40db22021-04-29 10:08:25 +08003072 printf(HELP_VLAN_PVID);
3073 return;
3074 }
3075
3076 macMT753xVlanSetPvid(port, pvid);
3077
3078 printf("port:%d pvid:%d,vlancap: max_port:%d maxvid:%d\r\n",
3079 port, pvid, SWITCH_MAX_PORT, MAX_VID_VALUE);
developerbe40a9e2024-03-07 21:44:26 +08003080} /*end doVlanSetPvid */
developerfd40db22021-04-29 10:08:25 +08003081
3082void doVlanSetVid(int argc, char *argv[])
3083{
developer3a780bf2024-06-15 20:34:27 +08003084 unsigned char index = 0, active = 0;
3085 unsigned char portMap = 0, tagPortMap = 0;
3086 unsigned short vid = 0, stag = 0;
3087 unsigned char ivl_en = 0, fid = 0;
3088 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003089
developer3a780bf2024-06-15 20:34:27 +08003090 errno = 0;
3091 index = strtoul(argv[3], &endptr, 10);
3092 if (errno != 0 || *endptr != '\0' || index >= MAX_VLAN_RULE) {
3093 printf(HELP_VLAN_VID);
3094 return;
3095 }
developerfd40db22021-04-29 10:08:25 +08003096
developer3a780bf2024-06-15 20:34:27 +08003097 errno = 0;
3098 active = strtoul(argv[4], &endptr, 10);
3099 if (errno != 0 || *endptr != '\0' || active > ACTIVED) {
3100 printf(HELP_VLAN_VID);
3101 return;
3102 }
developerfd40db22021-04-29 10:08:25 +08003103
developer3a780bf2024-06-15 20:34:27 +08003104 errno = 0;
3105 vid = strtoul(argv[5], &endptr, 10);
3106 if (errno != 0 || *endptr != '\0' || vid >= 4096) {
3107 printf(HELP_VLAN_VID);
3108 return;
3109 }
3110
3111 errno = 0;
3112 portMap = strtoul(argv[6], &endptr, 10);
3113 if (errno != 0 || *endptr != '\0') {
developerfd40db22021-04-29 10:08:25 +08003114 printf(HELP_VLAN_VID);
3115 return;
3116 }
3117
developer3a780bf2024-06-15 20:34:27 +08003118 errno = 0;
3119 tagPortMap = strtoul(argv[7], &endptr, 10);
3120 if (errno != 0 || *endptr != '\0') {
3121 printf(HELP_VLAN_VID);
3122 return;
3123 }
developerfd40db22021-04-29 10:08:25 +08003124
3125 printf("subcmd parameter argc = %d\r\n", argc);
3126 if (argc >= 9) {
developer3a780bf2024-06-15 20:34:27 +08003127 errno = 0;
3128 ivl_en = strtoul(argv[8], &endptr, 10);
3129 if (errno != 0 || *endptr != '\0') {
3130 printf(HELP_VLAN_VID);
3131 return;
3132 }
developerfd40db22021-04-29 10:08:25 +08003133 if (argc >= 10) {
developer3a780bf2024-06-15 20:34:27 +08003134 errno = 0;
3135 fid = strtoul(argv[9], &endptr, 16);
3136 if (errno != 0 || *endptr != '\0') {
3137 printf(HELP_VLAN_VID);
3138 return;
3139 }
3140 if (argc >= 11) {
3141 errno = 0;
3142 stag = strtoul(argv[10], &endptr, 10);
3143 if (errno != 0 || *endptr != '\0') {
3144 printf(HELP_VLAN_VID);
3145 return;
3146 }
3147 }
developerfd40db22021-04-29 10:08:25 +08003148 }
3149 }
3150 macMT753xVlanSetVid(index, active, vid, portMap, tagPortMap,
3151 ivl_en, fid, stag);
3152 printf("index:%d active:%d vid:%d\r\n", index, active, vid);
developerbe40a9e2024-03-07 21:44:26 +08003153} /*end doVlanSetVid */
developerfd40db22021-04-29 10:08:25 +08003154
3155void doVlanSetAccFrm(int argc, char *argv[])
3156{
3157 unsigned char port = 0;
3158 unsigned char type = 0;
developerbe40a9e2024-03-07 21:44:26 +08003159 unsigned int value = 0;
3160 unsigned int reg = 0;
developer3a780bf2024-06-15 20:34:27 +08003161 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003162
developer3a780bf2024-06-15 20:34:27 +08003163 errno = 0;
3164 port = strtoul(argv[3], &endptr, 10);
3165 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3166 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3167 return;
3168 }
developerfd40db22021-04-29 10:08:25 +08003169
developer3a780bf2024-06-15 20:34:27 +08003170 errno = 0;
3171 type = strtoul(argv[4], &endptr, 10);
3172 if (errno != 0 || *endptr != '\0' || type > REG_PVC_ACC_FRM_RELMASK) {
developerfd40db22021-04-29 10:08:25 +08003173 printf(HELP_VLAN_ACC_FRM);
3174 return;
3175 }
3176
developer3a780bf2024-06-15 20:34:27 +08003177 printf("port: %d, type: %d\n", port, type);
3178
developerfd40db22021-04-29 10:08:25 +08003179 reg = REG_PVC_P0_ADDR + port * 0x100;
3180 reg_read(reg, &value);
3181 value &= (~REG_PVC_ACC_FRM_MASK);
3182 value |= ((unsigned int)type << REG_PVC_ACC_FRM_OFFT);
3183
3184 printf("write reg: %x, value: %x\n", reg, value);
3185 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003186} /*end doVlanSetAccFrm */
developerfd40db22021-04-29 10:08:25 +08003187
3188void doVlanSetPortAttr(int argc, char *argv[])
3189{
3190 unsigned char port = 0;
3191 unsigned char attr = 0;
developerbe40a9e2024-03-07 21:44:26 +08003192 unsigned int value = 0;
3193 unsigned int reg = 0;
developer3a780bf2024-06-15 20:34:27 +08003194 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003195
developer3a780bf2024-06-15 20:34:27 +08003196 errno = 0;
3197 port = strtoul(argv[3], &endptr, 10);
3198 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3199 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3200 return;
3201 }
developerfd40db22021-04-29 10:08:25 +08003202
developer3a780bf2024-06-15 20:34:27 +08003203 errno = 0;
3204 attr = strtoul(argv[4], &endptr, 10);
3205 if (errno != 0 || *endptr != '\0' || attr > 3) {
developerfd40db22021-04-29 10:08:25 +08003206 printf(HELP_VLAN_PORT_ATTR);
3207 return;
3208 }
3209
developer3a780bf2024-06-15 20:34:27 +08003210 printf("port: %x, attr: %x\n", port, attr);
3211
developerfd40db22021-04-29 10:08:25 +08003212 reg = 0x2010 + port * 0x100;
3213 reg_read(reg, &value);
3214 value &= (0xffffff3f);
3215 value |= (attr << 6);
3216
3217 printf("write reg: %x, value: %x\n", reg, value);
3218 reg_write(reg, value);
3219}
3220
3221void doVlanSetPortMode(int argc, char *argv[])
3222{
3223 unsigned char port = 0;
3224 unsigned char mode = 0;
developerbe40a9e2024-03-07 21:44:26 +08003225 unsigned int value = 0;
3226 unsigned int reg = 0;
developer3a780bf2024-06-15 20:34:27 +08003227 char *endptr;
developerbe40a9e2024-03-07 21:44:26 +08003228
developer3a780bf2024-06-15 20:34:27 +08003229 errno = 0;
3230 port = strtoul(argv[3], &endptr, 10);
3231 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3232 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3233 return;
3234 }
developerfd40db22021-04-29 10:08:25 +08003235
developer3a780bf2024-06-15 20:34:27 +08003236 errno = 0;
3237 mode = strtoul(argv[4], &endptr, 10);
3238 if (errno != 0 || *endptr != '\0' || mode > 3) {
developerfd40db22021-04-29 10:08:25 +08003239 printf(HELP_VLAN_PORT_MODE);
3240 return;
3241 }
3242
developer3a780bf2024-06-15 20:34:27 +08003243 printf("port: %x, mode: %x\n", port, mode);
3244
developerfd40db22021-04-29 10:08:25 +08003245 reg = 0x2004 + port * 0x100;
3246 reg_read(reg, &value);
3247 value &= (~((1 << 0) | (1 << 1)));
3248 value |= (mode & 0x3);
3249 printf("write reg: %x, value: %x\n", reg, value);
3250 reg_write(reg, value);
3251}
3252
3253void doVlanSetEgressTagPCR(int argc, char *argv[])
3254{
3255 unsigned char port = 0;
3256 unsigned char eg_tag = 0;
developerbe40a9e2024-03-07 21:44:26 +08003257 unsigned int value = 0;
3258 unsigned int reg = 0;
developer3a780bf2024-06-15 20:34:27 +08003259 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003260
developer3a780bf2024-06-15 20:34:27 +08003261 errno = 0;
3262 port = strtoul(argv[3], &endptr, 10);
3263 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3264 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3265 return;
3266 }
developerfd40db22021-04-29 10:08:25 +08003267
developer3a780bf2024-06-15 20:34:27 +08003268 errno = 0;
3269 eg_tag = strtoul(argv[4], &endptr, 10);
3270 if (errno != 0 || *endptr != '\0' || (eg_tag > REG_PCR_EG_TAG_RELMASK)) {
developerfd40db22021-04-29 10:08:25 +08003271 printf(HELP_VLAN_EGRESS_TAG_PCR);
3272 return;
3273 }
3274
developer3a780bf2024-06-15 20:34:27 +08003275 printf("port: %d, eg_tag: %d\n", port, eg_tag);
3276
developerfd40db22021-04-29 10:08:25 +08003277 reg = REG_PCR_P0_ADDR + port * 0x100;
3278 reg_read(reg, &value);
3279 value &= (~REG_PCR_EG_TAG_MASK);
3280 value |= ((unsigned int)eg_tag << REG_PCR_EG_TAG_OFFT);
3281
3282 printf("write reg: %x, value: %x\n", reg, value);
3283 reg_write(reg, value);
3284
developerbe40a9e2024-03-07 21:44:26 +08003285} /*end doVlanSetEgressTagPCR */
developerfd40db22021-04-29 10:08:25 +08003286
3287void doVlanSetEgressTagPVC(int argc, char *argv[])
3288{
3289 unsigned char port = 0;
3290 unsigned char eg_tag = 0;
developerbe40a9e2024-03-07 21:44:26 +08003291 unsigned int value = 0;
3292 unsigned int reg = 0;
developer3a780bf2024-06-15 20:34:27 +08003293 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003294
developer3a780bf2024-06-15 20:34:27 +08003295 errno = 0;
3296 port = strtoul(argv[3], &endptr, 10);
3297 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3298 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3299 return;
3300 }
developerfd40db22021-04-29 10:08:25 +08003301
developer3a780bf2024-06-15 20:34:27 +08003302 errno = 0;
3303 eg_tag = strtoul(argv[4], &endptr, 10);
3304 if (errno != 0 || *endptr != '\0' || (eg_tag > REG_PVC_EG_TAG_RELMASK)) {
developerfd40db22021-04-29 10:08:25 +08003305 printf(HELP_VLAN_EGRESS_TAG_PVC);
3306 return;
3307 }
3308
developer3a780bf2024-06-15 20:34:27 +08003309 printf("port: %d, eg_tag: %d\n", port, eg_tag);
3310
developerfd40db22021-04-29 10:08:25 +08003311 reg = REG_PVC_P0_ADDR + port * 0x100;
3312 reg_read(reg, &value);
3313 value &= (~REG_PVC_EG_TAG_MASK);
3314 value |= ((unsigned int)eg_tag << REG_PVC_EG_TAG_OFFT);
3315
3316 printf("write reg: %x, value: %x\n", reg, value);
3317 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003318} /*end doVlanSetEgressTagPVC */
developerfd40db22021-04-29 10:08:25 +08003319
3320void doArlAging(int argc, char *argv[])
3321{
3322 unsigned char aging_en = 0;
developer2fdae312024-06-15 20:36:12 +08003323 unsigned int time = 0, aging_cnt = 0, aging_unit = 0;
3324 unsigned int value = 0, reg = 0;
3325 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003326
developer2fdae312024-06-15 20:36:12 +08003327 errno = 0;
3328 aging_en = strtoul(argv[3], &endptr, 10);
3329 if (errno != 0 || *endptr != '\0' || aging_en > 1) {
3330 printf(HELP_ARL_AGING);
3331 return;
3332 }
developerfd40db22021-04-29 10:08:25 +08003333
developer2fdae312024-06-15 20:36:12 +08003334 errno = 0;
3335 time = strtoul(argv[4], &endptr, 10);
3336 if (errno != 0 || *endptr != '\0' || (time <= 0 || time > 65536)) {
developerfd40db22021-04-29 10:08:25 +08003337 printf(HELP_ARL_AGING);
3338 return;
3339 }
3340
developer2fdae312024-06-15 20:36:12 +08003341 printf("aging_en: %x, aging time: %x\n", aging_en, time);
3342
developerfd40db22021-04-29 10:08:25 +08003343 reg = 0xa0;
3344 reg_read(reg, &value);
3345 value &= (~(1 << 20));
3346 if (!aging_en) {
3347 value |= (1 << 20);
3348 }
3349
3350 aging_unit = (time / 0x100) + 1;
3351 aging_cnt = (time / aging_unit);
3352 aging_unit--;
3353 aging_cnt--;
3354
3355 value &= (0xfff00000);
3356 value |= ((aging_cnt << 12) | aging_unit);
3357
3358 printf("aging_unit: %x, aging_cnt: %x\n", aging_unit, aging_cnt);
3359 printf("write reg: %x, value: %x\n", reg, value);
3360
3361 reg_write(reg, value);
3362}
3363
3364void doMirrorEn(int argc, char *argv[])
3365{
developerbe40a9e2024-03-07 21:44:26 +08003366 unsigned char mirror_en = 0;
3367 unsigned char mirror_port = 0;
3368 unsigned int value = 0, reg = 0;
developer2fdae312024-06-15 20:36:12 +08003369 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003370
developer2fdae312024-06-15 20:36:12 +08003371 errno = 0;
3372 mirror_en = strtoul(argv[3], &endptr, 10);
3373 if (errno != 0 || *endptr != '\0' || mirror_en > 1) {
3374 printf(HELP_MIRROR_EN);
3375 return;
3376 }
developerfd40db22021-04-29 10:08:25 +08003377
developer2fdae312024-06-15 20:36:12 +08003378 errno = 0;
3379 mirror_port = strtoul(argv[4], &endptr, 10);
3380 if (errno != 0 || *endptr != '\0' || mirror_port > REG_CFC_MIRROR_PORT_RELMASK) {
developerfd40db22021-04-29 10:08:25 +08003381 printf(HELP_MIRROR_EN);
3382 return;
3383 }
3384
developer2fdae312024-06-15 20:36:12 +08003385 printf("mirror_en: %d, mirror_port: %d\n", mirror_en, mirror_port);
3386
developerfd40db22021-04-29 10:08:25 +08003387 reg = REG_CFC_ADDR;
3388 reg_read(reg, &value);
3389 value &= (~REG_CFC_MIRROR_EN_MASK);
3390 value |= (mirror_en << REG_CFC_MIRROR_EN_OFFT);
3391 value &= (~REG_CFC_MIRROR_PORT_MASK);
3392 value |= (mirror_port << REG_CFC_MIRROR_PORT_OFFT);
3393
3394 printf("write reg: %x, value: %x\n", reg, value);
3395 reg_write(reg, value);
3396
developerbe40a9e2024-03-07 21:44:26 +08003397} /*end doMirrorEn */
developerfd40db22021-04-29 10:08:25 +08003398
3399void doMirrorPortBased(int argc, char *argv[])
3400{
developerbe40a9e2024-03-07 21:44:26 +08003401 unsigned char port = 0, port_tx_mir = 0, port_rx_mir = 0, vlan_mis =
3402 0, acl_mir = 0, igmp_mir = 0;
3403 unsigned int value = 0, reg = 0;
developer2fdae312024-06-15 20:36:12 +08003404 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003405
developer2fdae312024-06-15 20:36:12 +08003406 errno = 0;
3407 port = strtoul(argv[3], &endptr, 10);
3408 if (errno != 0 || *endptr != '\0' || port > MAX_PORT)
3409 goto error;
3410
3411 errno = 0;
3412 port_tx_mir = strtoul(argv[4], &endptr, 10);
3413 if (errno != 0 || *endptr != '\0' || port_tx_mir > 1)
3414 goto error;
3415
3416 errno = 0;
3417 port_rx_mir = strtoul(argv[5], &endptr, 10);
3418 if (errno != 0 || *endptr != '\0' || port_rx_mir > 1)
3419 goto error;
3420
3421 errno = 0;
3422 acl_mir = strtoul(argv[6], &endptr, 10);
3423 if (errno != 0 || *endptr != '\0' || acl_mir > 1)
3424 goto error;
3425
3426 errno = 0;
3427 vlan_mis = strtoul(argv[7], &endptr, 10);
3428 if (errno != 0 || *endptr != '\0' || vlan_mis > 1)
3429 goto error;
3430
3431 errno = 0;
3432 igmp_mir = strtoul(argv[8], &endptr, 10);
3433 if (errno != 0 || *endptr != '\0' || igmp_mir > 1)
3434 goto error;
developerfd40db22021-04-29 10:08:25 +08003435
developerbe40a9e2024-03-07 21:44:26 +08003436 printf
3437 ("port:%d, port_tx_mir:%d, port_rx_mir:%d, acl_mir:%d, vlan_mis:%d, igmp_mir:%d\n",
3438 port, port_tx_mir, port_rx_mir, acl_mir, vlan_mis, igmp_mir);
developerfd40db22021-04-29 10:08:25 +08003439
developerfd40db22021-04-29 10:08:25 +08003440 reg = REG_PCR_P0_ADDR + port * 0x100;
3441 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003442 value &=
3443 ~(REG_PORT_TX_MIR_MASK | REG_PORT_RX_MIR_MASK | REG_PCR_ACL_MIR_MASK
3444 | REG_PCR_VLAN_MIS_MASK);
3445 value |=
3446 (port_tx_mir << REG_PORT_TX_MIR_OFFT) +
3447 (port_rx_mir << REG_PORT_RX_MIR_OFFT);
3448 value |=
3449 (acl_mir << REG_PCR_ACL_MIR_OFFT) +
3450 (vlan_mis << REG_PCR_VLAN_MIS_OFFT);
developerfd40db22021-04-29 10:08:25 +08003451
3452 printf("write reg: %x, value: %x\n", reg, value);
3453 reg_write(reg, value);
3454
3455 reg = REG_PIC_P0_ADDR + port * 0x100;
3456 reg_read(reg, &value);
3457 value &= ~(REG_PIC_IGMP_MIR_MASK);
3458 value |= (igmp_mir << REG_PIC_IGMP_MIR_OFFT);
3459
3460 printf("write reg: %x, value: %x\n", reg, value);
3461 reg_write(reg, value);
developer2fdae312024-06-15 20:36:12 +08003462 return;
developerfd40db22021-04-29 10:08:25 +08003463
developer2fdae312024-06-15 20:36:12 +08003464error:
3465 printf(HELP_MIRROR_PORTBASED);
3466 return;
developerbe40a9e2024-03-07 21:44:26 +08003467} /*end doMirrorPortBased */
developerfd40db22021-04-29 10:08:25 +08003468
3469void doStp(int argc, char *argv[])
3470{
3471 unsigned char port = 0;
3472 unsigned char fid = 0;
3473 unsigned char state = 0;
developerbe40a9e2024-03-07 21:44:26 +08003474 unsigned int value = 0;
3475 unsigned int reg = 0;
developer2fdae312024-06-15 20:36:12 +08003476 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003477
developer2fdae312024-06-15 20:36:12 +08003478 errno = 0;
3479 port = strtoul(argv[2], &endptr, 10);
3480 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3481 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3482 return;
3483 }
developerfd40db22021-04-29 10:08:25 +08003484
developer2fdae312024-06-15 20:36:12 +08003485 errno = 0;
3486 fid = strtoul(argv[3], &endptr, 10);
3487 if (errno != 0 || *endptr != '\0' || fid > 7) {
3488 printf(HELP_STP);
3489 return;
3490 }
developerfd40db22021-04-29 10:08:25 +08003491
developer2fdae312024-06-15 20:36:12 +08003492 errno = 0;
3493 state = strtoul(argv[4], &endptr, 10);
3494 if (errno != 0 || *endptr != '\0' || state > 3) {
developerfd40db22021-04-29 10:08:25 +08003495 printf(HELP_STP);
3496 return;
3497 }
3498
developer2fdae312024-06-15 20:36:12 +08003499 printf("port: %d, fid: %d, state: %d\n", port, fid, state);
3500
developerfd40db22021-04-29 10:08:25 +08003501 reg = REG_SSC_P0_ADDR + port * 0x100;
3502 reg_read(reg, &value);
3503 value &= (~(3 << (fid << 2)));
3504 value |= ((unsigned int)state << (fid << 2));
3505
3506 printf("write reg: %x, value: %x\n", reg, value);
3507 reg_write(reg, value);
3508}
3509
developerbe40a9e2024-03-07 21:44:26 +08003510void _ingress_rate_set(int on_off, int port, int bw)
developerfd40db22021-04-29 10:08:25 +08003511{
developerbe40a9e2024-03-07 21:44:26 +08003512 unsigned int reg = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08003513
3514 reg = 0x1800 + (0x100 * port);
3515 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08003516 /*token-bucket */
developerfd40db22021-04-29 10:08:25 +08003517 if (on_off == 1) {
3518 if (chip_name == 0x7530) {
3519 if (bw > 1000000) {
developerbe40a9e2024-03-07 21:44:26 +08003520 printf
3521 ("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",
3522 bw);
3523 return;
developerfd40db22021-04-29 10:08:25 +08003524 }
developerbe40a9e2024-03-07 21:44:26 +08003525 value =
3526 ((bw / 32) << 16) + (1 << 15) + (7 << 8) +
3527 (1 << 7) + 0x0f;
developer8c3871b2022-07-01 14:07:53 +08003528 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3529 if ((chip_name == 0x7531) && (bw > 2500000)) {
developerbe40a9e2024-03-07 21:44:26 +08003530 printf
3531 ("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",
3532 bw);
3533 return;
developerfd40db22021-04-29 10:08:25 +08003534 }
developer8c3871b2022-07-01 14:07:53 +08003535
3536 if ((chip_name == 0x7988) && (bw > 4000000)) {
developerbe40a9e2024-03-07 21:44:26 +08003537 printf
3538 ("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",
3539 bw);
3540 return;
developerfd40db22021-04-29 10:08:25 +08003541 }
developer8c3871b2022-07-01 14:07:53 +08003542
developerbe40a9e2024-03-07 21:44:26 +08003543 if (bw / 32 >= 65536) //supoort 2.5G case
3544 value =
3545 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3546 (1 << 12) + (7 << 8) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003547 else
developerbe40a9e2024-03-07 21:44:26 +08003548 value =
3549 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3550 (7 << 8) + 0xf;
3551 } else
developerfd40db22021-04-29 10:08:25 +08003552 printf("unknow chip\n");
3553 }
developerfd40db22021-04-29 10:08:25 +08003554#if leaky_bucket
3555 reg_read(reg, &value);
3556 value &= 0xffff0000;
developerbe40a9e2024-03-07 21:44:26 +08003557 if (on_off == 1) {
developerfd40db22021-04-29 10:08:25 +08003558 value |= on_off << 15;
3559 //7530 same as 7531
3560 if (bw < 100) {
3561 value |= (0x0 << 8);
3562 value |= bw;
3563 } else if (bw < 1000) {
3564 value |= (0x1 << 8);
3565 value |= bw / 10;
3566 } else if (bw < 10000) {
3567 value |= (0x2 << 8);
3568 value |= bw / 100;
3569 } else if (bw < 100000) {
3570 value |= (0x3 << 8);
3571 value |= bw / 1000;
3572 } else {
3573 value |= (0x4 << 8);
3574 value |= bw / 10000;
3575 }
3576 }
3577#endif
3578 reg_write(reg, value);
3579 reg = 0x1FFC;
3580 reg_read(reg, &value);
3581 value = 0x110104;
3582 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003583
3584 if (on_off)
3585 printf("switch port=%d, bw=%d\n", port, bw);
3586 else
3587 printf("switch port=%d ingress rate limit off\n", port);
developerfd40db22021-04-29 10:08:25 +08003588}
3589
developerbe40a9e2024-03-07 21:44:26 +08003590void ingress_rate_set(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003591{
developerbe40a9e2024-03-07 21:44:26 +08003592 int on_off = 0, port = 0, bw = 0;
developer997ed6b2024-03-26 14:03:42 +08003593 char *endptr;
developerbe40a9e2024-03-07 21:44:26 +08003594
developer997ed6b2024-03-26 14:03:42 +08003595 /* clear errno before conversion to detect overflow */
3596 errno = 0;
3597 port = strtoul(argv[3], &endptr, 0);
3598
3599 if (errno == ERANGE) {
3600 printf("Conversion error, value out of range\n");
3601 return;
3602 }
3603 if (*endptr != '\0') {
3604 printf("Conversion error, no digits were found\n");
3605 return;
3606 }
3607
3608 if (port < 0 || port > 6) {
3609 printf("Wrong port range, should be within 0-6\n");
3610 return;
3611 }
3612
developerbe40a9e2024-03-07 21:44:26 +08003613 if (argv[2][1] == 'n') {
developer997ed6b2024-03-26 14:03:42 +08003614 errno = 0;
3615 bw = strtoul(argv[4], &endptr, 0);
3616 if (errno == ERANGE) {
3617 printf("Conversion error, value out of range\n");
3618 return;
3619 }
3620 if (*endptr != '\0') {
3621 printf("Conversion error, no digits were found\n");
3622 return;
3623 }
developerbe40a9e2024-03-07 21:44:26 +08003624 on_off = 1;
3625 } else if (argv[2][1] == 'f') {
3626 if (argc != 4)
3627 return;
3628 on_off = 0;
3629 }
3630
3631 _ingress_rate_set(on_off, port, bw);
3632}
3633
3634void _egress_rate_set(int on_off, int port, int bw)
3635{
3636 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003637
3638 reg = 0x1040 + (0x100 * port);
3639 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08003640 /*token-bucket */
developerfd40db22021-04-29 10:08:25 +08003641 if (on_off == 1) {
3642 if (chip_name == 0x7530) {
3643 if (bw < 0 || bw > 1000000) {
developerbe40a9e2024-03-07 21:44:26 +08003644 printf
3645 ("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",
3646 bw);
3647 return;
developerfd40db22021-04-29 10:08:25 +08003648 }
developerbe40a9e2024-03-07 21:44:26 +08003649 value =
3650 ((bw / 32) << 16) + (1 << 15) + (7 << 8) +
3651 (1 << 7) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003652 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3653 if ((chip_name == 0x7531) && (bw < 0 || bw > 2500000)) {
developerbe40a9e2024-03-07 21:44:26 +08003654 printf
3655 ("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",
3656 bw);
3657 return;
developerfd40db22021-04-29 10:08:25 +08003658 }
developer8c3871b2022-07-01 14:07:53 +08003659 if ((chip_name == 0x7988) && (bw < 0 || bw > 4000000)) {
developerbe40a9e2024-03-07 21:44:26 +08003660 printf
3661 ("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",
3662 bw);
3663 return;
developer8c3871b2022-07-01 14:07:53 +08003664 }
3665
developerbe40a9e2024-03-07 21:44:26 +08003666 if (bw / 32 >= 65536) //support 2.5G cases
3667 value =
3668 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3669 (1 << 12) + (7 << 8) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003670 else
developerbe40a9e2024-03-07 21:44:26 +08003671 value =
3672 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3673 (7 << 8) + 0xf;
3674 } else
developerfd40db22021-04-29 10:08:25 +08003675 printf("unknow chip\n");
3676 }
3677 reg_write(reg, value);
3678 reg = 0x10E0;
3679 reg_read(reg, &value);
3680 value &= 0x18;
3681 reg_write(reg, value);
3682
developerbe40a9e2024-03-07 21:44:26 +08003683 if (on_off)
3684 printf("switch port=%d, bw=%d\n", port, bw);
3685 else
3686 printf("switch port=%d egress rate limit off\n", port);
3687}
3688
3689void egress_rate_set(int argc, char *argv[])
3690{
3691 unsigned int value = 0, reg = 0;
3692 int on_off = 0, port = 0, bw = 0;
developer997ed6b2024-03-26 14:03:42 +08003693 char *endptr;
developerbe40a9e2024-03-07 21:44:26 +08003694
developer997ed6b2024-03-26 14:03:42 +08003695 /* clear errno before conversion to detect overflow */
3696 errno = 0;
3697 port = strtoul(argv[3], &endptr, 0);
3698 if (errno == ERANGE) {
3699 printf("Conversion error, value out of range\n");
3700 return;
3701 }
3702 if (*endptr != '\0') {
3703 printf("Conversion error, no digits were found\n");
3704 return;
3705 }
3706 if (port < 0 || port > 6) {
3707 printf("Wrong port range, should be within 0-6\n");
3708 return;
3709 }
developerbe40a9e2024-03-07 21:44:26 +08003710 if (argv[2][1] == 'n') {
developer997ed6b2024-03-26 14:03:42 +08003711 errno = 0;
3712 bw = strtoul(argv[4], &endptr, 0);
3713 if (errno == ERANGE) {
3714 printf("Conversion error, value out of range\n");
3715 return;
3716 }
3717 if (*endptr != '\0') {
3718 printf("Conversion error, no digits were found\n");
3719 return;
3720 }
developerbe40a9e2024-03-07 21:44:26 +08003721 on_off = 1;
3722 } else if (argv[2][1] == 'f') {
3723 if (argc != 4)
3724 return;
3725 on_off = 0;
3726 }
3727
3728 _egress_rate_set(on_off, port, bw);
developerfd40db22021-04-29 10:08:25 +08003729}
3730
3731void rate_control(int argc, char *argv[])
3732{
3733 unsigned char dir = 0;
3734 unsigned char port = 0;
3735 unsigned int rate = 0;
developer3a780bf2024-06-15 20:34:27 +08003736 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003737
developer3a780bf2024-06-15 20:34:27 +08003738 errno = 0;
3739 dir = strtoul(argv[2], &endptr, 10);
3740 if (errno != 0 || *endptr != '\0' || dir > 1) {
3741 printf("Error: wrong port member, should be 0:egress, 1:ingress\n");
3742 return;
3743 }
developerfd40db22021-04-29 10:08:25 +08003744
developer3a780bf2024-06-15 20:34:27 +08003745 errno = 0;
3746 port = strtoul(argv[3], &endptr, 10);
3747 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3748 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3749 return;
3750 }
3751
3752 errno = 0;
3753 rate = strtoul(argv[4], &endptr, 10);
3754 if (errno != 0 || *endptr != '\0') {
3755 printf("Error: wrong traffic rate, unit is kbps\n");
developerfd40db22021-04-29 10:08:25 +08003756 return;
developer3a780bf2024-06-15 20:34:27 +08003757 }
developerfd40db22021-04-29 10:08:25 +08003758
developerbe40a9e2024-03-07 21:44:26 +08003759 if (dir == 1) //ingress
3760 _ingress_rate_set(1, port, rate);
3761 else if (dir == 0) //egress
3762 _egress_rate_set(1, port, rate);
developerfd40db22021-04-29 10:08:25 +08003763}
3764
developerbe40a9e2024-03-07 21:44:26 +08003765void collision_pool_enable(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003766{
3767
developerbe40a9e2024-03-07 21:44:26 +08003768 unsigned char enable = 0;
3769 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003770
3771 enable = atoi(argv[3]);
3772
developerfd40db22021-04-29 10:08:25 +08003773 printf("collision pool enable: %d \n", enable);
3774
developerbe40a9e2024-03-07 21:44:26 +08003775 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003776 if (enable > 1) {
3777 printf(HELP_COLLISION_POOL_EN);
developerbe40a9e2024-03-07 21:44:26 +08003778 return;
developerfd40db22021-04-29 10:08:25 +08003779 }
3780
developer8c3871b2022-07-01 14:07:53 +08003781 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003782 reg = REG_CPGC_ADDR;
developerbe40a9e2024-03-07 21:44:26 +08003783 if (enable == 1) {
developerfd40db22021-04-29 10:08:25 +08003784 /* active reset */
3785 reg_read(reg, &value);
3786 value &= (~REG_CPCG_COL_RST_N_MASK);
3787 reg_write(reg, value);
3788
3789 /* enanble clock */
3790 reg_read(reg, &value);
3791 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3792 value |= (1 << REG_CPCG_COL_CLK_EN_OFFT);
3793 reg_write(reg, value);
3794
3795 /* inactive reset */
3796 reg_read(reg, &value);
3797 value &= (~REG_CPCG_COL_RST_N_MASK);
3798 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3799 reg_write(reg, value);
3800
3801 /* enable collision pool */
3802 reg_read(reg, &value);
3803 value &= (~REG_CPCG_COL_EN_MASK);
3804 value |= (1 << REG_CPCG_COL_EN_OFFT);
3805 reg_write(reg, value);
3806
3807 reg_read(reg, &value);
3808 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003809 } else {
developerfd40db22021-04-29 10:08:25 +08003810
3811 /* disable collision pool */
3812 reg_read(reg, &value);
3813 value &= (~REG_CPCG_COL_EN_MASK);
3814 reg_write(reg, value);
3815
3816 /* active reset */
3817 reg_read(reg, &value);
3818 value &= (~REG_CPCG_COL_RST_N_MASK);
3819 reg_write(reg, value);
3820
3821 /* inactive reset */
3822 reg_read(reg, &value);
3823 value &= (~REG_CPCG_COL_RST_N_MASK);
3824 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3825 reg_write(reg, value);
3826
3827 /* disable clock */
3828 reg_read(reg, &value);
3829 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3830 reg_write(reg, value);
3831
3832 reg_read(reg, &value);
3833 printf("write reg: %x, value: %x\n", reg, value);
3834
3835 }
developerbe40a9e2024-03-07 21:44:26 +08003836 } else {
developerfd40db22021-04-29 10:08:25 +08003837 printf("\nCommand not support by this chip.\n");
developerbe40a9e2024-03-07 21:44:26 +08003838 }
developerfd40db22021-04-29 10:08:25 +08003839}
3840
developerbe40a9e2024-03-07 21:44:26 +08003841void collision_pool_mac_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003842{
developerbe40a9e2024-03-07 21:44:26 +08003843 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003844
developer8c3871b2022-07-01 14:07:53 +08003845 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003846 reg = REG_CPGC_ADDR;
3847 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003848 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003849 table_dump_internal(COLLISION_TABLE);
3850 else
developerbe40a9e2024-03-07 21:44:26 +08003851 printf
3852 ("\ncollision pool is disabled, please enable it before use this command.\n");
3853 } else {
developerfd40db22021-04-29 10:08:25 +08003854 printf("\nCommand not support by this chip.\n");
3855 }
3856}
3857
developerbe40a9e2024-03-07 21:44:26 +08003858void collision_pool_dip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003859{
developerbe40a9e2024-03-07 21:44:26 +08003860 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003861
developer8c3871b2022-07-01 14:07:53 +08003862 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003863 reg = REG_CPGC_ADDR;
3864 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003865 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003866 dip_dump_internal(COLLISION_TABLE);
3867 else
developerbe40a9e2024-03-07 21:44:26 +08003868 printf
3869 ("\ncollision pool is disabled, please enable it before use this command.\n");
3870 } else {
developerfd40db22021-04-29 10:08:25 +08003871 printf("\nCommand not support by this chip.\n");
3872 }
developerfd40db22021-04-29 10:08:25 +08003873}
3874
developerbe40a9e2024-03-07 21:44:26 +08003875void collision_pool_sip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003876{
developerbe40a9e2024-03-07 21:44:26 +08003877 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003878
developerbe40a9e2024-03-07 21:44:26 +08003879 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003880 reg = REG_CPGC_ADDR;
3881 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003882 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003883 sip_dump_internal(COLLISION_TABLE);
3884 else
developerbe40a9e2024-03-07 21:44:26 +08003885 printf
3886 ("\ncollision pool is disabled, please enable it before use this command.\n");
3887 } else {
developerfd40db22021-04-29 10:08:25 +08003888 printf("\nCommand not support by this chip.\n");
3889 }
developerfd40db22021-04-29 10:08:25 +08003890}
3891
3892void pfc_get_rx_counter(int argc, char *argv[])
3893{
developerbe40a9e2024-03-07 21:44:26 +08003894 int port = 0;
3895 unsigned int value = 0, reg = 0;
3896 unsigned int user_pri = 0;
developerfd40db22021-04-29 10:08:25 +08003897
3898 port = strtoul(argv[3], NULL, 0);
3899 if (port < 0 || 6 < port) {
3900 printf("wrong port range, should be within 0~6\n");
3901 return;
3902 }
3903
developerbe40a9e2024-03-07 21:44:26 +08003904 if (chip_name == 0x7531 || chip_name == 0x7988) {
3905 reg = PFC_RX_COUNTER_L(port);
developerfd40db22021-04-29 10:08:25 +08003906 reg_read(reg, &value);
3907 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003908 printf("\n port %d rx pfc (up=0)pause on counter is %d.\n",
3909 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003910 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003911 printf("\n port %d rx pfc (up=1)pause on counter is %d.\n",
3912 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003913 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003914 printf("\n port %d rx pfc (up=2)pause on counter is %d.\n",
3915 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003916 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003917 printf("\n port %d rx pfc (up=3)pause on counter is %d.\n",
3918 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003919
developerbe40a9e2024-03-07 21:44:26 +08003920 reg = PFC_RX_COUNTER_H(port);
developerfd40db22021-04-29 10:08:25 +08003921 reg_read(reg, &value);
3922 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003923 printf("\n port %d rx pfc (up=4)pause on counter is %d.\n",
3924 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003925 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003926 printf("\n port %d rx pfc (up=5)pause on counter is %d.\n",
3927 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003928 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003929 printf("\n port %d rx pfc (up=6)pause on counter is %d.\n",
3930 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003931 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003932 printf("\n port %d rx pfc (up=7)pause on counter is %d.\n",
3933 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003934
3935 /* for rx counter could be updated successfully */
3936 reg_read(PMSR_P(port), &value);
3937 reg_read(PMSR_P(port), &value);
developerbe40a9e2024-03-07 21:44:26 +08003938 } else {
developerfd40db22021-04-29 10:08:25 +08003939 printf("\nCommand not support by this chip.\n");
3940 }
3941
3942}
3943
3944void pfc_get_tx_counter(int argc, char *argv[])
3945{
developerbe40a9e2024-03-07 21:44:26 +08003946 int port = 0;
3947 unsigned int value = 0, reg = 0;
3948 unsigned int user_pri = 0;
developerfd40db22021-04-29 10:08:25 +08003949
3950 port = strtoul(argv[3], NULL, 0);
3951 if (port < 0 || 6 < port) {
3952 printf("wrong port range, should be within 0~6\n");
3953 return;
3954 }
3955
developer8c3871b2022-07-01 14:07:53 +08003956 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerbe40a9e2024-03-07 21:44:26 +08003957 reg = PFC_TX_COUNTER_L(port);
developerfd40db22021-04-29 10:08:25 +08003958 reg_read(reg, &value);
3959 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003960 printf("\n port %d tx pfc (up=0)pause on counter is %d.\n",
3961 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003962 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003963 printf("\n port %d tx pfc (up=1)pause on counter is %d.\n",
3964 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003965 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003966 printf("\n port %d tx pfc (up=2)pause on counter is %d.\n",
3967 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003968 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003969 printf("\n port %d tx pfc (up=3)pause on counter is %d.\n",
3970 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003971
developerbe40a9e2024-03-07 21:44:26 +08003972 reg = PFC_TX_COUNTER_H(port);
developerfd40db22021-04-29 10:08:25 +08003973 reg_read(reg, &value);
3974 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003975 printf("\n port %d tx pfc (up=4)pause on counter is %d.\n",
3976 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003977 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003978 printf("\n port %d tx pfc (up=5)pause on counter is %d.\n",
3979 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003980 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003981 printf("\n port %d tx pfc (up=6)pause on counter is %d.\n",
3982 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003983 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003984 printf("\n port %d tx pfc (up=7)pause on counter is %d.\n",
3985 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003986
3987 /* for tx counter could be updated successfully */
3988 reg_read(PMSR_P(port), &value);
3989 reg_read(PMSR_P(port), &value);
developerbe40a9e2024-03-07 21:44:26 +08003990 } else {
3991 printf("\nCommand not support by this chip.\n");
developerfd40db22021-04-29 10:08:25 +08003992 }
3993}
3994
developerbe40a9e2024-03-07 21:44:26 +08003995void read_output_queue_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003996{
developerbe40a9e2024-03-07 21:44:26 +08003997 unsigned int port = 0;
3998 unsigned int value = 0, output_queue = 0;
3999 unsigned int base = 0x220;
developerfd40db22021-04-29 10:08:25 +08004000
4001 for (port = 0; port < 7; port++) {
developerbe40a9e2024-03-07 21:44:26 +08004002 reg_write(0x7038, base + (port * 4));
developerfd40db22021-04-29 10:08:25 +08004003 reg_read(0x7034, &value);
4004 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08004005 printf("\n port %d output queue 0 counter is %d.\n", port,
4006 output_queue);
developerfd40db22021-04-29 10:08:25 +08004007 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08004008 printf("\n port %d output queue 1 counter is %d.\n", port,
4009 output_queue);
developerfd40db22021-04-29 10:08:25 +08004010
developerbe40a9e2024-03-07 21:44:26 +08004011 reg_write(0x7038, base + (port * 4) + 1);
developerfd40db22021-04-29 10:08:25 +08004012 reg_read(0x7034, &value);
4013 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08004014 printf("\n port %d output queue 2 counter is %d.\n", port,
4015 output_queue);
developerfd40db22021-04-29 10:08:25 +08004016 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08004017 printf("\n port %d output queue 3 counter is %d.\n", port,
4018 output_queue);
developerfd40db22021-04-29 10:08:25 +08004019
developerbe40a9e2024-03-07 21:44:26 +08004020 reg_write(0x7038, base + (port * 4) + 2);
developerfd40db22021-04-29 10:08:25 +08004021 reg_read(0x7034, &value);
4022 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08004023 printf("\n port %d output queue 4 counter is %d.\n", port,
4024 output_queue);
developerfd40db22021-04-29 10:08:25 +08004025 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08004026 printf("\n port %d output queue 5 counter is %d.\n", port,
4027 output_queue);
developerfd40db22021-04-29 10:08:25 +08004028
developerbe40a9e2024-03-07 21:44:26 +08004029 reg_write(0x7038, base + (port * 4) + 3);
developerfd40db22021-04-29 10:08:25 +08004030 reg_read(0x7034, &value);
4031 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08004032 printf("\n port %d output queue 6 counter is %d.\n", port,
4033 output_queue);
developerfd40db22021-04-29 10:08:25 +08004034 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08004035 printf("\n port %d output queue 7 counter is %d.\n", port,
4036 output_queue);
developerfd40db22021-04-29 10:08:25 +08004037 }
4038}
4039
developerbe40a9e2024-03-07 21:44:26 +08004040void read_free_page_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08004041{
developerbe40a9e2024-03-07 21:44:26 +08004042 unsigned int value = 0;
4043 unsigned int free_page = 0, free_page_last_read = 0;
4044 unsigned int fc_free_blk_lothd = 0, fc_free_blk_hithd = 0;
4045 unsigned int fc_port_blk_thd = 0, fc_port_blk_hi_thd = 0;
4046 unsigned int queue[8] = { 0 };
developerfd40db22021-04-29 10:08:25 +08004047
developer8c3871b2022-07-01 14:07:53 +08004048 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerbe40a9e2024-03-07 21:44:26 +08004049 /* get system free page link counter */
developerfd40db22021-04-29 10:08:25 +08004050 reg_read(0x1fc0, &value);
4051 free_page = value & 0xFFF;
4052 free_page_last_read = (value & 0xFFF0000) >> 16;
4053
4054 /* get system flow control waterwark */
4055 reg_read(0x1fe0, &value);
4056 fc_free_blk_lothd = value & 0x3FF;
4057 fc_free_blk_hithd = (value & 0x3FF0000) >> 16;
4058
4059 /* get port flow control waterwark */
4060 reg_read(0x1fe4, &value);
4061 fc_port_blk_thd = value & 0x3FF;
4062 fc_port_blk_hi_thd = (value & 0x3FF0000) >> 16;
4063
4064 /* get queue flow control waterwark */
4065 reg_read(0x1fe8, &value);
developerbe40a9e2024-03-07 21:44:26 +08004066 queue[0] = value & 0x3F;
4067 queue[1] = (value & 0x3F00) >> 8;
4068 queue[2] = (value & 0x3F0000) >> 16;
4069 queue[3] = (value & 0x3F000000) >> 24;
developerfd40db22021-04-29 10:08:25 +08004070 reg_read(0x1fec, &value);
developerbe40a9e2024-03-07 21:44:26 +08004071 queue[4] = value & 0x3F;
4072 queue[5] = (value & 0x3F00) >> 8;
4073 queue[6] = (value & 0x3F0000) >> 16;
4074 queue[7] = (value & 0x3F000000) >> 24;
developerfd40db22021-04-29 10:08:25 +08004075 } else {
developerbe40a9e2024-03-07 21:44:26 +08004076 /* get system free page link counter */
developerfd40db22021-04-29 10:08:25 +08004077 reg_read(0x1fc0, &value);
4078 free_page = value & 0x3FF;
4079 free_page_last_read = (value & 0x3FF0000) >> 16;
4080
4081 /* get system flow control waterwark */
4082 reg_read(0x1fe0, &value);
4083 fc_free_blk_lothd = value & 0xFF;
4084 fc_free_blk_hithd = (value & 0xFF00) >> 8;
4085
4086 /* get port flow control waterwark */
4087 reg_read(0x1fe0, &value);
4088 fc_port_blk_thd = (value & 0xFF0000) >> 16;
4089 reg_read(0x1ff4, &value);
4090 fc_port_blk_hi_thd = (value & 0xFF00) >> 8;
4091
4092 /* get queue flow control waterwark */
4093 reg_read(0x1fe4, &value);
developerbe40a9e2024-03-07 21:44:26 +08004094 queue[0] = value & 0xF;
4095 queue[1] = (value & 0xF0) >> 4;
4096 queue[2] = (value & 0xF00) >> 8;
4097 queue[3] = (value & 0xF000) >> 12;
4098 queue[4] = (value & 0xF0000) >> 16;
4099 queue[5] = (value & 0xF00000) >> 20;
4100 queue[6] = (value & 0xF000000) >> 24;
4101 queue[7] = (value & 0xF0000000) >> 28;
developerfd40db22021-04-29 10:08:25 +08004102 }
4103
developerbe40a9e2024-03-07 21:44:26 +08004104 printf("<===Free Page=======Current=======Last Read access=====>\n");
4105 printf("\n");
4106 printf(" page counter %u %u\n ",
4107 free_page, free_page_last_read);
4108 printf("\n ");
4109 printf("=========================================================\n");
4110 printf("<===Type=======High threshold======Low threshold=========\n");
4111 printf("\n ");
4112 printf(" system: %u %u\n",
4113 fc_free_blk_hithd * 2, fc_free_blk_lothd * 2);
4114 printf(" port: %u %u\n",
4115 fc_port_blk_hi_thd * 2, fc_port_blk_thd * 2);
4116 printf(" queue 0: %u NA\n",
4117 queue[0]);
4118 printf(" queue 1: %u NA\n",
4119 queue[1]);
4120 printf(" queue 2: %u NA\n",
4121 queue[2]);
4122 printf(" queue 3: %u NA\n",
4123 queue[3]);
4124 printf(" queue 4: %u NA\n",
4125 queue[4]);
4126 printf(" queue 5: %u NA\n",
4127 queue[5]);
4128 printf(" queue 6: %u NA\n",
4129 queue[6]);
4130 printf(" queue 7: %u NA\n",
4131 queue[7]);
4132 printf("=========================================================\n");
developerfd40db22021-04-29 10:08:25 +08004133}
4134
4135void eee_enable(int argc, char *argv[])
4136{
developerbe40a9e2024-03-07 21:44:26 +08004137 unsigned long enable = 0;
4138 unsigned int value = 0;
4139 unsigned int eee_cap = 0;
developerfd40db22021-04-29 10:08:25 +08004140 unsigned int eee_en_bitmap = 0;
developerbe40a9e2024-03-07 21:44:26 +08004141 unsigned long port_map = 0;
developerfd40db22021-04-29 10:08:25 +08004142 long port_num = -1;
developerbe40a9e2024-03-07 21:44:26 +08004143 int p = 0;
developerfd40db22021-04-29 10:08:25 +08004144
4145 if (argc < 3)
4146 goto error;
4147
developerbe40a9e2024-03-07 21:44:26 +08004148 /* Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08004149 if (!strncmp(argv[2], "enable", 7))
4150 enable = 1;
4151 else if (!strncmp(argv[2], "disable", 8))
4152 enable = 0;
4153 else
4154 goto error;
4155
4156 if (argc > 3) {
4157 if (strlen(argv[3]) == 1) {
4158 port_num = strtol(argv[3], (char **)NULL, 10);
4159 if (port_num < 0 || port_num > MAX_PHY_PORT - 1) {
4160 printf("Illegal port index and port:0~4\n");
4161 goto error;
4162 }
4163 port_map = 1 << port_num;
4164 } else if (strlen(argv[3]) == 5) {
4165 port_map = 0;
4166 for (p = 0; p < MAX_PHY_PORT; p++) {
4167 if (argv[3][p] != '0' && argv[3][p] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08004168 printf
4169 ("portmap format error, should be combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08004170 goto error;
4171 }
4172 port_map |= ((argv[3][p] - '0') << p);
4173 }
4174 } else {
developerbe40a9e2024-03-07 21:44:26 +08004175 printf
4176 ("port_no or portmap format error, should be length of 1 or 5\n");
developerfd40db22021-04-29 10:08:25 +08004177 goto error;
4178 }
4179 } else {
4180 port_map = 0x1f;
4181 }
4182
developerbe40a9e2024-03-07 21:44:26 +08004183 eee_cap = (enable) ? 6 : 0;
developerfd40db22021-04-29 10:08:25 +08004184 for (p = 0; p < MAX_PHY_PORT; p++) {
4185 /* port_map describe p0p1p2p3p4 from left to rignt */
developerbe40a9e2024-03-07 21:44:26 +08004186 if (!!(port_map & (1 << p)))
developerfd40db22021-04-29 10:08:25 +08004187 mii_mgr_c45_write(p, 0x7, 0x3c, eee_cap);
4188
4189 mii_mgr_c45_read(p, 0x7, 0x3c, &value);
4190 /* mt7531: Always readback eee_cap = 0 when global EEE switch
4191 * is turned off.
4192 */
4193 if (value | eee_cap)
4194 eee_en_bitmap |= (1 << (MAX_PHY_PORT - 1 - p));
4195 }
4196
4197 /* Turn on/off global EEE switch */
developer8c3871b2022-07-01 14:07:53 +08004198 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08004199 mii_mgr_c45_read(0, 0x1f, 0x403, &value);
4200 if (eee_en_bitmap)
4201 value |= (1 << 6);
4202 else
4203 value &= ~(1 << 6);
4204 mii_mgr_c45_write(0, 0x1f, 0x403, value);
4205 } else {
4206 printf("\nCommand not support by this chip.\n");
4207 }
4208
developerbe40a9e2024-03-07 21:44:26 +08004209 printf("EEE(802.3az) %s", (enable) ? "enable" : "disable");
developerfd40db22021-04-29 10:08:25 +08004210 if (argc == 4) {
4211 if (port_num >= 0)
4212 printf(" port%ld", port_num);
4213 else
4214 printf(" port_map: %s", argv[3]);
4215 } else {
4216 printf(" all ports");
4217 }
4218 printf("\n");
4219
4220 return;
4221error:
4222 printf(HELP_EEE_EN);
4223 return;
4224}
4225
4226void eee_dump(int argc, char *argv[])
4227{
developerbe40a9e2024-03-07 21:44:26 +08004228 unsigned int cap = 0, lp_cap = 0;
developerfd40db22021-04-29 10:08:25 +08004229 long port = -1;
developerbe40a9e2024-03-07 21:44:26 +08004230 int p = 0;
developerfd40db22021-04-29 10:08:25 +08004231
4232 if (argc > 3) {
4233 if (strlen(argv[3]) > 1) {
4234 printf("port# format error, should be of length 1\n");
4235 return;
4236 }
4237
4238 port = strtol(argv[3], (char **)NULL, 0);
4239 if (port < 0 || port > MAX_PHY_PORT) {
4240 printf("port# format error, should be 0 to %d\n",
developerbe40a9e2024-03-07 21:44:26 +08004241 MAX_PHY_PORT);
developerfd40db22021-04-29 10:08:25 +08004242 return;
4243 }
4244 }
4245
4246 for (p = 0; p < MAX_PHY_PORT; p++) {
4247 if (port >= 0 && p != port)
4248 continue;
4249
4250 mii_mgr_c45_read(p, 0x7, 0x3c, &cap);
4251 mii_mgr_c45_read(p, 0x7, 0x3d, &lp_cap);
4252 printf("port%d EEE cap=0x%02x, link partner EEE cap=0x%02x",
4253 p, cap, lp_cap);
4254
4255 if (port >= 0 && p == port) {
4256 mii_mgr_c45_read(p, 0x3, 0x1, &cap);
4257 printf(", st=0x%03x", cap);
4258 }
4259 printf("\n");
4260 }
4261}
4262
4263void dump_each_port(unsigned int base)
4264{
4265 unsigned int pkt_cnt = 0;
4266 int i = 0;
4267
4268 for (i = 0; i < 7; i++) {
developer0dea3402022-10-14 13:41:11 +08004269 if (chip_name == 0x7988) {
4270 if ((base == 0x402C) && (i == 6))
4271 base = 0x408C;
4272 else if ((base == 0x408C) && (i == 6))
4273 base = 0x402C;
4274 else
4275 ;
4276 }
developerfd40db22021-04-29 10:08:25 +08004277 reg_read((base) + (i * 0x100), &pkt_cnt);
4278 printf("%8u ", pkt_cnt);
4279 }
4280 printf("\n");
4281}
4282
developerbe40a9e2024-03-07 21:44:26 +08004283void read_mib_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08004284{
4285 printf("===================== %8s %8s %8s %8s %8s %8s %8s\n",
4286 "Port0", "Port1", "Port2", "Port3", "Port4", "Port5", "Port6");
4287 printf("Tx Drop Packet :");
4288 dump_each_port(0x4000);
4289 printf("Tx CRC Error :");
4290 dump_each_port(0x4004);
4291 printf("Tx Unicast Packet :");
4292 dump_each_port(0x4008);
4293 printf("Tx Multicast Packet :");
4294 dump_each_port(0x400C);
4295 printf("Tx Broadcast Packet :");
4296 dump_each_port(0x4010);
4297 printf("Tx Collision Event :");
4298 dump_each_port(0x4014);
4299 printf("Tx Pause Packet :");
4300 dump_each_port(0x402C);
4301 printf("Rx Drop Packet :");
4302 dump_each_port(0x4060);
4303 printf("Rx Filtering Packet :");
4304 dump_each_port(0x4064);
4305 printf("Rx Unicast Packet :");
4306 dump_each_port(0x4068);
4307 printf("Rx Multicast Packet :");
4308 dump_each_port(0x406C);
4309 printf("Rx Broadcast Packet :");
4310 dump_each_port(0x4070);
4311 printf("Rx Alignment Error :");
4312 dump_each_port(0x4074);
4313 printf("Rx CRC Error :");
4314 dump_each_port(0x4078);
4315 printf("Rx Undersize Error :");
4316 dump_each_port(0x407C);
4317 printf("Rx Fragment Error :");
4318 dump_each_port(0x4080);
4319 printf("Rx Oversize Error :");
4320 dump_each_port(0x4084);
4321 printf("Rx Jabber Error :");
4322 dump_each_port(0x4088);
4323 printf("Rx Pause Packet :");
4324 dump_each_port(0x408C);
4325}
4326
developerbe40a9e2024-03-07 21:44:26 +08004327void clear_mib_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08004328{
4329 reg_write(0x4fe0, 0xf0);
developerbe40a9e2024-03-07 21:44:26 +08004330 read_mib_counters(argc, argv);
developerfd40db22021-04-29 10:08:25 +08004331 reg_write(0x4fe0, 0x800000f0);
4332}
4333
developerfd40db22021-04-29 10:08:25 +08004334void exit_free()
4335{
4336 free(attres);
4337 attres = NULL;
4338 switch_ioctl_fini();
4339 mt753x_netlink_free();
4340}