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