blob: ce9d2bb2c4e30ebd0b5c098c6932af97aee0a42e [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>
14
15#include "switch_extend.h"
16#include "switch_netlink.h"
17#include "switch_ioctl.h"
18#include "switch_fun.h"
19
20#define leaky_bucket 0
21
22static int getnext(char *src, int separator, char *dest)
23{
24 char *c;
25 int len;
26
27 if ((src == NULL) || (dest == NULL))
28 return -1;
29
30 c = strchr(src, separator);
31 if (c == NULL)
32 return -1;
33
34 len = c - src;
35 strncpy(dest, src, len);
36 dest[len] = '\0';
37 return len + 1;
38}
39
40static int str_to_ip(unsigned int *ip, char *str)
41{
42 int i;
43 int len;
44 char *ptr = str;
45 char buf[128];
46 unsigned char c[4];
47
48 for (i = 0; i < 3; ++i) {
49 if ((len = getnext(ptr, '.', buf)) == -1)
50 return 1;
51 c[i] = atoi(buf);
52 ptr += len;
53 }
54 c[3] = atoi(ptr);
55 *ip = (c[0] << 24) + (c[1] << 16) + (c[2] << 8) + c[3];
56 return 0;
57}
58
59/*convert IP address from number to string */
60static void ip_to_str(char *str, unsigned int ip)
61{
62 unsigned char *ptr = (unsigned char *)&ip;
63 unsigned char c[4];
64
65 c[0] = *(ptr);
66 c[1] = *(ptr + 1);
67 c[2] = *(ptr + 2);
68 c[3] = *(ptr + 3);
69 /*sprintf(str, "%d.%d.%d.%d", c[0], c[1], c[2], c[3]);*/
70 sprintf(str, "%d.%d.%d.%d", c[3], c[2], c[1], c[0]);
71}
72
73int reg_read(unsigned int offset, unsigned int *value)
74{
75 int ret = -1;
76
77 if (nl_init_flag == true) {
78 ret = reg_read_netlink(attres, offset, value);
79 } else {
80 if (attres->dev_id == -1)
81 ret = reg_read_ioctl(offset, value);
82 }
83 if (ret < 0) {
84 printf("Read fail\n");
85 *value = 0;
86 return ret;
87 }
88
89 return 0;
90}
91
92int reg_write(unsigned int offset, unsigned int value)
93{
94 int ret = -1;
95
96 if (nl_init_flag == true) {
97 ret = reg_write_netlink(attres, offset, value);
98 } else {
99 if (attres->dev_id == -1)
100 ret = reg_write_ioctl(offset, value);
101 }
102 if (ret < 0) {
103 printf("Write fail\n");
104 exit_free();
105 exit(0);
106 }
107 return 0;
108}
109
110int mii_mgr_read(unsigned int port_num, unsigned int reg, unsigned int *value)
111{
112 int ret;
113
114 if (port_num > 31) {
115 printf("Invalid Port or PHY addr \n");
116 return -1;
117 }
118
119 if (nl_init_flag == true)
120 ret = phy_cl22_read_netlink(attres, port_num, reg, value);
121 else
122 ret = mii_mgr_cl22_read_ioctl(port_num, reg, value);
123
124 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800125 printf("Phy cl22 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800126 exit_free();
127 exit(0);
128 }
129
130 return 0;
131}
132
133int mii_mgr_write(unsigned int port_num, unsigned int reg, unsigned int value)
134{
135 int ret;
136
137 if (port_num > 31) {
138 printf("Invalid Port or PHY addr \n");
139 return -1;
140 }
141
142 if (nl_init_flag == true)
143 ret = phy_cl22_write_netlink(attres, port_num, reg, value);
144 else
145 ret = mii_mgr_cl22_write_ioctl(port_num, reg, value);
146
147 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800148 printf("Phy cl22 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800149 exit_free();
150 exit(0);
151 }
152
153 return 0;
154}
155
156int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int *value)
157{
158 int ret;
159
160 if (port_num > 31) {
161 printf("Invalid Port or PHY addr \n");
162 return -1;
163 }
164
165 if (nl_init_flag == true)
166 ret = phy_cl45_read_netlink(attres, port_num, dev, reg, value);
167 else
168 ret = mii_mgr_cl45_read_ioctl(port_num, dev, reg, value);
169
170 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800171 printf("Phy cl45 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800172 exit_free();
173 exit(0);
174 }
175
176 return 0;
177}
178
179int mii_mgr_c45_write(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int value)
180{
181 int ret;
182
183 if (port_num > 31) {
184 printf("Invalid Port or PHY addr \n");
185 return -1;
186 }
187
188 if (nl_init_flag == true)
189 ret = phy_cl45_write_netlink(attres, port_num, dev, reg, value);
190 else
191 ret = mii_mgr_cl45_write_ioctl(port_num, dev, reg, value);
192
193 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800194 printf("Phy cl45 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800195 exit_free();
196 exit(0);
197 }
198
199 return 0;
200}
201
202
203int phy_dump(int phy_addr)
204{
205 int ret;
206
207 if (nl_init_flag == true)
208 ret = phy_dump_netlink(attres, phy_addr);
209 else
210 ret = phy_dump_ioctl(phy_addr);
211
212 if (ret < 0) {
213 printf("Phy dump fail\n");
214 exit_free();
215 exit(0);
216 }
217
218 return 0;
219}
220
221void phy_crossover(int argc, char *argv[])
222{
223 unsigned int port_num = strtoul(argv[2], NULL, 10);
224 unsigned int value;
225 int ret;
226
227 if (port_num > 4) {
228 printf("invaild value, port_name:0~4\n");
229 return;
230 }
231
232 if (nl_init_flag == true)
233 ret = phy_cl45_read_netlink(attres, port_num, 0x1E, MT7530_T10_TEST_CONTROL, &value);
234 else
235 ret = mii_mgr_cl45_read_ioctl(port_num, 0x1E, MT7530_T10_TEST_CONTROL, &value);
236 if (ret < 0) {
237 printf("phy_cl45 read fail\n");
238 exit_free();
239 exit(0);
240 }
241
242 printf("mii_mgr_cl45:");
243 printf("Read: port#=%d, device=0x%x, reg=0x%x, value=0x%x\n", port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
244
245 if (!strncmp(argv[3], "auto", 5))
246 {
247 value &= (~(0x3 << 3));
248 } else if (!strncmp(argv[3], "mdi", 4)) {
249 value &= (~(0x3 << 3));
250 value |= (0x2 << 3);
251 } else if (!strncmp(argv[3], "mdix", 5)) {
252 value |= (0x3 << 3);
253 } else {
254 printf("invaild parameter\n");
255 return;
256 }
257 printf("Write: port#=%d, device=0x%x, reg=0x%x. value=0x%x\n", port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
258
259 if (nl_init_flag == true)
260 ret = phy_cl45_write_netlink(attres, port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
261 else
262 ret = mii_mgr_cl45_write_ioctl(port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
263
264 if (ret < 0) {
265 printf("phy_cl45 write fail\n");
266 exit_free();
267 exit(0);
268 }
269}
270
271int rw_phy_token_ring(int argc, char *argv[])
272{
273 int ch_addr, node_addr, data_addr;
274 unsigned int tr_reg_control;
275 unsigned int val_l = 0;
276 unsigned int val_h = 0;
277 unsigned int port_num;
278
279 if (argc < 4)
280 return -1;
281
282 if (argv[2][0] == 'r') {
283 if (argc != 7)
284 return -1;
285 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
286 port_num = strtoul(argv[3], NULL, 0);
287 if (port_num > MAX_PORT) {
288 printf("Illegal port index and port:0~6\n");
289 return -1;
290 }
291 ch_addr = strtoul(argv[4], NULL, 0);
292 node_addr = strtoul(argv[5], NULL, 0);
293 data_addr = strtoul(argv[6], NULL, 0);
294 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n", port_num, ch_addr, node_addr, data_addr);
295 tr_reg_control = (1 << 15) | (1 << 13) | (ch_addr << 11) | (node_addr << 7) | (data_addr << 1);
296 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
297 mii_mgr_read(port_num, 17, &val_l);
298 mii_mgr_read(port_num, 18, &val_h);
299 printf("switch trreg read tr_reg_control=%x, value_H=%x, value_L=%x\n", tr_reg_control, val_h, val_l);
300 } else if (argv[2][0] == 'w') {
301 if (argc != 9)
302 return -1;
303 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
304 port_num = strtoul(argv[3], NULL, 0);
305 if (port_num > MAX_PORT) {
306 printf("\n**Illegal port index and port:0~6\n");
307 return -1;
308 }
309 ch_addr = strtoul(argv[4], NULL, 0);
310 node_addr = strtoul(argv[5], NULL, 0);
311 data_addr = strtoul(argv[6], NULL, 0);
312 val_h = strtoul(argv[7], NULL, 0);
313 val_l = strtoul(argv[8], NULL, 0);
314 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n", port_num, ch_addr, node_addr, data_addr);
315 tr_reg_control = (1 << 15) | (0 << 13) | (ch_addr << 11) | (node_addr << 7) | (data_addr << 1);
316 mii_mgr_write(port_num, 17, val_l);
317 mii_mgr_write(port_num, 18, val_h);
318 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
319 printf("switch trreg Write tr_reg_control=%x, value_H=%x, value_L=%x\n", tr_reg_control, val_h, val_l);
320 } else
321 return -1;
322 return 0;
323}
324
325void write_acl_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2)
326{
327 unsigned int value, reg;
328 unsigned int max_index;
329
developer8c3871b2022-07-01 14:07:53 +0800330 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800331 max_index = 256;
332 else
333 max_index = 64;
334
335 printf("Pattern_acl_tbl_idx:%d\n", tbl_idx);
336
337 if (tbl_idx >= max_index) {
338 printf(HELP_ACL_ACL_TBL_ADD);
339 return;
340 }
341
342 reg = REG_VTCR_ADDR;
343 while (1)
344 { // wait until not busy
345 reg_read(reg, &value);
346 if ((value & REG_VTCR_BUSY_MASK) == 0) {
347 break;
348 }
349 }
350 reg_write(REG_VAWD1_ADDR, vawd1);
351 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
352 reg_write(REG_VAWD2_ADDR, vawd2);
353 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
354 reg = REG_VTCR_ADDR;
355 value = REG_VTCR_BUSY_MASK | (0x05 << REG_VTCR_FUNC_OFFT) | tbl_idx;
356 reg_write(reg, value);
357 printf("write reg: %x, value: %x\n", reg, value);
358
359 while (1)
360 { // wait until not busy
361 reg_read(reg, &value);
362 if ((value & REG_VTCR_BUSY_MASK) == 0)
363 break;
364 }
365}
366
367void acl_table_add(int argc, char *argv[])
368{
369 unsigned int vawd1, vawd2;
370 unsigned char tbl_idx;
371
372 tbl_idx = atoi(argv[3]);
373 vawd1 = strtoul(argv[4], (char **)NULL, 16);
374 vawd2 = strtoul(argv[5], (char **)NULL, 16);
375 write_acl_table(tbl_idx, vawd1, vawd2);
376}
377
378void write_acl_mask_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2)
379{
380 unsigned int value, reg;
381 unsigned int max_index;
382
developer8c3871b2022-07-01 14:07:53 +0800383 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800384 max_index = 128;
385 else
386 max_index = 32;
387
388 printf("Rule_mask_tbl_idx:%d\n", tbl_idx);
389
390 if (tbl_idx >= max_index) {
391 printf(HELP_ACL_MASK_TBL_ADD);
392 return;
393 }
394 reg = REG_VTCR_ADDR;
395 while (1)
396 { // wait until not busy
397 reg_read(reg, &value);
398 if ((value & REG_VTCR_BUSY_MASK) == 0)
399 break;
400 }
401 reg_write(REG_VAWD1_ADDR, vawd1);
402 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
403 reg_write(REG_VAWD2_ADDR, vawd2);
404 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
405 reg = REG_VTCR_ADDR;
406 value = REG_VTCR_BUSY_MASK | (0x09 << REG_VTCR_FUNC_OFFT) | tbl_idx;
407 reg_write(reg, value);
408 printf("write reg: %x, value: %x\n", reg, value);
409 while (1)
410 { // wait until not busy
411 reg_read(reg, &value);
412 if ((value & REG_VTCR_BUSY_MASK) == 0)
413 break;
414 }
415}
416
417void acl_mask_table_add(int argc, char *argv[])
418{
419 unsigned int vawd1, vawd2;
420 unsigned char tbl_idx;
421
422 tbl_idx = atoi(argv[3]);
423 vawd1 = strtoul(argv[4], (char **)NULL, 16);
424 vawd2 = strtoul(argv[5], (char **)NULL, 16);
425 write_acl_mask_table(tbl_idx, vawd1, vawd2);
426}
427
428void write_acl_rule_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2)
429{
430 unsigned int value, reg;
431 unsigned int max_index;
432
developer8c3871b2022-07-01 14:07:53 +0800433 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800434 max_index = 128;
435 else
436 max_index = 32;
437
438 printf("Rule_control_tbl_idx:%d\n", tbl_idx);
439
440 if (tbl_idx >= max_index) { /*Check the input parameters is right or not.*/
441 printf(HELP_ACL_RULE_TBL_ADD);
442 return;
443 }
444 reg = REG_VTCR_ADDR;
445
446 while (1)
447 { // wait until not busy
448 reg_read(reg, &value);
449 if ((value & REG_VTCR_BUSY_MASK) == 0) {
450 break;
451 }
452 }
453 reg_write(REG_VAWD1_ADDR, vawd1);
454 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
455 reg_write(REG_VAWD2_ADDR, vawd2);
456 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
457 reg = REG_VTCR_ADDR;
458 value = REG_VTCR_BUSY_MASK | (0x0B << REG_VTCR_FUNC_OFFT) | tbl_idx;
459 reg_write(reg, value);
460 printf("write reg: %x, value: %x\n", reg, value);
461
462 while (1)
463 { // wait until not busy
464 reg_read(reg, &value);
465 if ((value & REG_VTCR_BUSY_MASK) == 0) {
466 break;
467 }
468 }
469}
470
471void acl_rule_table_add(int argc, char *argv[])
472{
473 unsigned int vawd1, vawd2;
474 unsigned char tbl_idx;
475
476 tbl_idx = atoi(argv[3]);
477 vawd1 = strtoul(argv[4], (char **)NULL, 16);
478 vawd2 = strtoul(argv[5], (char **)NULL, 16);
479 write_acl_rule_table(tbl_idx, vawd1, vawd2);
480}
481
482void write_rate_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2)
483{
484 unsigned int value, reg;
485 unsigned int max_index = 32;
486
487 printf("Rule_action_tbl_idx:%d\n", tbl_idx);
488
489 if (tbl_idx >= max_index) {
490 printf(HELP_ACL_RATE_TBL_ADD);
491 return;
492 }
493
494 reg = REG_VTCR_ADDR;
495 while (1) { // wait until not busy
496 reg_read(reg, &value);
497 if ((value & REG_VTCR_BUSY_MASK) == 0)
498 break;
499 }
500
501 reg_write(REG_VAWD1_ADDR, vawd1);
502 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
503 reg_write(REG_VAWD2_ADDR, vawd2);
504 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
505 reg = REG_VTCR_ADDR;
506 value = REG_VTCR_BUSY_MASK | (0x0D << REG_VTCR_FUNC_OFFT) | tbl_idx;
507 reg_write(reg, value);
508 printf("write reg: %x, value: %x\n", reg, value);
509
510 while (1) { // wait until not busy
511 reg_read(reg, &value);
512 if ((value & REG_VTCR_BUSY_MASK) == 0)
513 break;
514 }
515}
516
517void acl_rate_table_add(int argc, char *argv[])
518{
519 unsigned int vawd1, vawd2;
520 unsigned char tbl_idx;
521
522 tbl_idx = atoi(argv[3]);
523 vawd1 = strtoul(argv[4], (char **)NULL, 16);
524 vawd2 = strtoul(argv[5], (char **)NULL, 16);
525
526 write_rate_table(tbl_idx, vawd1, vawd2);
527}
528
529void write_trTCM_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2)
530{
531 unsigned int value, reg;
532 unsigned int max_index = 32;
533
534 printf("trTCM_tbl_idx:%d\n", tbl_idx);
535
536 if (tbl_idx >= max_index) {
537 printf(HELP_ACL_TRTCM_TBL_ADD);
538 return;
539 }
540
541 reg = REG_VTCR_ADDR;
542 while (1) { // wait until not busy
543 reg_read(reg, &value);
544 if ((value & REG_VTCR_BUSY_MASK) == 0)
545 break;
546 }
547
548 reg_write(REG_VAWD1_ADDR, vawd1);
549 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
550 reg_write(REG_VAWD2_ADDR, vawd2);
551 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
552 reg = REG_VTCR_ADDR;
553 value = REG_VTCR_BUSY_MASK | (0x07 << REG_VTCR_FUNC_OFFT) | tbl_idx;
554 reg_write(reg, value);
555 printf("write reg: %x, value: %x\n", reg, value);
556
557 while (1) { // wait until not busy
558 reg_read(reg, &value);
559 if ((value & REG_VTCR_BUSY_MASK) == 0)
560 break;
561 }
562}
563
564int acl_parameters_pre_del(int len1, int len2, int argc, char *argv[], int *port)
565{
566 int i;
567
568 *port = 0;
569 if (argc < len1) {
570 printf("insufficient arguments!\n");
571 return -1;
572 }
573
574 if (len2 == 12)
575 {
576 if (!argv[4] || strlen(argv[4]) != len2) {
577 printf("The [%s] format error, should be of length %d\n",argv[4], len2);
578 return -1;
579 }
580 }
581
582 if (!argv[5] || strlen(argv[5]) != 8) {
583 printf("portsmap format error, should be of length 7\n");
584 return -1;
585 }
586
587 for (i = 0; i < 7; i++) {
588 if (argv[5][i] != '0' && argv[5][i] != '1') {
589 printf("portmap format error, should be of combination of 0 or 1\n");
590 return -1;
591 }
592 *port += (argv[5][i] - '0') * (1 << i);
593 }
594 return 0;
595}
596
597void acl_compare_pattern(int ports, int comparion, int base, int word, unsigned char table_index)
598{
599 unsigned int value;
600
601 comparion |= 0xffff0000; //compare mask
602
603 value = ports << 8; //w_port_map
604 value |= 0x1 << 19; //enable
605 value |= base << 16; //mac header
606 value |= word << 1; //word offset
607
608 write_acl_table(table_index, comparion, value);
609}
610
611void acl_mac_add(int argc, char *argv[])
612{
613 unsigned int value;
614 int ports;
615 char tmpstr[5];
616 int ret;
617
618 ret = acl_parameters_pre_del(6, 12, argc, argv, &ports);
619 if (ret < 0)
620 return;
621 //set pattern
622 strncpy(tmpstr, argv[4], 4);
623 tmpstr[4] = '\0';
624 value = strtoul(tmpstr, NULL, 16);
625 acl_compare_pattern(ports, value, 0x0, 0, 0);
626
627 strncpy(tmpstr, argv[4] + 4, 4);
628 tmpstr[4] = '\0';
629 value = strtoul(tmpstr, NULL, 16);
630 acl_compare_pattern(ports, value, 0x0, 1, 1);
631
632 strncpy(tmpstr, argv[4] + 8, 4);
633 tmpstr[4] = '\0';
634 value = strtoul(tmpstr, NULL, 16);
635 acl_compare_pattern(ports, value, 0x0, 2, 2);
636
637 //set mask
638 write_acl_mask_table(0,0x7,0);
639
640 //set action
641 value = 0x7; //drop
642 value |= 1 << 28; //acl intterupt enable
643 value |= 1 << 27; //acl hit count
644 value |= 2 << 24; //acl hit count group index (0~3)
645 write_acl_rule_table(0,value,0);
646}
647
648void acl_dip_meter(int argc, char *argv[])
649{
650 unsigned int value, ip_value, meter;
651 int ports;
652 int ret;
653
654 ip_value = 0;
655 ret = acl_parameters_pre_del(7, -1, argc, argv, &ports);
656 if (ret < 0)
657 return;
658
659 str_to_ip(&ip_value, argv[4]);
660 //set pattern
661 value = (ip_value >> 16);
662 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
663
664 //set pattern
665 value = (ip_value & 0xffff);
666 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
667
668 //set mask
669 write_acl_mask_table(0,0x3,0);
670
671 //set action
672 meter = strtoul(argv[6], NULL, 0);
673 if (((chip_name == 0x7530) && (meter > 1000000)) ||
developer8c3871b2022-07-01 14:07:53 +0800674 ((chip_name == 0x7531) && (meter > 2500000)) ||
675 ((chip_name == 0x7988) && (meter > 4000000))) {
676 printf("\n**Illegal meter input, and 7530: 0~1000000Kpbs, 7531: 0~2500000Kpbs, 7988: 0~4000000Kpbs**\n");
developerfd40db22021-04-29 10:08:25 +0800677 return;
678 }
developer8c3871b2022-07-01 14:07:53 +0800679 if (((chip_name == 0x7531 || chip_name == 0x7988) && (meter > 1000000))) {
developerfd40db22021-04-29 10:08:25 +0800680 reg_read(0xc,&value);
681 value |= 0x1 << 30;
682 reg_write(0xC,value);
683 printf("AGC: 0x%x\n",value);
684 value = meter / 1000; //uint is 1Mbps
685 } else {
686 reg_read(0xc,&value);
687 value &= ~(0x1 << 30);
688 reg_write(0xC,value);
689 printf("AGC: 0x%x\n",value);
690 value = meter >> 6; //uint is 64Kbps
691 }
692 value |= 0x1 << 15; //enable rate control
693 printf("Acl rate control:0x%x\n",value);
694 write_rate_table(0, value, 0);
695}
696
697void acl_dip_trtcm(int argc, char *argv[])
698{
699 unsigned int value, value2, ip_value;
700 unsigned int CIR, CBS, PIR, PBS;
701 int ports;
702 int ret;
703
704 ip_value = 0;
705 ret = acl_parameters_pre_del(10, -1, argc, argv, &ports);
706 if (ret < 0)
707 return;
708
709 str_to_ip(&ip_value, argv[4]);
710 //set pattern
711 value = (ip_value >> 16);
712 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
713
714 //set pattern
715 value = (ip_value & 0xffff);
716 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
717
718 //set CBS PBS
719 CIR = strtoul(argv[6], NULL, 0);
720 CBS = strtoul(argv[7], NULL, 0);
721 PIR = strtoul(argv[8], NULL, 0);
722 PBS = strtoul(argv[9], NULL, 0);
723
724 if (CIR > 65535*64 || CBS > 65535 || PIR > 65535*64 || PBS > 65535) {
725 printf("\n**Illegal input parameters**\n");
726 return;
727 }
728
729 value = CBS << 16; //bit16~31
730 value |= PBS; //bit0~15
731 //value |= 1;//valid
732 CIR = CIR >> 6;
733 PIR = PIR >> 6;
734
735 value2 = CIR << 16; //bit16~31
736 value2 |= PIR; //bit0~15
737 write_trTCM_table(0,value,value2);
738
739 //set pattern
740 write_acl_mask_table(0,0x3,0);
741
742 //set action
743 value = 0x1 << (11 + 1); //TrTCM green meter#0 Low drop
744 value |= 0x2 << (8 + 1); //TrTCM yellow meter#0 Med drop
745 value |= 0x3 << (5 + 1); //TrTCM red meter#0 Hig drop
746 value |= 0x1 << 0; //TrTCM drop pcd select
747 write_acl_rule_table(0,0,value);
748}
749
750void acl_ethertype(int argc, char *argv[])
751{
752 unsigned int value, ethertype;
753 int ports;
754 int ret;
755
756 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
757 if (ret < 0)
758 return;
759 printf("ports:0x%x\n",ports);
760 ethertype = strtoul(argv[4], NULL, 16);
761 //set pattern
762 value = ethertype;
763 acl_compare_pattern(ports, value, 0x0, 0x6, 0);
764
765 //set pattern
766 write_acl_mask_table(0,0x1,0);
767
768 //set action(drop)
769 value = 0x7; //default. Nodrop
770 value |= 1 << 28; //acl intterupt enable
771 value |= 1 << 27; //acl hit count
772
773 write_acl_rule_table(0,value,0);
774}
775
776void acl_dip_modify(int argc, char *argv[])
777{
778 unsigned int value, ip_value;
779 int ports;
780 int priority;
781 int ret;
782
783 ip_value = 0;
784 priority = strtoul(argv[6], NULL, 16);
785 if (priority < 0 || priority > 7) {
786 printf("\n**Illegal priority value!**\n");
787 return;
788 }
789
790 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
791 if (ret < 0)
792 return;
793
794 str_to_ip(&ip_value, argv[4]);
795 //set pattern
796 value = (ip_value >> 16);
797 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
798
799 //set pattern
800 value = (ip_value & 0xffff);
801 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
802
803 //set pattern
804 write_acl_mask_table(0,0x3,0);
805
806 //set action
807 value = 0x0; //default. Nodrop
808 value |= 1 << 28; //acl intterupt enable
809 value |= 1 << 27; //acl hit count
810 value |= priority << 4; //acl UP
811 write_acl_rule_table(0,value,0);
812}
813
814void acl_dip_pppoe(int argc, char *argv[])
815{
816 unsigned int value, ip_value;
817 int ports;
818 int ret;
819
820 ip_value = 0;
821 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
822 if (ret < 0)
823 return;
824
825 str_to_ip(&ip_value, argv[4]);
826 //set pattern
827 value = (ip_value >> 16);
828 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
829
830 //set pattern
831 value = (ip_value & 0xffff);
832 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
833
834 //set pattern
835 write_acl_mask_table(0,0x3,0);
836
837 //set action
838 value = 0x0; //default. Nodrop
839 value |= 1 << 28; //acl intterupt enable
840 value |= 1 << 27; //acl hit count
841 value |= 1 << 20; //pppoe header remove
842 value |= 1 << 21; //SA MAC SWAP
843 value |= 1 << 22; //DA MAC SWAP
844 write_acl_rule_table(0,value,7);
845}
846
847void acl_dip_add(int argc, char *argv[])
848{
849 unsigned int value, ip_value;
850 int ports;
851 int ret;
852
853 ip_value = 0;
854 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
855 if (ret < 0)
856 return;
857
858 str_to_ip(&ip_value, argv[4]);
859 //set pattern
860 value = (ip_value >> 16);
861 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
862
863 //set pattern
864 value = (ip_value & 0xffff);
865 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
866
867 //set pattern
868 write_acl_mask_table(0,0x3,0);
869
870 //set action
871 //value = 0x0; //default
872 value = 0x7; //drop
873 value |= 1 << 28; //acl intterupt enable
874 value |= 1 << 27; //acl hit count
875 value |= 2 << 24; //acl hit count group index (0~3)
876 write_acl_rule_table(0,value,0);
877}
878
879void acl_l4_add(int argc, char *argv[])
880{
881 unsigned int value;
882 int ports;
883 int ret;
884
885 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
886 if (ret < 0)
887 return;
888
889 //set pattern
890 value = strtoul(argv[4], NULL, 16);
891 acl_compare_pattern(ports, value, 0x5, 0x0, 0);
892
893 //set rue mask
894 write_acl_mask_table(0,0x1,0);
895 //set action
896 value = 0x7; //drop
897 //value |= 1;//valid
898 write_acl_rule_table(0,value,0);
899}
900
901void acl_sp_add(int argc, char *argv[])
902{
903 unsigned int value;
904 int ports;
905 int ret;
906
907 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
908 if (ret < 0)
909 return;
910 //set pattern
911 value = strtoul(argv[4], NULL, 0);
912 acl_compare_pattern(ports, value, 0x4, 0x0, 0);
913
914 //set rue mask
915 write_acl_mask_table(0,0x1,0);
916
917 //set action
918 value = 0x7; //drop
919 //value |= 1;//valid
920 write_acl_rule_table(0,value,0);
921}
922
923void acl_port_enable(int argc, char *argv[])
924{
925 unsigned int value, reg;
926 unsigned char acl_port, acl_en;
927
928 acl_port = atoi(argv[3]);
929 acl_en = atoi(argv[4]);
930
931 printf("acl_port:%d, acl_en:%d\n", acl_port, acl_en);
932
933 /*Check the input parameters is right or not.*/
934 if ((acl_port > SWITCH_MAX_PORT) || (acl_en > 1)) {
935 printf(HELP_ACL_SETPORTEN);
936 return;
937 }
938
939 reg = REG_PCR_P0_ADDR + (0x100 * acl_port); // 0x2004[10]
940 reg_read(reg, &value);
941 value &= (~REG_PORT_ACL_EN_MASK);
942 value |= (acl_en << REG_PORT_ACL_EN_OFFT);
943
944 printf("write reg: %x, value: %x\n", reg, value);
945 reg_write(reg, value);
946}
947
948static void dip_dump_internal(int type)
949{
950 unsigned int i, j, value, mac, mac2, value2;
951 char tmpstr[16];
952 int table_size = 0;
953 int hit_value1 = 0;
954 int hit_value2 = 0;
955
956 if(type == GENERAL_TABLE) {
957 table_size = 0x800;
958 reg_write(REG_ATC_ADDR, 0x8104); //dip search command
959 } else {
960 table_size = 0x40;
961 reg_write(REG_ATC_ADDR, 0x811c); //dip search command
962 }
963 printf("hash port(0:6) rsp_cnt flag timer dip-address ATRD\n");
964 for (i = 0; i < table_size; i++) {
965 while (1)
966 {
967 reg_read(REG_ATC_ADDR, &value);
968 if(type == GENERAL_TABLE) {
969 hit_value1 = value & (0x1 << 13);
970 hit_value2 = 1;
971 }else {
972 hit_value1 = value & (0x1 << 13);
973 hit_value2 = value & (0x1 << 28);
974 }
975
976 if (hit_value1 && hit_value2 ) { //search_rdy
977 reg_read(REG_ATRD_ADDR, &value2);
978 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
979
980 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
981 j = (value2 >> 4) & 0xff; //r_port_map
982 printf("%c", (j & 0x01) ? '1' : '-');
983 printf("%c", (j & 0x02) ? '1' : '-');
984 printf("%c", (j & 0x04) ? '1' : '-');
985 printf("%c ", (j & 0x08) ? '1' : '-');
986 printf("%c", (j & 0x10) ? '1' : '-');
987 printf("%c", (j & 0x20) ? '1' : '-');
988 printf("%c", (j & 0x40) ? '1' : '-');
989
990 reg_read(REG_TSRA2_ADDR, &mac2);
991
992 printf(" 0x%4x", (mac2 & 0xffff)); //RESP_CNT
993 printf(" 0x%2x", ((mac2 >> 16) & 0xff)); //RESP_FLAG
994 printf(" %3d", ((mac2 >> 24) & 0xff)); //RESP_TIMER
995 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
996 reg_read(REG_TSRA1_ADDR, &mac);
997 ip_to_str(tmpstr, mac);
998 printf(" %s", tmpstr);
999 printf(" 0x%8x\n", value2); //ATRD
1000 //printf("%04x", ((mac2 >> 16) & 0xffff));
1001 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
1002 if (value & 0x4000) {
1003 printf("end of table %d\n", i);
1004 return;
1005 }
1006 break;
1007 }
1008 else if (value & 0x4000) { //at_table_end
1009 printf("found the last entry %d (not ready)\n", i);
1010 return;
1011 }
1012 usleep(5000);
1013 }
1014
1015 if(type == GENERAL_TABLE)
1016 reg_write(REG_ATC_ADDR, 0x8105); //search for next dip address
1017 else
1018 reg_write(REG_ATC_ADDR, 0x811d); //search for next dip address
1019 usleep(5000);
1020 }
1021}
1022
1023void dip_dump(void)
1024{
1025 dip_dump_internal(GENERAL_TABLE);
1026
1027}
1028
1029void dip_add(int argc, char *argv[])
1030{
1031 unsigned int value = 0;
1032 unsigned int i, j;
1033
1034 value = 0;
1035
1036 str_to_ip(&value, argv[3]);
1037
1038 reg_write(REG_ATA1_ADDR, value);
1039 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1040
1041#if 0
1042 reg_write(REG_ATA2_ADDR, value);
1043 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1044#endif
1045 if (!argv[4] || strlen(argv[4]) != 8) {
1046 printf("portmap format error, should be of length 7\n");
1047 return;
1048 }
1049 j = 0;
1050 for (i = 0; i < 7; i++) {
1051 if (argv[4][i] != '0' && argv[4][i] != '1') {
1052 printf("portmap format error, should be of combination of 0 or 1\n");
1053 return;
1054 }
1055 j += (argv[4][i] - '0') * (1 << i);
1056 }
1057 value = j << 4; //w_port_map
1058 value |= (0x3 << 2); //static
1059
1060 reg_write(REG_ATWD_ADDR, value);
1061
1062 usleep(5000);
1063 reg_read(REG_ATWD_ADDR, &value);
1064 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1065
1066 value = 0x8011; //single w_dip_cmd
1067 reg_write(REG_ATC_ADDR, value);
1068
1069 usleep(1000);
1070
1071 for (i = 0; i < 20; i++) {
1072 reg_read(REG_ATC_ADDR, &value);
1073 if ((value & 0x8000) == 0) { //mac address busy
1074 printf("done.\n");
1075 return;
1076 }
1077 usleep(1000);
1078 }
1079 if (i == 20)
1080 printf("timeout.\n");
1081}
1082
1083void dip_del(int argc, char *argv[])
1084{
1085 unsigned int i, value;
1086
1087 value = 0;
1088 str_to_ip(&value, argv[3]);
1089
1090 reg_write(REG_ATA1_ADDR, value);
1091
1092 value = 0;
1093 reg_write(REG_ATA2_ADDR, value);
1094
1095 value = 0; //STATUS=0, delete dip
1096 reg_write(REG_ATWD_ADDR, value);
1097
1098 value = 0x8011; //w_dip_cmd
1099 reg_write(REG_ATC_ADDR, value);
1100
1101 for (i = 0; i < 20; i++) {
1102 reg_read(REG_ATC_ADDR, &value);
1103 if ((value & 0x8000) == 0) { //mac address busy
1104 if (argv[1] != NULL)
1105 printf("done.\n");
1106 return;
1107 }
1108 usleep(1000);
1109 }
1110 if (i == 20)
1111 printf("timeout.\n");
1112}
1113
1114void dip_clear(void)
1115{
1116
1117 unsigned int value;
1118
1119 reg_write(REG_ATC_ADDR, 0x8102); //clear all dip
1120 usleep(5000);
1121 reg_read(REG_ATC_ADDR, &value);
1122 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1123}
1124
1125static void sip_dump_internal(int type)
1126{
1127 unsigned int i, j, value, mac, mac2, value2;
1128 int table_size = 0;
1129 int hit_value1 = 0;
1130 int hit_value2 = 0;
1131 char tmpstr[16];
1132
1133 if (type == GENERAL_TABLE) {
1134 table_size = 0x800;
1135 reg_write(REG_ATC_ADDR, 0x8204); //sip search command
1136 }else {
1137 table_size = 0x40;
1138 reg_write(REG_ATC_ADDR, 0x822c); //sip search command
1139 }
1140 printf("hash port(0:6) dip-address sip-address ATRD\n");
1141 for (i = 0; i < table_size; i++) {
1142 while (1)
1143 {
1144 reg_read(REG_ATC_ADDR, &value);
1145 if(type == GENERAL_TABLE) {
1146 hit_value1 = value & (0x1 << 13);
1147 hit_value2 = 1;
1148 } else {
1149 hit_value1 = value & (0x1 << 13);
1150 hit_value2 = value & (0x1 << 28);
1151 }
1152
1153 if (hit_value1 && hit_value2) { //search_rdy
1154 reg_read(REG_ATRD_ADDR, &value2);
1155 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1156
1157 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1158 j = (value2 >> 4) & 0xff; //r_port_map
1159 printf("%c", (j & 0x01) ? '1' : '-');
1160 printf("%c", (j & 0x02) ? '1' : '-');
1161 printf("%c", (j & 0x04) ? '1' : '-');
1162 printf("%c", (j & 0x08) ? '1' : '-');
1163 printf(" %c", (j & 0x10) ? '1' : '-');
1164 printf("%c", (j & 0x20) ? '1' : '-');
1165 printf("%c", (j & 0x40) ? '1' : '-');
1166
1167 reg_read(REG_TSRA2_ADDR, &mac2);
1168
1169 ip_to_str(tmpstr, mac2);
1170 printf(" %s", tmpstr);
1171
1172 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
1173 reg_read(REG_TSRA1_ADDR, &mac);
1174 ip_to_str(tmpstr, mac);
1175 printf(" %s", tmpstr);
1176 printf(" 0x%x\n", value2);
1177 //printf("%04x", ((mac2 >> 16) & 0xffff));
1178 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
1179 if (value & 0x4000) {
1180 printf("end of table %d\n", i);
1181 return;
1182 }
1183 break;
1184 } else if (value & 0x4000) { //at_table_end
1185 printf("found the last entry %d (not ready)\n", i);
1186 return;
1187 }
1188 usleep(5000);
1189 }
1190
1191 if(type == GENERAL_TABLE)
1192 reg_write(REG_ATC_ADDR, 0x8205); //search for next sip address
1193 else
1194 reg_write(REG_ATC_ADDR, 0x822d); //search for next sip address
1195 usleep(5000);
1196 }
1197}
1198
1199void sip_dump(void)
1200{
1201
1202 sip_dump_internal(GENERAL_TABLE);
1203
1204}
1205
1206
1207void sip_add(int argc, char *argv[])
1208{
1209 unsigned int i, j, value;
1210
1211 value = 0;
1212 str_to_ip(&value, argv[3]); //SIP
1213
1214 reg_write(REG_ATA2_ADDR, value);
1215 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1216
1217 value = 0;
1218
1219 str_to_ip(&value, argv[4]); //DIP
1220 reg_write(REG_ATA1_ADDR, value);
1221 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1222
1223 if (!argv[5] || strlen(argv[5]) != 8) {
1224 printf("portmap format error, should be of length 7\n");
1225 return;
1226 }
1227 j = 0;
1228 for (i = 0; i < 7; i++) {
1229 if (argv[5][i] != '0' && argv[5][i] != '1') {
1230 printf("portmap format error, should be of combination of 0 or 1\n");
1231 return;
1232 }
1233 j += (argv[5][i] - '0') * (1 << i);
1234 }
1235 value = j << 4; //w_port_map
1236 value |= (0x3 << 2); //static
1237
1238 reg_write(REG_ATWD_ADDR, value);
1239
1240 usleep(5000);
1241 reg_read(REG_ATWD_ADDR, &value);
1242 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1243
1244 value = 0x8021; //single w_sip_cmd
1245 reg_write(REG_ATC_ADDR, value);
1246
1247 usleep(1000);
1248
1249 for (i = 0; i < 20; i++) {
1250 reg_read(REG_ATC_ADDR, &value);
1251 if ((value & 0x8000) == 0) { //mac address busy
1252 printf("done.\n");
1253 return;
1254 }
1255 usleep(1000);
1256 }
1257 if (i == 20)
1258 printf("timeout.\n");
1259}
1260
1261void sip_del(int argc, char *argv[])
1262{
1263 unsigned int i, value;
1264
1265 value = 0;
1266 str_to_ip(&value, argv[3]);
1267
1268 reg_write(REG_ATA2_ADDR, value); //SIP
1269
1270 str_to_ip(&value, argv[4]);
1271 reg_write(REG_ATA1_ADDR, value); //DIP
1272
1273 value = 0; //STATUS=0, delete sip
1274 reg_write(REG_ATWD_ADDR, value);
1275
1276 value = 0x8021; //w_sip_cmd
1277 reg_write(REG_ATC_ADDR, value);
1278
1279 for (i = 0; i < 20; i++) {
1280 reg_read(REG_ATC_ADDR, &value);
1281 if ((value & 0x8000) == 0) { //mac address busy
1282 if (argv[1] != NULL)
1283 printf("done.\n");
1284 return;
1285 }
1286 usleep(1000);
1287 }
1288 if (i == 20)
1289 printf("timeout.\n");
1290}
1291
1292void sip_clear(void)
1293{
1294 unsigned int value;
1295
1296 reg_write(REG_ATC_ADDR, 0x8202); //clear all sip
1297 usleep(5000);
1298 reg_read(REG_ATC_ADDR, &value);
1299 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1300}
1301
1302static void table_dump_internal(int type)
1303{
1304 unsigned int i, j, value, mac, mac2, value2;
1305 int table_size = 0;
1306 int table_end = 0;
1307 int hit_value1 = 0;
1308 int hit_value2 = 0;
1309
1310 if (type == GENERAL_TABLE){
1311 table_size = 0x800;
1312 table_end = 0x7FF;
1313 reg_write(REG_ATC_ADDR, 0x8004);
1314 } else {
1315 table_size = 0x40;
1316 table_end = 0x3F;
1317 reg_write(REG_ATC_ADDR, 0x800C);
1318 }
1319 printf("hash port(0:6) fid vid age(s) mac-address filter my_mac\n");
1320 for (i = 0; i < table_size; i++) {
1321 while (1)
1322 {
1323 reg_read(REG_ATC_ADDR, &value);
1324 //printf("ATC = 0x%x\n", value);
1325 if(type == GENERAL_TABLE) {
1326 hit_value1 = value & (0x1 << 13);
1327 hit_value2 = 1;
1328 } else {
1329 hit_value1 = value & (0x1 << 13);
1330 hit_value2 = value & (0x1 << 28);
1331 }
1332
1333 if (hit_value1 && hit_value2 && (((value >> 15) & 0x1) == 0)) {
1334 printf("%03x: ", (value >> 16) & 0xfff);
1335 reg_read(REG_ATRD_ADDR, &value2);
1336 j = (value2 >> 4) & 0xff; //r_port_map
1337 printf("%c", (j & 0x01) ? '1' : '-');
1338 printf("%c", (j & 0x02) ? '1' : '-');
1339 printf("%c", (j & 0x04) ? '1' : '-');
1340 printf("%c", (j & 0x08) ? '1' : '-');
1341 printf("%c", (j & 0x10) ? '1' : '-');
1342 printf("%c", (j & 0x20) ? '1' : '-');
1343 printf("%c", (j & 0x40) ? '1' : '-');
1344 printf("%c", (j & 0x80) ? '1' : '-');
1345
1346 reg_read(REG_TSRA2_ADDR, &mac2);
1347
1348 printf(" %2d", (mac2 >> 12) & 0x7); //FID
1349 printf(" %4d", (mac2 & 0xfff));
1350 if (((value2 >> 24) & 0xff) == 0xFF)
1351 printf(" --- "); //r_age_field:static
1352 else
1353 printf(" %5d ", (((value2 >> 24) & 0xff)+1)*2); //r_age_field
1354 reg_read(REG_TSRA1_ADDR, &mac);
1355 printf(" %08x", mac);
1356 printf("%04x", ((mac2 >> 16) & 0xffff));
1357 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1358 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1359 if ((value & 0x4000) && (((value >> 16) & 0xfff) == table_end)) {
1360 printf("end of table %d\n", i);
1361 return;
1362 }
1363 break;
1364 }
1365 else if ((value & 0x4000) && (((value >> 15) & 0x1) == 0) && (((value >> 16) & 0xfff) == table_end)) { //at_table_end
1366 printf("found the last entry %d (not ready)\n", i);
1367 return;
1368 }
1369 else
1370 usleep(5);
1371 }
1372
1373 if(type == GENERAL_TABLE)
1374 reg_write(REG_ATC_ADDR, 0x8005);//search for next address
1375 else
1376 reg_write(REG_ATC_ADDR, 0x800d);//search for next address
1377 usleep(5);
1378 }
1379}
1380
1381void table_dump(void)
1382{
1383 table_dump_internal(GENERAL_TABLE);
1384
1385}
1386
1387
1388void table_add(int argc, char *argv[])
1389{
1390 unsigned int i, j, value, is_filter, is_mymac;
1391 char tmpstr[9];
1392
1393 is_filter = (argv[1][0] == 'f') ? 1 : 0;
1394 is_mymac = (argv[1][0] == 'm') ? 1 : 0;
1395 if (!argv[2] || strlen(argv[2]) != 12) {
1396 printf("MAC address format error, should be of length 12\n");
1397 return;
1398 }
1399 strncpy(tmpstr, argv[2], 8);
1400 tmpstr[8] = '\0';
1401 value = strtoul(tmpstr, NULL, 16);
1402 reg_write(REG_ATA1_ADDR, value);
1403 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1404
1405 strncpy(tmpstr, argv[2] + 8, 4);
1406 tmpstr[4] = '\0';
1407
1408 value = strtoul(tmpstr, NULL, 16);
1409 value = (value << 16);
1410 value |= (1 << 15); //IVL=1
1411
1412 if (argc > 4) {
1413 j = strtoul(argv[4], NULL, 0);
1414 if (4095 < j) {
1415 printf("wrong vid range, should be within 0~4095\n");
1416 return;
1417 }
1418 value |= j; //vid
1419 }
1420
1421 reg_write(REG_ATA2_ADDR, value);
1422 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1423
1424 if (!argv[3] || strlen(argv[3]) != 8) {
1425 if (is_filter)
1426 argv[3] = "11111111";
1427 else {
1428 printf("portmap format error, should be of length 8\n");
1429 return;
1430 }
1431 }
1432 j = 0;
1433 for (i = 0; i < 7; i++) {
1434 if (argv[3][i] != '0' && argv[3][i] != '1') {
1435 printf("portmap format error, should be of combination of 0 or 1\n");
1436 return;
1437 }
1438 j += (argv[3][i] - '0') * (1 << i);
1439 }
1440 value = j << 4; //w_port_map
1441
1442 if (argc > 5) {
1443 j = strtoul(argv[5], NULL, 0);
1444 if (j < 1 || 255 < j) {
1445 printf("wrong age range, should be within 1~255\n");
1446 return;
1447 }
1448 value |= (j << 24); //w_age_field
1449 value |= (0x1 << 2); //dynamic
1450 } else {
1451 value |= (0xff << 24); //w_age_field
1452 value |= (0x3 << 2); //static
1453 }
1454
1455 if (argc > 6) {
1456 j = strtoul(argv[6], NULL, 0);
1457 if (7 < j) {
1458 printf("wrong eg-tag range, should be within 0~7\n");
1459 return;
1460 }
1461 value |= (j << 13); //EG_TAG
1462 }
1463
1464 if (is_filter)
1465 value |= (7 << 20); //sa_filter
1466
1467 if (is_mymac)
1468 value |= (1 << 23);
1469
1470 reg_write(REG_ATWD_ADDR, value);
1471
1472 usleep(5000);
1473 reg_read(REG_ATWD_ADDR, &value);
1474 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1475
1476 value = 0x8001; //w_mac_cmd
1477 reg_write(REG_ATC_ADDR, value);
1478
1479 usleep(1000);
1480
1481 for (i = 0; i < 20; i++) {
1482 reg_read(REG_ATC_ADDR, &value);
1483 if ((value & 0x8000) == 0) { //mac address busy
1484 printf("done.\n");
1485 return;
1486 }
1487 usleep(1000);
1488 }
1489 if (i == 20)
1490 printf("timeout.\n");
1491}
1492
1493void table_search_mac_vid(int argc, char *argv[])
1494{
1495 unsigned int i, j, value, mac, mac2, value2;
1496 char tmpstr[9];
1497
1498 if (!argv[3] || strlen(argv[3]) != 12) {
1499 printf("MAC address format error, should be of length 12\n");
1500 return;
1501 }
1502 strncpy(tmpstr, argv[3], 8);
1503 tmpstr[8] = '\0';
1504 value = strtoul(tmpstr, NULL, 16);
1505 reg_write(REG_ATA1_ADDR, value);
1506 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1507
1508 strncpy(tmpstr, argv[3] + 8, 4);
1509 tmpstr[4] = '\0';
1510
1511 value = strtoul(tmpstr, NULL, 16);
1512 value = (value << 16);
1513 value |= (1 << 15); //IVL=1
1514
1515 j = strtoul(argv[5], NULL, 0);
1516 if (4095 < j) {
1517 printf("wrong vid range, should be within 0~4095\n");
1518 return;
1519 }
1520 value |= j; //vid
1521
1522 reg_write(REG_ATA2_ADDR, value);
1523 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1524
1525 value = 0x8000; //w_mac_cmd
1526 reg_write(REG_ATC_ADDR, value);
1527
1528 usleep(1000);
1529
1530 for (i = 0; i < 20; i++) {
1531 reg_read(REG_ATC_ADDR, &value);
1532 if ((value & 0x8000) == 0) { //mac address busy
1533 break;
1534 }
1535 usleep(1000);
1536 }
1537 if (i == 20) {
1538 printf("search timeout.\n");
1539 return;
1540 }
1541
1542 if (value & 0x1000) {
1543 printf("search no entry.\n");
1544 return;
1545 }
1546
1547 printf("search done.\n");
1548 printf("hash port(0:6) fid vid age mac-address filter my_mac\n");
1549
1550 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1551 reg_read(REG_ATRD_ADDR, &value2);
1552 j = (value2 >> 4) & 0xff; //r_port_map
1553 printf("%c", (j & 0x01) ? '1' : '-');
1554 printf("%c", (j & 0x02) ? '1' : '-');
1555 printf("%c", (j & 0x04) ? '1' : '-');
1556 printf("%c ", (j & 0x08) ? '1' : '-');
1557 printf("%c", (j & 0x10) ? '1' : '-');
1558 printf("%c", (j & 0x20) ? '1' : '-');
1559 printf("%c", (j & 0x40) ? '1' : '-');
1560 printf("%c", (j & 0x80) ? '1' : '-');
1561
1562 reg_read(REG_TSRA2_ADDR, &mac2);
1563
1564 printf(" %2d", (mac2 >> 12) & 0x7); //FID
1565 printf(" %4d", (mac2 & 0xfff));
1566 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
1567 reg_read(REG_TSRA1_ADDR, &mac);
1568 printf(" %08x", mac);
1569 printf("%04x", ((mac2 >> 16) & 0xffff));
1570 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1571 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1572}
1573
1574void table_search_mac_fid(int argc, char *argv[])
1575{
1576 unsigned int i, j, value, mac, mac2, value2;
1577 char tmpstr[9];
1578
1579 if (!argv[3] || strlen(argv[3]) != 12) {
1580 printf("MAC address format error, should be of length 12\n");
1581 return;
1582 }
1583 strncpy(tmpstr, argv[3], 8);
1584 tmpstr[8] = '\0';
1585 value = strtoul(tmpstr, NULL, 16);
1586 reg_write(REG_ATA1_ADDR, value);
1587 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1588
1589 strncpy(tmpstr, argv[3] + 8, 4);
1590 tmpstr[4] = '\0';
1591
1592 value = strtoul(tmpstr, NULL, 16);
1593 value = (value << 16);
1594 value &= ~(1 << 15); //IVL=0
1595
1596 j = strtoul(argv[5], NULL, 0);
1597 if (7 < j) {
1598 printf("wrong fid range, should be within 0~7\n");
1599 return;
1600 }
1601 value |= (j << 12); //vid
1602
1603 reg_write(REG_ATA2_ADDR, value);
1604 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1605
1606 value = 0x8000; //w_mac_cmd
1607 reg_write(REG_ATC_ADDR, value);
1608
1609 usleep(1000);
1610
1611 for (i = 0; i < 20; i++) {
1612 reg_read(REG_ATC_ADDR, &value);
1613 if ((value & 0x8000) == 0) { //mac address busy
1614 break;
1615 }
1616 usleep(1000);
1617 }
1618 if (i == 20) {
1619 printf("search timeout.\n");
1620 return;
1621 }
1622
1623 if (value & 0x1000) {
1624 printf("search no entry.\n");
1625 return;
1626 }
1627
1628 printf("search done.\n");
1629 printf("hash port(0:6) fid vid age mac-address filter my_mac\n");
1630
1631 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1632 reg_read(REG_ATRD_ADDR, &value2);
1633 j = (value2 >> 4) & 0xff; //r_port_map
1634 printf("%c", (j & 0x01) ? '1' : '-');
1635 printf("%c", (j & 0x02) ? '1' : '-');
1636 printf("%c", (j & 0x04) ? '1' : '-');
1637 printf("%c ", (j & 0x08) ? '1' : '-');
1638 printf("%c", (j & 0x10) ? '1' : '-');
1639 printf("%c", (j & 0x20) ? '1' : '-');
1640 printf("%c", (j & 0x40) ? '1' : '-');
1641 printf("%c", (j & 0x80) ? '1' : '-');
1642
1643 reg_read(REG_TSRA2_ADDR, &mac2);
1644
1645 printf(" %2d", (mac2 >> 12) & 0x7); //FID
1646 printf(" %4d", (mac2 & 0xfff));
1647 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
1648 reg_read(REG_TSRA1_ADDR, &mac);
1649 printf(" %08x", mac);
1650 printf("%04x", ((mac2 >> 16) & 0xffff));
1651 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1652 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1653}
1654
1655void table_del_fid(int argc, char *argv[])
1656{
1657 unsigned int i, j, value;
1658 char tmpstr[9];
1659
1660 if (!argv[3] || strlen(argv[3]) != 12) {
1661 printf("MAC address format error, should be of length 12\n");
1662 return;
1663 }
1664 strncpy(tmpstr, argv[3], 8);
1665 tmpstr[8] = '\0';
1666 value = strtoul(tmpstr, NULL, 16);
1667 reg_write(REG_ATA1_ADDR, value);
1668 strncpy(tmpstr, argv[3] + 8, 4);
1669 tmpstr[4] = '\0';
1670 value = strtoul(tmpstr, NULL, 16);
1671 value = (value << 16);
1672
1673 if (argc > 5) {
1674 j = strtoul(argv[5], NULL, 0);
1675 if (j > 7) {
1676 printf("wrong fid range, should be within 0~7\n");
1677 return;
1678 }
1679 value |= (j << 12); //fid
1680 }
1681
1682 reg_write(REG_ATA2_ADDR, value);
1683
1684 value = 0; //STATUS=0, delete mac
1685 reg_write(REG_ATWD_ADDR, value);
1686
1687 value = 0x8001; //w_mac_cmd
1688 reg_write(REG_ATC_ADDR, value);
1689
1690 for (i = 0; i < 20; i++) {
1691 reg_read(REG_ATC_ADDR, &value);
1692 if ((value & 0x8000) == 0) { //mac address busy
1693 if (argv[1] != NULL)
1694 printf("done.\n");
1695 return;
1696 }
1697 usleep(1000);
1698 }
1699 if (i == 20)
1700 printf("timeout.\n");
1701}
1702
1703void table_del_vid(int argc, char *argv[])
1704{
1705 unsigned int i, j, value;
1706 char tmpstr[9];
1707
1708 if (!argv[3] || strlen(argv[3]) != 12) {
1709 printf("MAC address format error, should be of length 12\n");
1710 return;
1711 }
1712 strncpy(tmpstr, argv[3], 8);
1713 tmpstr[8] = '\0';
1714 value = strtoul(tmpstr, NULL, 16);
1715 reg_write(REG_ATA1_ADDR, value);
1716
1717 strncpy(tmpstr, argv[3] + 8, 4);
1718 tmpstr[4] = '\0';
1719 value = strtoul(tmpstr, NULL, 16);
1720 value = (value << 16);
1721
1722 j = strtoul(argv[5], NULL, 0);
1723 if (j > 4095) {
1724 printf("wrong fid range, should be within 0~4095\n");
1725 return;
1726 }
1727 value |= j; //vid
1728 value |= 1 << 15;
1729 reg_write(REG_ATA2_ADDR, value);
1730
1731 value = 0; //STATUS=0, delete mac
1732 reg_write(REG_ATWD_ADDR, value);
1733
1734 value = 0x8001; //w_mac_cmd
1735 reg_write(REG_ATC_ADDR, value);
1736
1737 for (i = 0; i < 20; i++) {
1738 reg_read(REG_ATC_ADDR, &value);
1739 if ((value & 0x8000) == 0) { //mac address busy
1740 if (argv[1] != NULL)
1741 printf("done.\n");
1742 return;
1743 }
1744 usleep(1000);
1745 }
1746 if (i == 20)
1747 printf("timeout.\n");
1748}
1749
1750void table_clear(void)
1751{
1752 unsigned int value;
1753 reg_write(REG_ATC_ADDR, 0x8002);
1754 usleep(5000);
1755 reg_read(REG_ATC_ADDR, &value);
1756
1757 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1758}
1759
1760void set_mirror_to(int argc, char *argv[])
1761{
1762 unsigned int value;
1763 int idx;
1764
1765 idx = strtoul(argv[3], NULL, 0);
1766 if (idx < 0 || MAX_PORT < idx) {
1767 printf("wrong port member, should be within 0~%d\n", MAX_PORT);
1768 return;
1769 }
1770 if (chip_name == 0x7530) {
1771
1772 reg_read(REG_MFC_ADDR, &value);
1773 value |= 0x1 << 3;
1774 value &= 0xfffffff8;
1775 value |= idx << 0;
1776
1777 reg_write(REG_MFC_ADDR, value);
1778 } else {
1779
1780 reg_read(REG_CFC_ADDR, &value);
1781 value &= (~REG_CFC_MIRROR_EN_MASK);
1782 value |= (1 << REG_CFC_MIRROR_EN_OFFT);
1783 value &= (~REG_CFC_MIRROR_PORT_MASK);
1784 value |= (idx << REG_CFC_MIRROR_PORT_OFFT);
1785 reg_write(REG_CFC_ADDR, value);
1786 }
1787}
1788
1789void set_mirror_from(int argc, char *argv[])
1790{
1791 unsigned int offset, value;
1792 int idx, mirror;
1793
1794 idx = strtoul(argv[3], NULL, 0);
1795 mirror = strtoul(argv[4], NULL, 0);
1796
1797 if (idx < 0 || MAX_PORT < idx) {
1798 printf("wrong port member, should be within 0~%d\n", MAX_PORT);
1799 return;
1800 }
1801
1802 if (mirror < 0 || 3 < mirror) {
1803 printf("wrong mirror setting, should be within 0~3\n");
1804 return;
1805 }
1806
1807 offset = (0x2004 | (idx << 8));
1808 reg_read(offset, &value);
1809
1810 value &= 0xfffffcff;
1811 value |= mirror << 8;
1812
1813 reg_write(offset, value);
1814}
1815
1816void vlan_dump(int argc, char *argv[])
1817{
1818 unsigned int i, j, value, value2;
1819 int eg_tag = 0;
1820
1821 if (argc == 4) {
1822 if (!strncmp(argv[3], "egtag", 6))
1823 eg_tag = 1;
1824 }
1825
1826 if (eg_tag)
1827 printf(" vid fid portmap s-tag\teg_tag(0:untagged 2:tagged)\n");
1828 else
1829 printf(" vid fid portmap s-tag\n");
1830
1831 for (i = 1; i < 4095; i++) {
1832 value = (0x80000000 + i); //r_vid_cmd
1833 reg_write(REG_VTCR_ADDR, value);
1834
1835 for (j = 0; j < 20; j++) {
1836 reg_read(REG_VTCR_ADDR, &value);
1837 if ((value & 0x80000000) == 0) { //mac address busy
1838 break;
1839 }
1840 usleep(1000);
1841 }
1842 if (j == 20)
1843 printf("timeout.\n");
1844
1845 reg_read(REG_VAWD1_ADDR, &value);
1846 reg_read(REG_VAWD2_ADDR, &value2);
1847 //printf("REG_VAWD1_ADDR value%d is 0x%x\n\r", i, value);
1848 //printf("REG_VAWD2_ADDR value%d is 0x%x\n\r", i, value2);
1849
1850 if ((value & 0x01) != 0) {
1851 printf(" %4d ", i);
1852 printf(" %2d ", ((value & 0xe) >> 1));
1853 printf(" %c", (value & 0x00010000) ? '1' : '-');
1854 printf("%c", (value & 0x00020000) ? '1' : '-');
1855 printf("%c", (value & 0x00040000) ? '1' : '-');
1856 printf("%c", (value & 0x00080000) ? '1' : '-');
1857 printf("%c", (value & 0x00100000) ? '1' : '-');
1858 printf("%c", (value & 0x00200000) ? '1' : '-');
1859 printf("%c", (value & 0x00400000) ? '1' : '-');
1860 printf("%c", (value & 0x00800000) ? '1' : '-');
1861 printf(" %4d", ((value & 0xfff0) >> 4));
1862 if (eg_tag) {
1863 printf("\t");
1864 if ((value & (0x3 << 28)) == (0x3 << 28)) {
1865 /* VTAG_EN=1 and EG_CON=1 */
1866 printf("CONSISTENT");
1867 } else if (value & (0x1 << 28)) {
1868 /* VTAG_EN=1 */
1869 printf("%d", (value2 & 0x0003) >> 0);
1870 printf("%d", (value2 & 0x000c) >> 2);
1871 printf("%d", (value2 & 0x0030) >> 4);
1872 printf("%d", (value2 & 0x00c0) >> 6);
1873 printf("%d", (value2 & 0x0300) >> 8);
1874 printf("%d", (value2 & 0x0c00) >> 10);
1875 printf("%d", (value2 & 0x3000) >> 12);
1876 printf("%d", (value2 & 0xc000) >> 14);
1877 } else {
1878 /* VTAG_EN=0 */
1879 printf("DISABLED");
1880 }
1881 }
1882 printf("\n");
1883 } else {
1884 /*print 16 vid for reference information*/
1885 if (i <= 16) {
1886 printf(" %4d ", i);
1887 printf(" %2d ", ((value & 0xe) >> 1));
1888 printf(" invalid\n");
1889 }
1890 }
1891 }
1892}
1893
1894
1895static long timespec_diff_us(struct timespec start, struct timespec end)
1896{
1897 struct timespec temp;
1898 unsigned long duration = 0;
1899
1900 if ((end.tv_nsec - start.tv_nsec) < 0) {
1901 temp.tv_sec = end.tv_sec - start.tv_sec - 1;
1902 temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
1903 } else {
1904 temp.tv_sec = end.tv_sec - start.tv_sec;
1905 temp.tv_nsec = end.tv_nsec - start.tv_nsec;
1906 }
1907 /* calculate second part*/
1908 duration += temp.tv_sec * 1000000;
1909 /* calculate ns part*/
1910 duration += temp.tv_nsec >> 10;
1911
1912 return duration;
1913}
1914
1915
1916void vlan_clear(int argc, char *argv[])
1917{
1918 unsigned int value;
1919 int vid;
1920 unsigned long duration_us = 0;
1921 struct timespec start, end;
1922
1923 for (vid = 0; vid < 4096; vid++) {
1924 clock_gettime(CLOCK_REALTIME, &start);
1925 value = 0; //invalid
1926 reg_write(REG_VAWD1_ADDR, value);
1927
1928 value = (0x80001000 + vid); //w_vid_cmd
1929 reg_write(REG_VTCR_ADDR, value);
1930 while (duration_us <= 1000) {
1931 reg_read(REG_VTCR_ADDR, &value);
1932 if ((value & 0x80000000) == 0) { //table busy
1933 break;
1934 }
1935 clock_gettime(CLOCK_REALTIME, &end);
1936 duration_us = timespec_diff_us(start, end);
1937 }
1938 if (duration_us > 1000)
1939 printf("config vlan timeout: %ld.\n", duration_us);
1940 }
1941}
1942
1943void vlan_set(int argc, char *argv[])
1944{
1945 unsigned int vlan_mem = 0;
1946 unsigned int value = 0;
1947 unsigned int value2 = 0;
1948 int i, vid, fid;
1949 int stag = 0;
1950 unsigned long eg_con = 0;
1951 unsigned int eg_tag = 0;
1952
1953 if (argc < 5) {
1954 printf("insufficient arguments!\n");
1955 return;
1956 }
1957
1958 fid = strtoul(argv[3], NULL, 0);
1959 if (fid < 0 || fid > 7) {
1960 printf("wrong filtering db id range, should be within 0~7\n");
1961 return;
1962 }
1963 value |= (fid << 1);
1964
1965 vid = strtoul(argv[4], NULL, 0);
1966 if (vid < 0 || 0xfff < vid) {
1967 printf("wrong vlan id range, should be within 0~4095\n");
1968 return;
1969 }
1970
1971 if (strlen(argv[5]) != 8) {
1972 printf("portmap format error, should be of length 7\n");
1973 return;
1974 }
1975
1976 vlan_mem = 0;
1977 for (i = 0; i < 8; i++) {
1978 if (argv[5][i] != '0' && argv[5][i] != '1') {
1979 printf("portmap format error, should be of combination of 0 or 1\n");
1980 return;
1981 }
1982 vlan_mem += (argv[5][i] - '0') * (1 << i);
1983 }
1984
1985 /* VLAN stag */
1986 if (argc > 6) {
1987 stag = strtoul(argv[6], NULL, 16);
1988 if (stag < 0 || 0xfff < stag) {
1989 printf("wrong stag id range, should be within 0~4095\n");
1990 return;
1991 }
1992 //printf("STAG is 0x%x\n", stag);
1993 }
1994
1995 /* set vlan member */
1996 value |= (vlan_mem << 16);
1997 value |= (1 << 30); //IVL=1
1998 value |= ((stag & 0xfff) << 4); //stag
1999 value |= 1; //valid
2000
2001 if (argc > 7) {
2002 eg_con = strtoul(argv[7], NULL, 2);
2003 eg_con = !!eg_con;
2004 value |= (eg_con << 29); //eg_con
2005 value |= (1 << 28); //eg tag control enable
2006 }
2007
2008 if (argc > 8 && !eg_con) {
2009 if (strlen(argv[8]) != 8) {
2010 printf("egtag portmap format error, should be of length 7\n");
2011 return;
2012 }
2013
2014 for (i = 0; i < 8; i++) {
2015 if (argv[8][i] < '0' || argv[8][i] > '3') {
2016 printf("egtag portmap format error, should be of combination of 0 or 3\n");
2017 return;
2018 }
2019 //eg_tag += (argv[8][i] - '0') * (1 << i * 2);
2020 eg_tag |= (argv[8][i] - '0') << (i * 2);
2021 }
2022
2023 value |= (1 << 28); //eg tag control enable
2024 value2 &= ~(0xffff);
2025 value2 |= eg_tag;
2026 }
2027 reg_write(REG_VAWD1_ADDR, value);
2028 reg_write(REG_VAWD2_ADDR, value2);
2029 //printf("VAWD1=0x%08x VAWD2=0x%08x ", value, value2);
2030
2031 value = (0x80001000 + vid); //w_vid_cmd
2032 reg_write(REG_VTCR_ADDR, value);
2033 //printf("VTCR=0x%08x\n", value);
2034
2035 for (i = 0; i < 300; i++) {
2036 usleep(1000);
2037 reg_read(REG_VTCR_ADDR, &value);
2038 if ((value & 0x80000000) == 0) //table busy
2039 break;
2040 }
2041
2042 if (i == 300)
2043 printf("config vlan timeout.\n");
2044}
2045
2046void igmp_on(int argc, char *argv[])
2047{
2048 unsigned int leaky_en = 0;
2049 unsigned int wan_num = 4;
2050 unsigned int port, offset, value;
2051 char cmd[80];
2052 int ret;
2053
2054 if (argc > 3)
2055 leaky_en = strtoul(argv[3], NULL, 10);
2056 if (argc > 4)
2057 wan_num = strtoul(argv[4], NULL, 10);
2058
2059 if (leaky_en == 1) {
2060 if (wan_num == 4) {
2061 /* reg_write(0x2410, 0x810000c8); */
2062 reg_read(0x2410, &value);
2063 reg_write(0x2410, value | (1 << 3));
2064 /* reg_write(0x2010, 0x810000c0); */
2065 reg_read(0x2010, &value);
2066 reg_write(0x2010, value & (~(1 << 3)));
2067 reg_write(REG_ISC_ADDR, 0x10027d10);
2068 } else {
2069 /* reg_write(0x2010, 0x810000c8); */
2070 reg_read(0x2010, &value);
2071 reg_write(0x2010, value | (1 << 3));
2072 /* reg_write(0x2410, 0x810000c0); */
2073 reg_read(0x2410, &value);
2074 reg_write(0x2410, value & (~(1 << 3)));
2075 reg_write(REG_ISC_ADDR, 0x01027d01);
2076 }
2077 }
2078 else
2079 reg_write(REG_ISC_ADDR, 0x10027d60);
2080
2081 reg_write(0x1c, 0x08100810);
2082 reg_write(0x2008, 0xb3ff);
2083 reg_write(0x2108, 0xb3ff);
2084 reg_write(0x2208, 0xb3ff);
2085 reg_write(0x2308, 0xb3ff);
2086 reg_write(0x2408, 0xb3ff);
2087 reg_write(0x2608, 0xb3ff);
2088 /* Enable Port ACL
2089 * reg_write(0x2P04, 0xff0403);
2090 */
2091 for (port = 0; port <= 6; port++) {
2092 offset = 0x2004 + port * 0x100;
2093 reg_read(offset, &value);
2094 reg_write(offset, value | (1 << 10));
2095 }
2096
2097 /*IGMP query only p4 -> p5*/
2098 reg_write(0x94, 0x00ff0002);
2099 if (wan_num == 4)
2100 reg_write(0x98, 0x000a1008);
2101 else
2102 reg_write(0x98, 0x000a0108);
2103 reg_write(0x90, 0x80005000);
2104 reg_write(0x94, 0xff001100);
2105 if (wan_num == 4)
2106 reg_write(0x98, 0x000B1000);
2107 else
2108 reg_write(0x98, 0x000B0100);
2109 reg_write(0x90, 0x80005001);
2110 reg_write(0x94, 0x3);
2111 reg_write(0x98, 0x0);
2112 reg_write(0x90, 0x80009000);
2113 reg_write(0x94, 0x1a002080);
2114 reg_write(0x98, 0x0);
2115 reg_write(0x90, 0x8000b000);
2116
2117 /*IGMP p5 -> p4*/
2118 reg_write(0x94, 0x00ff0002);
2119 reg_write(0x98, 0x000a2008);
2120 reg_write(0x90, 0x80005002);
2121 reg_write(0x94, 0x4);
2122 reg_write(0x98, 0x0);
2123 reg_write(0x90, 0x80009001);
2124 if (wan_num == 4)
2125 reg_write(0x94, 0x1a001080);
2126 else
2127 reg_write(0x94, 0x1a000180);
2128 reg_write(0x98, 0x0);
2129 reg_write(0x90, 0x8000b001);
2130
2131 /*IGMP p0~p3 -> p6*/
2132 reg_write(0x94, 0x00ff0002);
2133 if (wan_num == 4)
2134 reg_write(0x98, 0x000a0f08);
2135 else
2136 reg_write(0x98, 0x000a1e08);
2137 reg_write(0x90, 0x80005003);
2138 reg_write(0x94, 0x8);
2139 reg_write(0x98, 0x0);
2140 reg_write(0x90, 0x80009002);
2141 reg_write(0x94, 0x1a004080);
2142 reg_write(0x98, 0x0);
2143 reg_write(0x90, 0x8000b002);
2144
2145 /*IGMP query only p6 -> p0~p3*/
2146 reg_write(0x94, 0x00ff0002);
2147 reg_write(0x98, 0x000a4008);
2148 reg_write(0x90, 0x80005004);
2149 reg_write(0x94, 0xff001100);
2150 reg_write(0x98, 0x000B4000);
2151 reg_write(0x90, 0x80005005);
2152 reg_write(0x94, 0x30);
2153 reg_write(0x98, 0x0);
2154 reg_write(0x90, 0x80009003);
2155 if (wan_num == 4)
2156 reg_write(0x94, 0x1a000f80);
2157 else
2158 reg_write(0x94, 0x1a001e80);
2159 reg_write(0x98, 0x0);
2160 reg_write(0x90, 0x8000b003);
2161
2162 /*Force eth2 to receive all igmp packets*/
2163 snprintf(cmd, sizeof(cmd), "echo 2 > /sys/devices/virtual/net/%s/brif/%s/multicast_router", BR_DEVNAME, ETH_DEVNAME);
2164 ret = system(cmd);
2165 if (ret)
2166 printf("Failed to set /sys/devices/virtual/net/%s/brif/%s/multicast_router\n",
2167 BR_DEVNAME, ETH_DEVNAME);
2168}
2169
2170void igmp_disable(int argc, char *argv[])
2171{
2172 unsigned int reg_offset, value;
2173 int port_num;
2174
2175 if (argc < 4) {
2176 printf("insufficient arguments!\n");
2177 return;
2178 }
2179 port_num = strtoul(argv[3], NULL, 0);
2180 if (port_num < 0 || 6 < port_num) {
2181 printf("wrong port range, should be within 0~6\n");
2182 return;
2183 }
2184
2185 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2186 reg_offset = 0x2008;
2187 reg_offset |= (port_num << 8);
2188 value = 0x8000;
2189
2190 reg_write(reg_offset, value);
2191}
2192
2193void igmp_enable(int argc, char *argv[])
2194{
2195 unsigned int reg_offset, value;
2196 int port_num;
2197
2198 if (argc < 4) {
2199 printf("insufficient arguments!\n");
2200 return;
2201 }
2202 port_num = strtoul(argv[3], NULL, 0);
2203 if (port_num < 0 || 6 < port_num) {
2204 printf("wrong port range, should be within 0~6\n");
2205 return;
2206 }
2207
2208 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2209 reg_offset = 0x2008;
2210 reg_offset |= (port_num << 8);
2211 value = 0x9755;
2212 reg_write(reg_offset, value);
2213}
2214
2215void igmp_off()
2216{
2217 unsigned int value;
2218 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2219 reg_read(REG_ISC_ADDR, &value);
2220 value &= ~(1 << 18); //disable
2221 reg_write(REG_ISC_ADDR, value);
2222
2223 /*restore wan port multicast leaky vlan function: default disabled*/
2224 reg_read(0x2010, &value);
2225 reg_write(0x2010, value & (~(1 << 3)));
2226 reg_read(0x2410, &value);
2227 reg_write(0x2410, value & (~(1 << 3)));
2228
2229 printf("config igmpsnoop off.\n");
2230}
2231
developer8c3871b2022-07-01 14:07:53 +08002232int switch_reset(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002233{
developer8c3871b2022-07-01 14:07:53 +08002234 if (chip_name == 0x7988)
2235 return -1;
2236
developerfd40db22021-04-29 10:08:25 +08002237 unsigned int value = 0;
2238 /*Software Register Reset and Software System Reset */
2239 reg_write(0x7000, 0x3);
2240 reg_read(0x7000, &value);
2241 printf("SYS_CTRL(0x7000) register value =0x%x \n", value);
2242 if (chip_name == 0x7531) {
2243 reg_write(0x7c0c, 0x11111111);
2244 reg_read(0x7c0c, &value);
2245 printf("GPIO Mode (0x7c0c) select value =0x%x \n", value);
2246 }
2247 printf("Switch Software Reset !!! \n");
developer8c3871b2022-07-01 14:07:53 +08002248 return 0;
developerfd40db22021-04-29 10:08:25 +08002249}
2250
2251int phy_set_fc(int argc, char *argv[])
2252{
2253 unsigned int port, pause_capable;
2254 unsigned int phy_value;
2255
2256 port = atoi(argv[3]);
2257 pause_capable = atoi(argv[4]);
2258
2259 /*Check the input parameters is right or not.*/
2260 if (port > MAX_PORT - 2 || pause_capable > 1) {
2261 printf("Illegal parameter (port:0~4, full_duplex_pause_capable:0|1)\n");
2262 return -1;
2263 }
2264 printf("port=%d, full_duplex_pause_capable:%d\n", port, pause_capable);
2265 mii_mgr_read(port, 4, &phy_value);
2266 printf("read phy_value:0x%x\r\n", phy_value);
2267 phy_value &= (~(0x1 << 10));
2268 phy_value &= (~(0x1 << 11));
2269 if (pause_capable == 1) {
2270 phy_value |= (0x1 << 10);
2271 phy_value |= (0x1 << 11);
2272 }
2273 mii_mgr_write(port, 4, phy_value);
2274 printf("write phy_value:0x%x\r\n", phy_value);
2275 return 0;
2276} /*end phy_set_fc*/
2277
2278int phy_set_an(int argc, char *argv[])
2279{
2280 unsigned int port, auto_negotiation_en;
2281 unsigned int phy_value;
2282
2283 port = atoi(argv[3]);
2284 auto_negotiation_en = atoi(argv[4]);
2285
2286 /*Check the input parameters is right or not.*/
2287 if (port > MAX_PORT - 2 || auto_negotiation_en > 1) {
2288 printf("Illegal parameter (port:0~4, auto_negotiation_en:0|1)\n");
2289 return -1;
2290 }
2291 printf("port=%d, auto_negotiation_en:%d\n", port, auto_negotiation_en);
2292 mii_mgr_read(port, 0, &phy_value);
2293 printf("read phy_value:0x%x\r\n", phy_value);
2294 phy_value &= (~(1 << 12));
2295 phy_value |= (auto_negotiation_en << 12);
2296 mii_mgr_write(port, 0, phy_value);
2297 printf("write phy_value:0x%x\r\n", phy_value);
2298 return 0;
2299} /*end phy_set_an*/
2300
2301int set_mac_pfc(int argc, char *argv[])
2302{
2303 unsigned int value;
2304 int port, enable = 0;
2305
2306 port = atoi(argv[3]);
2307 enable = atoi(argv[4]);
2308 printf("enable: %d\n", enable);
2309 if (port < 0 || port > 6 || enable < 0 || enable > 1) {
2310 printf("Illegal parameter (port:0~6, enable|diable:0|1) \n");
2311 return -1;
2312 }
developer8c3871b2022-07-01 14:07:53 +08002313 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002314 reg_read(REG_PFC_CTRL_ADDR, &value);
2315 value &= ~(1 << port);
2316 value |= (enable << port);
2317 printf("write reg: %x, value: %x\n", REG_PFC_CTRL_ADDR, value);
2318 reg_write(REG_PFC_CTRL_ADDR, value);
2319 }
2320 else
2321 printf("\nCommand not support by this chip.\n");
2322 return 0;
2323}
2324
2325int global_set_mac_fc(int argc, char *argv[])
2326{
2327 unsigned char enable = 0;
2328 unsigned int value, reg;
2329
2330 if (chip_name == 0x7530) {
2331 enable = atoi(argv[3]);
2332 printf("enable: %d\n", enable);
2333
2334 /*Check the input parameters is right or not.*/
2335 if (enable > 1) {
2336 printf(HELP_MACCTL_FC);
2337 return -1;
2338 }
2339 reg_write(0x7000, 0x3);
2340 reg = REG_GFCCR0_ADDR;
2341 reg_read(REG_GFCCR0_ADDR, &value);
2342 value &= (~REG_FC_EN_MASK);
2343 value |= (enable << REG_FC_EN_OFFT);
2344 printf("write reg: %x, value: %x\n", reg, value);
2345 reg_write(REG_GFCCR0_ADDR, value);
2346 } else
2347 printf("\r\nCommand not support by this chip.\n");
2348 return 0;
2349} /*end mac_set_fc*/
2350
2351int qos_sch_select(int argc, char *argv[])
2352{
2353 unsigned char port, queue;
2354 unsigned char type = 0;
2355 unsigned int value, reg;
2356
2357 if (argc < 7)
2358 return -1;
2359
2360 port = atoi(argv[3]);
2361 queue = atoi(argv[4]);
2362 type = atoi(argv[6]);
2363
2364 if (port > 6 || queue > 7) {
2365 printf("\n Illegal input parameters\n");
2366 return -1;
2367 }
2368
2369 if ((type != 0 && type != 1 && type != 2)) {
2370 printf(HELP_QOS_TYPE);
2371 return -1;
2372 }
2373
2374 printf("\r\nswitch qos type: %d.\n",type);
2375
2376 if (!strncmp(argv[5], "min", 4)) {
2377
2378 if (type == 0) {
2379 /*min sharper-->round roubin, disable min sharper rate limit*/
2380 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2381 reg_read(reg, &value);
2382 value = 0x0;
2383 reg_write(reg, value);
2384 } else if (type == 1) {
2385 /*min sharper-->sp, disable min sharper rate limit*/
2386 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2387 reg_read(reg, &value);
2388 value = 0x0;
2389 value |= (1 << 31);
2390 reg_write(reg, value);
2391 } else {
2392 printf("min sharper only support: rr or sp\n");
2393 return -1;
2394 }
2395 } else if (!strncmp(argv[5], "max", 4)) {
2396 if (type == 1) {
2397 /*max sharper-->sp, disable max sharper rate limit*/
2398 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2399 reg_read(reg, &value);
2400 value = 0x0;
2401 value |= (1 << 31);
2402 reg_write(reg, value);
2403 } else if (type == 2) {
2404 /*max sharper-->wfq, disable max sharper rate limit*/
2405 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2406 reg_read(reg, &value);
2407 value = 0x0;
2408 reg_write(reg, value);
2409 } else {
2410 printf("max sharper only support: wfq or sp\n");
2411 return -1;
2412 }
2413 } else {
2414 printf("\r\nIllegal sharper:%s\n",argv[5]);
2415 return -1;
2416 }
2417 printf("reg:0x%x--value:0x%x\n",reg,value);
2418
2419 return 0;
2420}
2421
2422void get_upw(unsigned int *value, unsigned char base)
2423{
2424 *value &= (~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
2425 (0x7 << 16) | (0x7 << 20)));
2426 switch (base)
2427 {
2428 case 0: /* port-based 0x2x40[18:16] */
2429 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2430 (0x2 << 12) | (0x7 << 16) | (0x2 << 20));
2431 break;
2432 case 1: /* tagged-based 0x2x40[10:8] */
2433 *value |= ((0x2 << 0) | (0x2 << 4) | (0x7 << 8) |
2434 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2435 break;
2436 case 2: /* DSCP-based 0x2x40[14:12] */
2437 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2438 (0x7 << 12) | (0x2 << 16) | (0x2 << 20));
2439 break;
2440 case 3: /* acl-based 0x2x40[2:0] */
2441 *value |= ((0x7 << 0) | (0x2 << 4) | (0x2 << 8) |
2442 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2443 break;
2444 case 4: /* arl-based 0x2x40[22:20] */
2445 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2446 (0x2 << 12) | (0x2 << 16) | (0x7 << 20));
2447 break;
2448 case 5: /* stag-based 0x2x40[6:4] */
2449 *value |= ((0x2 << 0) | (0x7 << 4) | (0x2 << 8) |
2450 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2451 break;
2452 default:
2453 break;
2454 }
2455}
2456
2457void qos_set_base(int argc, char *argv[])
2458{
2459 unsigned char base = 0;
2460 unsigned char port;
2461 unsigned int value;
2462
2463 if (argc < 5)
2464 return;
2465
2466 port = atoi(argv[3]);
2467 base = atoi(argv[4]);
2468
2469 if (base > 6) {
2470 printf(HELP_QOS_BASE);
2471 return;
2472 }
2473
2474 if (port > 6) {
2475 printf("Illegal port index:%d\n",port);
2476 return;
2477 }
2478
2479 printf("\r\nswitch qos base : %d. (port-based:0, tag-based:1,\
2480 dscp-based:2, acl-based:3, arl-based:4, stag-based:5)\n",
2481 base);
2482 if (chip_name == 0x7530) {
2483
2484 reg_read(0x44, &value);
2485 get_upw(&value, base);
2486 reg_write(0x44, value);
2487 printf("reg: 0x44, value: 0x%x\n", value);
2488
developer8c3871b2022-07-01 14:07:53 +08002489 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002490
2491 reg_read(GSW_UPW(port), &value);
2492 get_upw(&value, base);
2493 reg_write(GSW_UPW(port), value);
2494 printf("reg:0x%x, value: 0x%x\n",GSW_UPW(port),value);
2495
2496 } else {
2497 printf("unknown switch device");
2498 return;
2499 }
2500}
2501
2502void qos_wfq_set_weight(int argc, char *argv[])
2503{
2504 int port, weight[8], i;
2505 unsigned char queue;
2506 unsigned int reg, value;
2507
2508 port = atoi(argv[3]);
2509
2510 for (i = 0; i < 8; i++) {
2511 weight[i] = atoi(argv[i + 4]);
2512 }
2513
2514 /* MT7530 total 7 port */
2515 if (port < 0 || port > 6) {
2516 printf(HELP_QOS_PORT_WEIGHT);
2517 return;
2518 }
2519
2520 for (i = 0; i < 8; i++) {
2521 if (weight[i] < 1 || weight[i] > 16) {
2522 printf(HELP_QOS_PORT_WEIGHT);
2523 return;
2524 }
2525 }
2526 printf("port: %x, q0: %x, q1: %x, q2: %x, q3: %x, \
2527 q4: %x, q5: %x, q6: %x, q7: %x\n",
2528 port, weight[0], weight[1], weight[2], weight[3], weight[4],
2529 weight[5], weight[6], weight[7]);
2530
2531 for (queue = 0; queue < 8; queue++) {
2532 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2533 reg_read(reg, &value);
2534 value &= (~(0xf << 24)); //bit24~27
2535 value |= (((weight[queue] - 1) & 0xf) << 24);
2536 printf("reg: %x, value: %x\n", reg, value);
2537 reg_write(reg, value);
2538 }
2539}
2540
2541void qos_set_portpri(int argc, char *argv[])
2542{
2543 unsigned char port, prio;
2544 unsigned int value;
2545
2546 port = atoi(argv[3]);
2547 prio = atoi(argv[4]);
2548
2549 if (port >= 7 || prio > 7) {
2550 printf(HELP_QOS_PORT_PRIO);
2551 return;
2552 }
2553
2554 reg_read(GSW_PCR(port), &value);
2555 value &= (~(0x7 << 24));
2556 value |= (prio << 24);
2557 reg_write(GSW_PCR(port), value);
2558 printf("write reg: %x, value: %x\n", GSW_PCR(port), value);
2559}
2560
2561void qos_set_dscppri(int argc, char *argv[])
2562{
2563 unsigned char prio, dscp, pim_n, pim_offset;
2564 unsigned int reg, value;
2565
2566 dscp = atoi(argv[3]);
2567 prio = atoi(argv[4]);
2568
2569 if (dscp > 63 || prio > 7) {
2570 printf(HELP_QOS_DSCP_PRIO);
2571 return;
2572 }
2573
2574 pim_n = dscp / 10;
2575 pim_offset = (dscp - pim_n * 10) * 3;
2576 reg = 0x0058 + pim_n * 4;
2577 reg_read(reg, &value);
2578 value &= (~(0x7 << pim_offset));
2579 value |= ((prio & 0x7) << pim_offset);
2580 reg_write(reg, value);
2581 printf("write reg: %x, value: %x\n", reg, value);
2582}
2583
2584void qos_pri_mapping_queue(int argc, char *argv[])
2585{
2586 unsigned char prio, queue, pem_n, port;
2587 unsigned int reg, value;
2588
2589 if (argc < 6)
2590 return;
2591
2592 port = atoi(argv[3]);
2593 prio = atoi(argv[4]);
2594 queue = atoi(argv[5]);
2595
2596 if (prio > 7 || queue > 7) {
2597 printf(HELP_QOS_PRIO_QMAP);
2598 return;
2599 }
2600 if (chip_name == 0x7530) {
2601 pem_n = prio / 2;
2602 reg = pem_n * 0x4 + 0x48;
2603 reg_read(reg, &value);
2604 if (prio % 2) {
2605 value &= (~(0x7 << 24));
2606 value |= ((queue & 0x7) << 24);
2607 } else {
2608 value &= (~(0x7 << 8));
2609 value |= ((queue & 0x7) << 8);
2610 }
2611 reg_write(reg, value);
2612 printf("write reg: %x, value: %x\n", reg, value);
developer8c3871b2022-07-01 14:07:53 +08002613 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002614 pem_n = prio / 2;
2615 reg = GSW_PEM(pem_n) + 0x100 * port;
2616 reg_read(reg, &value);
2617 if (prio % 2) { // 1 1
2618 value &= (~(0x7 << 25));
2619 value |= ((queue & 0x7) << 25);
2620 } else { // 0 0
2621 value &= (~(0x7 << 9));
2622 value |= ((queue & 0x7) << 9);
2623 }
2624 reg_write(reg, value);
2625 printf("write reg: %x, value: %x\n", reg, value);
2626 }
2627 else {
2628 printf("unknown switch device");
2629 return;
2630 }
2631}
2632
2633static int macMT753xVlanSetVid(unsigned char index, unsigned char active,
2634 unsigned short vid, unsigned char portMap, unsigned char tagPortMap,
2635 unsigned char ivl_en, unsigned char fid, unsigned short stag)
2636{
2637 unsigned int value = 0;
2638 unsigned int value2 = 0;
2639 unsigned int reg;
2640 int i;
2641
2642 printf("index: %x, active: %x, vid: %x, portMap: %x, \
2643 tagPortMap: %x, ivl_en: %x, fid: %x, stag: %x\n",
2644 index, active, vid, portMap, tagPortMap, ivl_en, fid, stag);
2645
2646 value = (portMap << 16);
2647 value |= (stag << 4);
2648 value |= (ivl_en << 30);
2649 value |= (fid << 1);
2650 value |= (active ? 1 : 0);
2651
2652 // total 7 ports
2653 for (i = 0; i < 7; i++) {
2654 if (tagPortMap & (1 << i))
2655 value2 |= 0x2 << (i * 2);
2656 }
2657
2658 if (value2)
2659 value |= (1 << 28); // eg_tag
2660
2661 reg = 0x98; // VAWD2
2662 reg_write(reg, value2);
2663
2664 reg = 0x94; // VAWD1
2665 reg_write(reg, value);
2666
2667 reg = 0x90; // VTCR
2668 value = (0x80001000 + vid);
2669 reg_write(reg, value);
2670
2671 reg = 0x90; // VTCR
2672 while (1) {
2673 reg_read(reg, &value);
2674 if ((value & 0x80000000) == 0) //table busy
2675 break;
2676 }
2677
2678 /* switch clear */
2679 reg = 0x80;
2680 reg_write(reg, 0x8002);
2681 usleep(5000);
2682 reg_read(reg, &value);
2683
2684 printf("SetVid: index:%d active:%d vid:%d portMap:%x tagPortMap:%x\r\n",
2685 index, active, vid, portMap, tagPortMap);
2686 return 0;
2687
2688} /*end macMT753xVlanSetVid*/
2689/*
2690static int macMT753xVlanGetVtbl(unsigned short index)
2691{
2692 unsigned int reg, value, vawd1, vawd2;
2693
2694 reg = 0x90; // VTCR
2695 value = (0x80000000 + index);
2696
2697 reg_write(reg, value);
2698
2699 reg = 0x90; // VTCR
2700 while (1) {
2701 reg_read(reg, &value);
2702 if ((value & 0x80000000) == 0) //table busy
2703 break;
2704 }
2705
2706 reg = 0x94; // VAWD1
2707 reg_read(reg, &vawd1);
2708
2709 reg = 0x98; // VAWD2
2710 reg_read(reg, &vawd2);
2711
2712 if (vawd1 & 0x1) {
2713 fprintf(stderr, "%d.%s vid:%d fid:%d portMap:0x%x \
2714 tagMap:0x%x stag:0x%x ivl_en:0x%x\r\n",
2715 index, (vawd1 & 0x1) ? "on" : "off", index, ((vawd1 & 0xe) >> 1),
2716 (vawd1 & 0xff0000) >> 16, vawd2, (vawd1 & 0xfff0) >> 0x4, (vawd1 >> 30) & 0x1);
2717 }
2718 return 0;
2719} */ /*end macMT753xVlanGetVtbl*/
2720
2721static int macMT753xVlanSetPvid(unsigned char port, unsigned short pvid)
2722{
2723 unsigned int value;
2724 unsigned int reg;
2725
2726 /*Parameters is error*/
2727 if (port > 6)
2728 return -1;
2729
2730 reg = 0x2014 + (port * 0x100);
2731 reg_read(reg, &value);
2732 value &= ~0xfff;
2733 value |= pvid;
2734 reg_write(reg, value);
2735
2736 /* switch clear */
2737 reg = 0x80;
2738 reg_write(reg, 0x8002);
2739 usleep(5000);
2740 reg_read(reg, &value);
2741
2742 printf("SetPVID: port:%d pvid:%d\r\n", port, pvid);
2743 return 0;
2744}
2745/*
2746static int macMT753xVlanGetPvid(unsigned char port)
2747{
2748 unsigned int value;
2749 unsigned int reg;
2750
2751 if (port > 6)
2752 return -1;
2753 reg = 0x2014 + (port * 0x100);
2754 reg_read(reg, &value);
2755 return (value & 0xfff);
2756} */
2757/*
2758static int macMT753xVlanDisp(void)
2759{
2760 unsigned int i = 0;
2761 unsigned int reg, value;
2762
2763 reg = 0x2604;
2764 reg_read(reg, &value);
2765 value &= 0x30000000;
2766
2767 fprintf(stderr, "VLAN function is %s\n", value ? ETHCMD_ENABLE : ETHCMD_DISABLE);
2768 fprintf(stderr, "PVID e0:%02d e1:%02d e2:%02d e3:%02d e4:%02d e5:%02d e6:%02d\n",
2769 macMT753xVlanGetPvid(0), macMT753xVlanGetPvid(1), macMT753xVlanGetPvid(2),
2770 macMT753xVlanGetPvid(3), macMT753xVlanGetPvid(4), macMT753xVlanGetPvid(5), macMT753xVlanGetPvid(6));
2771
2772 for (i = 0; i < MAX_VID_VALUE; i++)
2773 macMT753xVlanGetVtbl(i);
2774
2775 return 0;
2776}*/ /*end macMT753xVlanDisp*/
2777
2778void doVlanSetPvid(int argc, char *argv[])
2779{
2780 unsigned char port = 0;
2781 unsigned short pvid = 0;
2782
2783 port = atoi(argv[3]);
2784 pvid = atoi(argv[4]);
2785 /*Check the input parameters is right or not.*/
2786 if ((port >= SWITCH_MAX_PORT) || (pvid > MAX_VID_VALUE)) {
2787 printf(HELP_VLAN_PVID);
2788 return;
2789 }
2790
2791 macMT753xVlanSetPvid(port, pvid);
2792
2793 printf("port:%d pvid:%d,vlancap: max_port:%d maxvid:%d\r\n",
2794 port, pvid, SWITCH_MAX_PORT, MAX_VID_VALUE);
2795} /*end doVlanSetPvid*/
2796
2797void doVlanSetVid(int argc, char *argv[])
2798{
2799 unsigned char index = 0;
2800 unsigned char active = 0;
2801 unsigned char portMap = 0;
2802 unsigned char tagPortMap = 0;
2803 unsigned short vid = 0;
2804
2805 unsigned char ivl_en = 0;
2806 unsigned char fid = 0;
2807 unsigned short stag = 0;
2808
2809 index = atoi(argv[3]);
2810 active = atoi(argv[4]);
2811 vid = atoi(argv[5]);
2812
2813 /*Check the input parameters is right or not.*/
2814 if ((index >= MAX_VLAN_RULE) || (vid >= 4096) || (active > ACTIVED)) {
2815 printf(HELP_VLAN_VID);
2816 return;
2817 }
2818
2819 /*CPU Port is always the membership*/
2820 portMap = atoi(argv[6]);
2821 tagPortMap = atoi(argv[7]);
2822
2823 printf("subcmd parameter argc = %d\r\n", argc);
2824 if (argc >= 9) {
2825 ivl_en = atoi(argv[8]);
2826 if (argc >= 10) {
2827 fid = atoi(argv[9]);
2828 if (argc >= 11)
2829 stag = atoi(argv[10]);
2830 }
2831 }
2832 macMT753xVlanSetVid(index, active, vid, portMap, tagPortMap,
2833 ivl_en, fid, stag);
2834 printf("index:%d active:%d vid:%d\r\n", index, active, vid);
2835} /*end doVlanSetVid*/
2836
2837void doVlanSetAccFrm(int argc, char *argv[])
2838{
2839 unsigned char port = 0;
2840 unsigned char type = 0;
2841 unsigned int value;
2842 unsigned int reg;
2843
2844 port = atoi(argv[3]);
2845 type = atoi(argv[4]);
2846
2847 printf("port: %d, type: %d\n", port, type);
2848
2849 /*Check the input parameters is right or not.*/
2850 if ((port > SWITCH_MAX_PORT) || (type > REG_PVC_ACC_FRM_RELMASK)) {
2851 printf(HELP_VLAN_ACC_FRM);
2852 return;
2853 }
2854
2855 reg = REG_PVC_P0_ADDR + port * 0x100;
2856 reg_read(reg, &value);
2857 value &= (~REG_PVC_ACC_FRM_MASK);
2858 value |= ((unsigned int)type << REG_PVC_ACC_FRM_OFFT);
2859
2860 printf("write reg: %x, value: %x\n", reg, value);
2861 reg_write(reg, value);
2862} /*end doVlanSetAccFrm*/
2863
2864void doVlanSetPortAttr(int argc, char *argv[])
2865{
2866 unsigned char port = 0;
2867 unsigned char attr = 0;
2868 unsigned int value;
2869 unsigned int reg;
2870
2871 port = atoi(argv[3]);
2872 attr = atoi(argv[4]);
2873
2874 printf("port: %x, attr: %x\n", port, attr);
2875
2876 /*Check the input parameters is right or not.*/
2877 if (port > SWITCH_MAX_PORT || attr > 3) {
2878 printf(HELP_VLAN_PORT_ATTR);
2879 return;
2880 }
2881
2882 reg = 0x2010 + port * 0x100;
2883 reg_read(reg, &value);
2884 value &= (0xffffff3f);
2885 value |= (attr << 6);
2886
2887 printf("write reg: %x, value: %x\n", reg, value);
2888 reg_write(reg, value);
2889}
2890
2891void doVlanSetPortMode(int argc, char *argv[])
2892{
2893 unsigned char port = 0;
2894 unsigned char mode = 0;
2895 unsigned int value;
2896 unsigned int reg;
2897 port = atoi(argv[3]);
2898 mode = atoi(argv[4]);
2899 printf("port: %x, mode: %x\n", port, mode);
2900
2901 /*Check the input parameters is right or not.*/
2902 if (port > SWITCH_MAX_PORT || mode > 3) {
2903 printf(HELP_VLAN_PORT_MODE);
2904 return;
2905 }
2906
2907 reg = 0x2004 + port * 0x100;
2908 reg_read(reg, &value);
2909 value &= (~((1 << 0) | (1 << 1)));
2910 value |= (mode & 0x3);
2911 printf("write reg: %x, value: %x\n", reg, value);
2912 reg_write(reg, value);
2913}
2914
2915void doVlanSetEgressTagPCR(int argc, char *argv[])
2916{
2917 unsigned char port = 0;
2918 unsigned char eg_tag = 0;
2919 unsigned int value;
2920 unsigned int reg;
2921
2922 port = atoi(argv[3]);
2923 eg_tag = atoi(argv[4]);
2924
2925 printf("port: %d, eg_tag: %d\n", port, eg_tag);
2926
2927 /*Check the input parameters is right or not.*/
2928 if ((port > SWITCH_MAX_PORT) || (eg_tag > REG_PCR_EG_TAG_RELMASK)) {
2929 printf(HELP_VLAN_EGRESS_TAG_PCR);
2930 return;
2931 }
2932
2933 reg = REG_PCR_P0_ADDR + port * 0x100;
2934 reg_read(reg, &value);
2935 value &= (~REG_PCR_EG_TAG_MASK);
2936 value |= ((unsigned int)eg_tag << REG_PCR_EG_TAG_OFFT);
2937
2938 printf("write reg: %x, value: %x\n", reg, value);
2939 reg_write(reg, value);
2940
2941} /*end doVlanSetEgressTagPCR*/
2942
2943void doVlanSetEgressTagPVC(int argc, char *argv[])
2944{
2945 unsigned char port = 0;
2946 unsigned char eg_tag = 0;
2947 unsigned int value;
2948 unsigned int reg;
2949
2950 port = atoi(argv[3]);
2951 eg_tag = atoi(argv[4]);
2952
2953 printf("port: %d, eg_tag: %d\n", port, eg_tag);
2954
2955 /*Check the input parameters is right or not.*/
2956 if ((port > SWITCH_MAX_PORT) || (eg_tag > REG_PVC_EG_TAG_RELMASK)) {
2957 printf(HELP_VLAN_EGRESS_TAG_PVC);
2958 return;
2959 }
2960
2961 reg = REG_PVC_P0_ADDR + port * 0x100;
2962 reg_read(reg, &value);
2963 value &= (~REG_PVC_EG_TAG_MASK);
2964 value |= ((unsigned int)eg_tag << REG_PVC_EG_TAG_OFFT);
2965
2966 printf("write reg: %x, value: %x\n", reg, value);
2967 reg_write(reg, value);
2968} /*end doVlanSetEgressTagPVC*/
2969
2970void doArlAging(int argc, char *argv[])
2971{
2972 unsigned char aging_en = 0;
2973 unsigned int time = 0, aging_cnt = 0, aging_unit = 0, value, reg;
2974 ;
2975
2976 aging_en = atoi(argv[3]);
2977 time = atoi(argv[4]);
2978 printf("aging_en: %x, aging time: %x\n", aging_en, time);
2979
2980 /*Check the input parameters is right or not.*/
2981 if ((aging_en != 0 && aging_en != 1) || (time <= 0 || time > 65536)) {
2982 printf(HELP_ARL_AGING);
2983 return;
2984 }
2985
2986 reg = 0xa0;
2987 reg_read(reg, &value);
2988 value &= (~(1 << 20));
2989 if (!aging_en) {
2990 value |= (1 << 20);
2991 }
2992
2993 aging_unit = (time / 0x100) + 1;
2994 aging_cnt = (time / aging_unit);
2995 aging_unit--;
2996 aging_cnt--;
2997
2998 value &= (0xfff00000);
2999 value |= ((aging_cnt << 12) | aging_unit);
3000
3001 printf("aging_unit: %x, aging_cnt: %x\n", aging_unit, aging_cnt);
3002 printf("write reg: %x, value: %x\n", reg, value);
3003
3004 reg_write(reg, value);
3005}
3006
3007void doMirrorEn(int argc, char *argv[])
3008{
3009 unsigned char mirror_en;
3010 unsigned char mirror_port;
3011 unsigned int value, reg;
3012
3013 mirror_en = atoi(argv[3]);
3014 mirror_port = atoi(argv[4]);
3015
3016 printf("mirror_en: %d, mirror_port: %d\n", mirror_en, mirror_port);
3017
3018 /*Check the input parameters is right or not.*/
3019 if ((mirror_en > 1) || (mirror_port > REG_CFC_MIRROR_PORT_RELMASK)) {
3020 printf(HELP_MIRROR_EN);
3021 return;
3022 }
3023
3024 reg = REG_CFC_ADDR;
3025 reg_read(reg, &value);
3026 value &= (~REG_CFC_MIRROR_EN_MASK);
3027 value |= (mirror_en << REG_CFC_MIRROR_EN_OFFT);
3028 value &= (~REG_CFC_MIRROR_PORT_MASK);
3029 value |= (mirror_port << REG_CFC_MIRROR_PORT_OFFT);
3030
3031 printf("write reg: %x, value: %x\n", reg, value);
3032 reg_write(reg, value);
3033
3034} /*end doMirrorEn*/
3035
3036void doMirrorPortBased(int argc, char *argv[])
3037{
3038 unsigned char port, port_tx_mir, port_rx_mir, vlan_mis, acl_mir, igmp_mir;
3039 unsigned int value, reg;
3040
3041 port = atoi(argv[3]);
3042 port_tx_mir = atoi(argv[4]);
3043 port_rx_mir = atoi(argv[5]);
3044 acl_mir = atoi(argv[6]);
3045 vlan_mis = atoi(argv[7]);
3046 igmp_mir = atoi(argv[8]);
3047
3048 printf("port:%d, port_tx_mir:%d, port_rx_mir:%d, acl_mir:%d, vlan_mis:%d, igmp_mir:%d\n", port, port_tx_mir, port_rx_mir, acl_mir, vlan_mis, igmp_mir);
3049
3050 /*Check the input parameters is right or not.*/
3051 //if((port >= vlanCap->max_port_no) || (port_tx_mir > 1) || (port_rx_mir > 1) || (acl_mir > 1) || (vlan_mis > 1)){
3052 if ((port >= 7) || (port_tx_mir > 1) || (port_rx_mir > 1) || (acl_mir > 1) || (vlan_mis > 1)) { // also allow CPU port (port6)
3053 printf(HELP_MIRROR_PORTBASED);
3054 return;
3055 }
3056
3057 reg = REG_PCR_P0_ADDR + port * 0x100;
3058 reg_read(reg, &value);
3059 value &= ~(REG_PORT_TX_MIR_MASK | REG_PORT_RX_MIR_MASK | REG_PCR_ACL_MIR_MASK | REG_PCR_VLAN_MIS_MASK);
3060 value |= (port_tx_mir << REG_PORT_TX_MIR_OFFT) + (port_rx_mir << REG_PORT_RX_MIR_OFFT);
3061 value |= (acl_mir << REG_PCR_ACL_MIR_OFFT) + (vlan_mis << REG_PCR_VLAN_MIS_OFFT);
3062
3063 printf("write reg: %x, value: %x\n", reg, value);
3064 reg_write(reg, value);
3065
3066 reg = REG_PIC_P0_ADDR + port * 0x100;
3067 reg_read(reg, &value);
3068 value &= ~(REG_PIC_IGMP_MIR_MASK);
3069 value |= (igmp_mir << REG_PIC_IGMP_MIR_OFFT);
3070
3071 printf("write reg: %x, value: %x\n", reg, value);
3072 reg_write(reg, value);
3073
3074} /*end doMirrorPortBased*/
3075
3076void doStp(int argc, char *argv[])
3077{
3078 unsigned char port = 0;
3079 unsigned char fid = 0;
3080 unsigned char state = 0;
3081 unsigned int value;
3082 unsigned int reg;
3083
3084 port = atoi(argv[2]);
3085 fid = atoi(argv[3]);
3086 state = atoi(argv[4]);
3087
3088 printf("port: %d, fid: %d, state: %d\n", port, fid, state);
3089
3090 /*Check the input parameters is right or not.*/
3091 if ((port > MAX_PORT + 1) || (fid > 7) || (state > 3)) {
3092 printf(HELP_STP);
3093 return;
3094 }
3095
3096 reg = REG_SSC_P0_ADDR + port * 0x100;
3097 reg_read(reg, &value);
3098 value &= (~(3 << (fid << 2)));
3099 value |= ((unsigned int)state << (fid << 2));
3100
3101 printf("write reg: %x, value: %x\n", reg, value);
3102 reg_write(reg, value);
3103}
3104
3105int ingress_rate_set(int on_off, unsigned int port, unsigned int bw)
3106{
3107 unsigned int reg, value;
3108
3109 reg = 0x1800 + (0x100 * port);
3110 value = 0;
3111 /*token-bucket*/
3112 if (on_off == 1) {
3113 if (chip_name == 0x7530) {
3114 if (bw > 1000000) {
3115 printf("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",bw);
3116 return -1;
3117 }
3118 value = ((bw / 32) << 16) + (1 << 15) + (7 << 8) + (1 << 7) + 0x0f;
developer8c3871b2022-07-01 14:07:53 +08003119 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3120 if ((chip_name == 0x7531) && (bw > 2500000)) {
developerfd40db22021-04-29 10:08:25 +08003121 printf("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",bw);
3122 return -1;
3123 }
developer8c3871b2022-07-01 14:07:53 +08003124
3125 if ((chip_name == 0x7988) && (bw > 4000000)) {
3126 printf("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",bw);
3127 return -1;
developerfd40db22021-04-29 10:08:25 +08003128 }
developer8c3871b2022-07-01 14:07:53 +08003129
3130 if (bw/32 >= 65536) //supoort 2.5G case
3131 value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (1 << 12) + (7 << 8) + 0xf;
3132 else
3133 value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (7 << 8) + 0xf;
3134 }
developerfd40db22021-04-29 10:08:25 +08003135 else
3136 printf("unknow chip\n");
3137 }
3138
3139#if leaky_bucket
3140 reg_read(reg, &value);
3141 value &= 0xffff0000;
3142 if (on_off == 1)
3143 {
3144 value |= on_off << 15;
3145 //7530 same as 7531
3146 if (bw < 100) {
3147 value |= (0x0 << 8);
3148 value |= bw;
3149 } else if (bw < 1000) {
3150 value |= (0x1 << 8);
3151 value |= bw / 10;
3152 } else if (bw < 10000) {
3153 value |= (0x2 << 8);
3154 value |= bw / 100;
3155 } else if (bw < 100000) {
3156 value |= (0x3 << 8);
3157 value |= bw / 1000;
3158 } else {
3159 value |= (0x4 << 8);
3160 value |= bw / 10000;
3161 }
3162 }
3163#endif
3164 reg_write(reg, value);
3165 reg = 0x1FFC;
3166 reg_read(reg, &value);
3167 value = 0x110104;
3168 reg_write(reg, value);
3169 return 0;
3170}
3171
3172int egress_rate_set(int on_off, int port, int bw)
3173{
3174 unsigned int reg, value;
3175
3176 reg = 0x1040 + (0x100 * port);
3177 value = 0;
3178 /*token-bucket*/
3179 if (on_off == 1) {
3180 if (chip_name == 0x7530) {
3181 if (bw < 0 || bw > 1000000) {
3182 printf("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",bw);
3183 return -1;
3184 }
3185 value = ((bw / 32) << 16) + (1 << 15) + (7 << 8) + (1 << 7) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003186 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3187 if ((chip_name == 0x7531) && (bw < 0 || bw > 2500000)) {
developerfd40db22021-04-29 10:08:25 +08003188 printf("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",bw);
3189 return -1;
3190 }
developer8c3871b2022-07-01 14:07:53 +08003191 if ((chip_name == 0x7988) && (bw < 0 || bw > 4000000)) {
3192 printf("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",bw);
3193 return -1;
3194 }
3195
3196 if (bw/32 >= 65536) //support 2.5G cases
3197 value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (1 << 12) + (7 << 8) + 0xf;
3198 else
3199 value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (7 << 8) + 0xf;
developerfd40db22021-04-29 10:08:25 +08003200 }
3201 else
3202 printf("unknow chip\n");
3203 }
3204 reg_write(reg, value);
3205 reg = 0x10E0;
3206 reg_read(reg, &value);
3207 value &= 0x18;
3208 reg_write(reg, value);
3209
3210 return 0;
3211}
3212
3213void rate_control(int argc, char *argv[])
3214{
3215 unsigned char dir = 0;
3216 unsigned char port = 0;
3217 unsigned int rate = 0;
3218
3219 dir = atoi(argv[2]);
3220 port = atoi(argv[3]);
3221 rate = atoi(argv[4]);
3222
3223 if (port > 6)
3224 return;
3225
3226 if (dir == 1) //ingress
3227 ingress_rate_set(1, port, rate);
3228 else if (dir == 0) //egress
3229 egress_rate_set(1, port, rate);
3230 else
3231 return;
3232}
3233
3234int collision_pool_enable(int argc, char *argv[])
3235{
3236
3237 unsigned char enable;
3238 unsigned int value, reg;
3239
3240 enable = atoi(argv[3]);
3241
3242
3243 printf("collision pool enable: %d \n", enable);
3244
3245 /*Check the input parameters is right or not.*/
3246 if (enable > 1) {
3247 printf(HELP_COLLISION_POOL_EN);
3248 return -1;
3249 }
3250
developer8c3871b2022-07-01 14:07:53 +08003251 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003252 reg = REG_CPGC_ADDR;
3253 if(enable == 1) {
3254 /* active reset */
3255 reg_read(reg, &value);
3256 value &= (~REG_CPCG_COL_RST_N_MASK);
3257 reg_write(reg, value);
3258
3259 /* enanble clock */
3260 reg_read(reg, &value);
3261 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3262 value |= (1 << REG_CPCG_COL_CLK_EN_OFFT);
3263 reg_write(reg, value);
3264
3265 /* inactive reset */
3266 reg_read(reg, &value);
3267 value &= (~REG_CPCG_COL_RST_N_MASK);
3268 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3269 reg_write(reg, value);
3270
3271 /* enable collision pool */
3272 reg_read(reg, &value);
3273 value &= (~REG_CPCG_COL_EN_MASK);
3274 value |= (1 << REG_CPCG_COL_EN_OFFT);
3275 reg_write(reg, value);
3276
3277 reg_read(reg, &value);
3278 printf("write reg: %x, value: %x\n", reg, value);
3279 }else {
3280
3281 /* disable collision pool */
3282 reg_read(reg, &value);
3283 value &= (~REG_CPCG_COL_EN_MASK);
3284 reg_write(reg, value);
3285
3286 /* active reset */
3287 reg_read(reg, &value);
3288 value &= (~REG_CPCG_COL_RST_N_MASK);
3289 reg_write(reg, value);
3290
3291 /* inactive reset */
3292 reg_read(reg, &value);
3293 value &= (~REG_CPCG_COL_RST_N_MASK);
3294 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3295 reg_write(reg, value);
3296
3297 /* disable clock */
3298 reg_read(reg, &value);
3299 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3300 reg_write(reg, value);
3301
3302 reg_read(reg, &value);
3303 printf("write reg: %x, value: %x\n", reg, value);
3304
3305 }
3306 }else{
3307 printf("\nCommand not support by this chip.\n");
3308}
3309
3310 return 0;
3311}
3312
3313void collision_pool_mac_dump()
3314{
3315 unsigned int value, reg;
3316
developer8c3871b2022-07-01 14:07:53 +08003317 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003318 reg = REG_CPGC_ADDR;
3319 reg_read(reg, &value);
3320 if(value & REG_CPCG_COL_EN_MASK)
3321 table_dump_internal(COLLISION_TABLE);
3322 else
3323 printf("\ncollision pool is disabled, please enable it before use this command.\n");
3324 }else {
3325 printf("\nCommand not support by this chip.\n");
3326 }
3327}
3328
3329void collision_pool_dip_dump()
3330{
3331 unsigned int value, reg;
3332
developer8c3871b2022-07-01 14:07:53 +08003333 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003334 reg = REG_CPGC_ADDR;
3335 reg_read(reg, &value);
3336 if(value & REG_CPCG_COL_EN_MASK)
3337 dip_dump_internal(COLLISION_TABLE);
3338 else
3339 printf("\ncollision pool is disabled, please enable it before use this command.\n");
3340 }else {
3341 printf("\nCommand not support by this chip.\n");
3342 }
3343
3344
3345}
3346
3347void collision_pool_sip_dump()
3348{
3349 unsigned int value, reg;
3350
developer8c3871b2022-07-01 14:07:53 +08003351 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003352 reg = REG_CPGC_ADDR;
3353 reg_read(reg, &value);
3354 if(value & REG_CPCG_COL_EN_MASK)
3355 sip_dump_internal(COLLISION_TABLE);
3356 else
3357 printf("\ncollision pool is disabled, please enable it before use this command.\n");
3358 }else {
3359 printf("\nCommand not support by this chip.\n");
3360 }
3361
3362
3363}
3364
3365void pfc_get_rx_counter(int argc, char *argv[])
3366{
3367 int port;
3368 unsigned int value, reg;
3369 unsigned int user_pri;
3370
3371 port = strtoul(argv[3], NULL, 0);
3372 if (port < 0 || 6 < port) {
3373 printf("wrong port range, should be within 0~6\n");
3374 return;
3375 }
3376
developer8c3871b2022-07-01 14:07:53 +08003377 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003378 reg= PFC_RX_COUNTER_L(port);
3379 reg_read(reg, &value);
3380 user_pri = value & 0xff;
3381 printf("\n port %d rx pfc (up=0)pause on counter is %d.\n", port,user_pri);
3382 user_pri = (value & 0xff00) >> 8;
3383 printf("\n port %d rx pfc (up=1)pause on counter is %d.\n", port,user_pri);
3384 user_pri = (value & 0xff0000) >> 16;
3385 printf("\n port %d rx pfc (up=2)pause on counter is %d.\n", port,user_pri);
3386 user_pri = (value & 0xff000000) >> 24;
3387 printf("\n port %d rx pfc (up=3)pause on counter is %d.\n", port,user_pri);
3388
3389 reg= PFC_RX_COUNTER_H(port);
3390 reg_read(reg, &value);
3391 user_pri = value & 0xff;
3392 printf("\n port %d rx pfc (up=4)pause on counter is %d.\n", port,user_pri);
3393 user_pri = (value & 0xff00) >> 8;
3394 printf("\n port %d rx pfc (up=5)pause on counter is %d.\n", port,user_pri);
3395 user_pri = (value & 0xff0000) >> 16;
3396 printf("\n port %d rx pfc (up=6)pause on counter is %d.\n", port,user_pri);
3397 user_pri = (value & 0xff000000) >> 24;
3398 printf("\n port %d rx pfc (up=7)pause on counter is %d.\n", port,user_pri);
3399
3400 /* for rx counter could be updated successfully */
3401 reg_read(PMSR_P(port), &value);
3402 reg_read(PMSR_P(port), &value);
3403 }else {
3404 printf("\nCommand not support by this chip.\n");
3405 }
3406
3407}
3408
3409void pfc_get_tx_counter(int argc, char *argv[])
3410{
3411 int port;
3412 unsigned int value, reg;
3413 unsigned int user_pri;
3414
3415 port = strtoul(argv[3], NULL, 0);
3416 if (port < 0 || 6 < port) {
3417 printf("wrong port range, should be within 0~6\n");
3418 return;
3419 }
3420
developer8c3871b2022-07-01 14:07:53 +08003421 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003422 reg= PFC_TX_COUNTER_L(port);
3423 reg_read(reg, &value);
3424 user_pri = value & 0xff;
3425 printf("\n port %d tx pfc (up=0)pause on counter is %d.\n", port,user_pri);
3426 user_pri = (value & 0xff00) >> 8;
3427 printf("\n port %d tx pfc (up=1)pause on counter is %d.\n", port,user_pri);
3428 user_pri = (value & 0xff0000) >> 16;
3429 printf("\n port %d tx pfc (up=2)pause on counter is %d.\n", port,user_pri);
3430 user_pri = (value & 0xff000000) >> 24;
3431 printf("\n port %d tx pfc (up=3)pause on counter is %d.\n", port,user_pri);
3432
3433 reg= PFC_TX_COUNTER_H(port);
3434 reg_read(reg, &value);
3435 user_pri = value & 0xff;
3436 printf("\n port %d tx pfc (up=4)pause on counter is %d.\n", port,user_pri);
3437 user_pri = (value & 0xff00) >> 8;
3438 printf("\n port %d tx pfc (up=5)pause on counter is %d.\n", port,user_pri);
3439 user_pri = (value & 0xff0000) >> 16;
3440 printf("\n port %d tx pfc (up=6)pause on counter is %d.\n", port,user_pri);
3441 user_pri = (value & 0xff000000) >> 24;
3442 printf("\n port %d tx pfc (up=7)pause on counter is %d.\n", port,user_pri);
3443
3444 /* for tx counter could be updated successfully */
3445 reg_read(PMSR_P(port), &value);
3446 reg_read(PMSR_P(port), &value);
3447 }else {
3448 printf("\nCommand not support by this chip.\n");
3449 }
3450}
3451
3452void read_output_queue_counters()
3453{
3454 unsigned int port=0;
3455 unsigned int value, output_queue;
3456 unsigned int base=0x220;
3457
3458 for (port = 0; port < 7; port++) {
3459 reg_write(0x7038, base + (port *4));
3460 reg_read(0x7034, &value);
3461 output_queue = value & 0xff;
3462 printf("\n port %d output queue 0 counter is %d.\n", port,output_queue);
3463 output_queue = (value & 0xff00) >> 8;
3464 printf("\n port %d output queue 1 counter is %d.\n", port,output_queue);
3465
3466 reg_write(0x7038, base + (port *4) + 1);
3467 reg_read(0x7034, &value);
3468 output_queue = value & 0xff;
3469 printf("\n port %d output queue 2 counter is %d.\n", port,output_queue);
3470 output_queue = (value & 0xff00) >> 8;
3471 printf("\n port %d output queue 3 counter is %d.\n", port,output_queue);
3472
3473 reg_write(0x7038, base + (port *4) + 2);
3474 reg_read(0x7034, &value);
3475 output_queue = value & 0xff;
3476 printf("\n port %d output queue 4 counter is %d.\n", port,output_queue);
3477 output_queue = (value & 0xff00) >> 8;
3478 printf("\n port %d output queue 5 counter is %d.\n", port,output_queue);
3479
3480 reg_write(0x7038, base + (port *4) + 3);
3481 reg_read(0x7034, &value);
3482 output_queue = value & 0xff;
3483 printf("\n port %d output queue 6 counter is %d.\n", port,output_queue);
3484 output_queue = (value & 0xff00) >> 8;
3485 printf("\n port %d output queue 7 counter is %d.\n", port,output_queue);
3486 }
3487}
3488
3489void read_free_page_counters()
3490{
3491 unsigned int value;
3492 unsigned int free_page,free_page_last_read;
3493 unsigned int fc_free_blk_lothd,fc_free_blk_hithd;
3494 unsigned int fc_port_blk_thd,fc_port_blk_hi_thd;
3495 unsigned int queue[8]={0};
3496
developer8c3871b2022-07-01 14:07:53 +08003497 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003498 /* get system free page link counter*/
3499 reg_read(0x1fc0, &value);
3500 free_page = value & 0xFFF;
3501 free_page_last_read = (value & 0xFFF0000) >> 16;
3502
3503 /* get system flow control waterwark */
3504 reg_read(0x1fe0, &value);
3505 fc_free_blk_lothd = value & 0x3FF;
3506 fc_free_blk_hithd = (value & 0x3FF0000) >> 16;
3507
3508 /* get port flow control waterwark */
3509 reg_read(0x1fe4, &value);
3510 fc_port_blk_thd = value & 0x3FF;
3511 fc_port_blk_hi_thd = (value & 0x3FF0000) >> 16;
3512
3513 /* get queue flow control waterwark */
3514 reg_read(0x1fe8, &value);
3515 queue[0]= value & 0x3F;
3516 queue[1]= (value & 0x3F00) >> 8;
3517 queue[2]= (value & 0x3F0000) >> 16;
3518 queue[3]= (value & 0x3F000000) >> 24;
3519 reg_read(0x1fec, &value);
3520 queue[4]= value & 0x3F;
3521 queue[5]= (value & 0x3F00) >> 8;
3522 queue[6]= (value & 0x3F0000) >> 16;
3523 queue[7]= (value & 0x3F000000) >> 24;
3524 } else {
3525 /* get system free page link counter*/
3526 reg_read(0x1fc0, &value);
3527 free_page = value & 0x3FF;
3528 free_page_last_read = (value & 0x3FF0000) >> 16;
3529
3530 /* get system flow control waterwark */
3531 reg_read(0x1fe0, &value);
3532 fc_free_blk_lothd = value & 0xFF;
3533 fc_free_blk_hithd = (value & 0xFF00) >> 8;
3534
3535 /* get port flow control waterwark */
3536 reg_read(0x1fe0, &value);
3537 fc_port_blk_thd = (value & 0xFF0000) >> 16;
3538 reg_read(0x1ff4, &value);
3539 fc_port_blk_hi_thd = (value & 0xFF00) >> 8;
3540
3541 /* get queue flow control waterwark */
3542 reg_read(0x1fe4, &value);
3543 queue[0]= value & 0xF;
3544 queue[1]= (value & 0xF0) >> 4;
3545 queue[2]= (value & 0xF00) >> 8;
3546 queue[3]= (value & 0xF000) >>12;
3547 queue[4]= (value & 0xF0000) >>16;
3548 queue[5]= (value & 0xF00000) >> 20;
3549 queue[6]= (value & 0xF000000) >> 24;
3550 queue[7]= (value & 0xF0000000) >> 28;
3551 }
3552
3553 printf("<===Free Page=======Current=======Last Read access=====> \n ");
3554 printf(" \n ");
3555 printf(" page counter %u %u \n ",free_page,free_page_last_read);
3556 printf(" \n ");
3557 printf("========================================================= \n ");
3558 printf("<===Type=======High threshold======Low threshold=========\n ");
3559 printf(" \n ");
3560 printf(" system: %u %u \n", fc_free_blk_hithd*2, fc_free_blk_lothd*2);
3561 printf(" port: %u %u \n", fc_port_blk_hi_thd*2, fc_port_blk_thd*2);
3562 printf(" queue 0: %u NA \n", queue[0]);
3563 printf(" queue 1: %u NA \n", queue[1]);
3564 printf(" queue 2: %u NA \n", queue[2]);
3565 printf(" queue 3: %u NA \n", queue[3]);
3566 printf(" queue 4: %u NA \n", queue[4]);
3567 printf(" queue 5: %u NA \n", queue[5]);
3568 printf(" queue 6: %u NA \n", queue[6]);
3569 printf(" queue 7: %u NA \n", queue[7]);
3570 printf("=========================================================\n ");
3571}
3572
3573void eee_enable(int argc, char *argv[])
3574{
3575 unsigned long enable;
3576 unsigned int value;
3577 unsigned int eee_cap;
3578 unsigned int eee_en_bitmap = 0;
3579 unsigned long port_map;
3580 long port_num = -1;
3581 int p;
3582
3583 if (argc < 3)
3584 goto error;
3585
3586 /*Check the input parameters is right or not.*/
3587 if (!strncmp(argv[2], "enable", 7))
3588 enable = 1;
3589 else if (!strncmp(argv[2], "disable", 8))
3590 enable = 0;
3591 else
3592 goto error;
3593
3594 if (argc > 3) {
3595 if (strlen(argv[3]) == 1) {
3596 port_num = strtol(argv[3], (char **)NULL, 10);
3597 if (port_num < 0 || port_num > MAX_PHY_PORT - 1) {
3598 printf("Illegal port index and port:0~4\n");
3599 goto error;
3600 }
3601 port_map = 1 << port_num;
3602 } else if (strlen(argv[3]) == 5) {
3603 port_map = 0;
3604 for (p = 0; p < MAX_PHY_PORT; p++) {
3605 if (argv[3][p] != '0' && argv[3][p] != '1') {
3606 printf("portmap format error, should be combination of 0 or 1\n");
3607 goto error;
3608 }
3609 port_map |= ((argv[3][p] - '0') << p);
3610 }
3611 } else {
3612 printf("port_no or portmap format error, should be length of 1 or 5\n");
3613 goto error;
3614 }
3615 } else {
3616 port_map = 0x1f;
3617 }
3618
3619 eee_cap = (enable)? 6: 0;
3620 for (p = 0; p < MAX_PHY_PORT; p++) {
3621 /* port_map describe p0p1p2p3p4 from left to rignt */
3622 if(!!(port_map & (1 << p)))
3623 mii_mgr_c45_write(p, 0x7, 0x3c, eee_cap);
3624
3625 mii_mgr_c45_read(p, 0x7, 0x3c, &value);
3626 /* mt7531: Always readback eee_cap = 0 when global EEE switch
3627 * is turned off.
3628 */
3629 if (value | eee_cap)
3630 eee_en_bitmap |= (1 << (MAX_PHY_PORT - 1 - p));
3631 }
3632
3633 /* Turn on/off global EEE switch */
developer8c3871b2022-07-01 14:07:53 +08003634 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003635 mii_mgr_c45_read(0, 0x1f, 0x403, &value);
3636 if (eee_en_bitmap)
3637 value |= (1 << 6);
3638 else
3639 value &= ~(1 << 6);
3640 mii_mgr_c45_write(0, 0x1f, 0x403, value);
3641 } else {
3642 printf("\nCommand not support by this chip.\n");
3643 }
3644
3645 printf("EEE(802.3az) %s", (enable)? "enable": "disable");
3646 if (argc == 4) {
3647 if (port_num >= 0)
3648 printf(" port%ld", port_num);
3649 else
3650 printf(" port_map: %s", argv[3]);
3651 } else {
3652 printf(" all ports");
3653 }
3654 printf("\n");
3655
3656 return;
3657error:
3658 printf(HELP_EEE_EN);
3659 return;
3660}
3661
3662void eee_dump(int argc, char *argv[])
3663{
3664 unsigned int cap, lp_cap;
3665 long port = -1;
3666 int p;
3667
3668 if (argc > 3) {
3669 if (strlen(argv[3]) > 1) {
3670 printf("port# format error, should be of length 1\n");
3671 return;
3672 }
3673
3674 port = strtol(argv[3], (char **)NULL, 0);
3675 if (port < 0 || port > MAX_PHY_PORT) {
3676 printf("port# format error, should be 0 to %d\n",
3677 MAX_PHY_PORT);
3678 return;
3679 }
3680 }
3681
3682 for (p = 0; p < MAX_PHY_PORT; p++) {
3683 if (port >= 0 && p != port)
3684 continue;
3685
3686 mii_mgr_c45_read(p, 0x7, 0x3c, &cap);
3687 mii_mgr_c45_read(p, 0x7, 0x3d, &lp_cap);
3688 printf("port%d EEE cap=0x%02x, link partner EEE cap=0x%02x",
3689 p, cap, lp_cap);
3690
3691 if (port >= 0 && p == port) {
3692 mii_mgr_c45_read(p, 0x3, 0x1, &cap);
3693 printf(", st=0x%03x", cap);
3694 }
3695 printf("\n");
3696 }
3697}
3698
3699void dump_each_port(unsigned int base)
3700{
3701 unsigned int pkt_cnt = 0;
3702 int i = 0;
3703
3704 for (i = 0; i < 7; i++) {
3705 reg_read((base) + (i * 0x100), &pkt_cnt);
3706 printf("%8u ", pkt_cnt);
3707 }
3708 printf("\n");
3709}
3710
3711void read_mib_counters()
3712{
3713 printf("===================== %8s %8s %8s %8s %8s %8s %8s\n",
3714 "Port0", "Port1", "Port2", "Port3", "Port4", "Port5", "Port6");
3715 printf("Tx Drop Packet :");
3716 dump_each_port(0x4000);
3717 printf("Tx CRC Error :");
3718 dump_each_port(0x4004);
3719 printf("Tx Unicast Packet :");
3720 dump_each_port(0x4008);
3721 printf("Tx Multicast Packet :");
3722 dump_each_port(0x400C);
3723 printf("Tx Broadcast Packet :");
3724 dump_each_port(0x4010);
3725 printf("Tx Collision Event :");
3726 dump_each_port(0x4014);
3727 printf("Tx Pause Packet :");
3728 dump_each_port(0x402C);
3729 printf("Rx Drop Packet :");
3730 dump_each_port(0x4060);
3731 printf("Rx Filtering Packet :");
3732 dump_each_port(0x4064);
3733 printf("Rx Unicast Packet :");
3734 dump_each_port(0x4068);
3735 printf("Rx Multicast Packet :");
3736 dump_each_port(0x406C);
3737 printf("Rx Broadcast Packet :");
3738 dump_each_port(0x4070);
3739 printf("Rx Alignment Error :");
3740 dump_each_port(0x4074);
3741 printf("Rx CRC Error :");
3742 dump_each_port(0x4078);
3743 printf("Rx Undersize Error :");
3744 dump_each_port(0x407C);
3745 printf("Rx Fragment Error :");
3746 dump_each_port(0x4080);
3747 printf("Rx Oversize Error :");
3748 dump_each_port(0x4084);
3749 printf("Rx Jabber Error :");
3750 dump_each_port(0x4088);
3751 printf("Rx Pause Packet :");
3752 dump_each_port(0x408C);
3753}
3754
3755void clear_mib_counters()
3756{
3757 reg_write(0x4fe0, 0xf0);
3758 read_mib_counters();
3759 reg_write(0x4fe0, 0x800000f0);
3760}
3761
3762
3763void exit_free()
3764{
3765 free(attres);
3766 attres = NULL;
3767 switch_ioctl_fini();
3768 mt753x_netlink_free();
3769}