blob: aefb927d2376ec7cd140a09bc194b716be9976ff [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001/*
2* switch_fun.c: switch function sets
3*/
4#include <stdio.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <string.h>
8#include <stdbool.h>
9#include <sys/ioctl.h>
10#include <sys/socket.h>
11#include <linux/if.h>
12#include <stdbool.h>
13#include <time.h>
14
15#include "switch_extend.h"
16#include "switch_netlink.h"
17#include "switch_ioctl.h"
18#include "switch_fun.h"
19
20#define leaky_bucket 0
21
22static int getnext(char *src, int separator, char *dest)
23{
24 char *c;
25 int len;
26
27 if ((src == NULL) || (dest == NULL))
28 return -1;
29
30 c = strchr(src, separator);
31 if (c == NULL)
32 return -1;
33
34 len = c - src;
35 strncpy(dest, src, len);
36 dest[len] = '\0';
37 return len + 1;
38}
39
40static int str_to_ip(unsigned int *ip, char *str)
41{
42 int i;
43 int len;
44 char *ptr = str;
45 char buf[128];
46 unsigned char c[4];
47
48 for (i = 0; i < 3; ++i) {
49 if ((len = getnext(ptr, '.', buf)) == -1)
50 return 1;
51 c[i] = atoi(buf);
52 ptr += len;
53 }
54 c[3] = atoi(ptr);
55 *ip = (c[0] << 24) + (c[1] << 16) + (c[2] << 8) + c[3];
56 return 0;
57}
58
59/*convert IP address from number to string */
60static void ip_to_str(char *str, unsigned int ip)
61{
62 unsigned char *ptr = (unsigned char *)&ip;
63 unsigned char c[4];
64
65 c[0] = *(ptr);
66 c[1] = *(ptr + 1);
67 c[2] = *(ptr + 2);
68 c[3] = *(ptr + 3);
69 /*sprintf(str, "%d.%d.%d.%d", c[0], c[1], c[2], c[3]);*/
70 sprintf(str, "%d.%d.%d.%d", c[3], c[2], c[1], c[0]);
71}
72
73int reg_read(unsigned int offset, unsigned int *value)
74{
75 int ret = -1;
76
77 if (nl_init_flag == true) {
78 ret = reg_read_netlink(attres, offset, value);
79 } else {
80 if (attres->dev_id == -1)
81 ret = reg_read_ioctl(offset, value);
82 }
83 if (ret < 0) {
84 printf("Read fail\n");
85 *value = 0;
86 return ret;
87 }
88
89 return 0;
90}
91
92int reg_write(unsigned int offset, unsigned int value)
93{
94 int ret = -1;
95
96 if (nl_init_flag == true) {
97 ret = reg_write_netlink(attres, offset, value);
98 } else {
99 if (attres->dev_id == -1)
100 ret = reg_write_ioctl(offset, value);
101 }
102 if (ret < 0) {
103 printf("Write fail\n");
104 exit_free();
105 exit(0);
106 }
107 return 0;
108}
109
110int mii_mgr_read(unsigned int port_num, unsigned int reg, unsigned int *value)
111{
112 int ret;
113
114 if (port_num > 31) {
115 printf("Invalid Port or PHY addr \n");
116 return -1;
117 }
118
119 if (nl_init_flag == true)
120 ret = phy_cl22_read_netlink(attres, port_num, reg, value);
121 else
122 ret = mii_mgr_cl22_read_ioctl(port_num, reg, value);
123
124 if (ret < 0) {
125 printf("Phy read fail\n");
126 exit_free();
127 exit(0);
128 }
129
130 return 0;
131}
132
133int mii_mgr_write(unsigned int port_num, unsigned int reg, unsigned int value)
134{
135 int ret;
136
137 if (port_num > 31) {
138 printf("Invalid Port or PHY addr \n");
139 return -1;
140 }
141
142 if (nl_init_flag == true)
143 ret = phy_cl22_write_netlink(attres, port_num, reg, value);
144 else
145 ret = mii_mgr_cl22_write_ioctl(port_num, reg, value);
146
147 if (ret < 0) {
148 printf("Phy write fail\n");
149 exit_free();
150 exit(0);
151 }
152
153 return 0;
154}
155
156int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int *value)
157{
158 int ret;
159
160 if (port_num > 31) {
161 printf("Invalid Port or PHY addr \n");
162 return -1;
163 }
164
165 if (nl_init_flag == true)
166 ret = phy_cl45_read_netlink(attres, port_num, dev, reg, value);
167 else
168 ret = mii_mgr_cl45_read_ioctl(port_num, dev, reg, value);
169
170 if (ret < 0) {
171 printf("Phy read fail\n");
172 exit_free();
173 exit(0);
174 }
175
176 return 0;
177}
178
179int mii_mgr_c45_write(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int value)
180{
181 int ret;
182
183 if (port_num > 31) {
184 printf("Invalid Port or PHY addr \n");
185 return -1;
186 }
187
188 if (nl_init_flag == true)
189 ret = phy_cl45_write_netlink(attres, port_num, dev, reg, value);
190 else
191 ret = mii_mgr_cl45_write_ioctl(port_num, dev, reg, value);
192
193 if (ret < 0) {
194 printf("Phy write fail\n");
195 exit_free();
196 exit(0);
197 }
198
199 return 0;
200}
201
202
203int phy_dump(int phy_addr)
204{
205 int ret;
206
207 if (nl_init_flag == true)
208 ret = phy_dump_netlink(attres, phy_addr);
209 else
210 ret = phy_dump_ioctl(phy_addr);
211
212 if (ret < 0) {
213 printf("Phy dump fail\n");
214 exit_free();
215 exit(0);
216 }
217
218 return 0;
219}
220
221void phy_crossover(int argc, char *argv[])
222{
223 unsigned int port_num = strtoul(argv[2], NULL, 10);
224 unsigned int value;
225 int ret;
226
227 if (port_num > 4) {
228 printf("invaild value, port_name:0~4\n");
229 return;
230 }
231
232 if (nl_init_flag == true)
233 ret = phy_cl45_read_netlink(attres, port_num, 0x1E, MT7530_T10_TEST_CONTROL, &value);
234 else
235 ret = mii_mgr_cl45_read_ioctl(port_num, 0x1E, MT7530_T10_TEST_CONTROL, &value);
236 if (ret < 0) {
237 printf("phy_cl45 read fail\n");
238 exit_free();
239 exit(0);
240 }
241
242 printf("mii_mgr_cl45:");
243 printf("Read: port#=%d, device=0x%x, reg=0x%x, value=0x%x\n", port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
244
245 if (!strncmp(argv[3], "auto", 5))
246 {
247 value &= (~(0x3 << 3));
248 } else if (!strncmp(argv[3], "mdi", 4)) {
249 value &= (~(0x3 << 3));
250 value |= (0x2 << 3);
251 } else if (!strncmp(argv[3], "mdix", 5)) {
252 value |= (0x3 << 3);
253 } else {
254 printf("invaild parameter\n");
255 return;
256 }
257 printf("Write: port#=%d, device=0x%x, reg=0x%x. value=0x%x\n", port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
258
259 if (nl_init_flag == true)
260 ret = phy_cl45_write_netlink(attres, port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
261 else
262 ret = mii_mgr_cl45_write_ioctl(port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
263
264 if (ret < 0) {
265 printf("phy_cl45 write fail\n");
266 exit_free();
267 exit(0);
268 }
269}
270
271int rw_phy_token_ring(int argc, char *argv[])
272{
273 int ch_addr, node_addr, data_addr;
274 unsigned int tr_reg_control;
275 unsigned int val_l = 0;
276 unsigned int val_h = 0;
277 unsigned int port_num;
278
279 if (argc < 4)
280 return -1;
281
282 if (argv[2][0] == 'r') {
283 if (argc != 7)
284 return -1;
285 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
286 port_num = strtoul(argv[3], NULL, 0);
287 if (port_num > MAX_PORT) {
288 printf("Illegal port index and port:0~6\n");
289 return -1;
290 }
291 ch_addr = strtoul(argv[4], NULL, 0);
292 node_addr = strtoul(argv[5], NULL, 0);
293 data_addr = strtoul(argv[6], NULL, 0);
294 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n", port_num, ch_addr, node_addr, data_addr);
295 tr_reg_control = (1 << 15) | (1 << 13) | (ch_addr << 11) | (node_addr << 7) | (data_addr << 1);
296 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
297 mii_mgr_read(port_num, 17, &val_l);
298 mii_mgr_read(port_num, 18, &val_h);
299 printf("switch trreg read tr_reg_control=%x, value_H=%x, value_L=%x\n", tr_reg_control, val_h, val_l);
300 } else if (argv[2][0] == 'w') {
301 if (argc != 9)
302 return -1;
303 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
304 port_num = strtoul(argv[3], NULL, 0);
305 if (port_num > MAX_PORT) {
306 printf("\n**Illegal port index and port:0~6\n");
307 return -1;
308 }
309 ch_addr = strtoul(argv[4], NULL, 0);
310 node_addr = strtoul(argv[5], NULL, 0);
311 data_addr = strtoul(argv[6], NULL, 0);
312 val_h = strtoul(argv[7], NULL, 0);
313 val_l = strtoul(argv[8], NULL, 0);
314 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n", port_num, ch_addr, node_addr, data_addr);
315 tr_reg_control = (1 << 15) | (0 << 13) | (ch_addr << 11) | (node_addr << 7) | (data_addr << 1);
316 mii_mgr_write(port_num, 17, val_l);
317 mii_mgr_write(port_num, 18, val_h);
318 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
319 printf("switch trreg Write tr_reg_control=%x, value_H=%x, value_L=%x\n", tr_reg_control, val_h, val_l);
320 } else
321 return -1;
322 return 0;
323}
324
325void write_acl_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2)
326{
327 unsigned int value, reg;
328 unsigned int max_index;
329
330 if (chip_name == 0x7531)
331 max_index = 256;
332 else
333 max_index = 64;
334
335 printf("Pattern_acl_tbl_idx:%d\n", tbl_idx);
336
337 if (tbl_idx >= max_index) {
338 printf(HELP_ACL_ACL_TBL_ADD);
339 return;
340 }
341
342 reg = REG_VTCR_ADDR;
343 while (1)
344 { // wait until not busy
345 reg_read(reg, &value);
346 if ((value & REG_VTCR_BUSY_MASK) == 0) {
347 break;
348 }
349 }
350 reg_write(REG_VAWD1_ADDR, vawd1);
351 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
352 reg_write(REG_VAWD2_ADDR, vawd2);
353 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
354 reg = REG_VTCR_ADDR;
355 value = REG_VTCR_BUSY_MASK | (0x05 << REG_VTCR_FUNC_OFFT) | tbl_idx;
356 reg_write(reg, value);
357 printf("write reg: %x, value: %x\n", reg, value);
358
359 while (1)
360 { // wait until not busy
361 reg_read(reg, &value);
362 if ((value & REG_VTCR_BUSY_MASK) == 0)
363 break;
364 }
365}
366
367void acl_table_add(int argc, char *argv[])
368{
369 unsigned int vawd1, vawd2;
370 unsigned char tbl_idx;
371
372 tbl_idx = atoi(argv[3]);
373 vawd1 = strtoul(argv[4], (char **)NULL, 16);
374 vawd2 = strtoul(argv[5], (char **)NULL, 16);
375 write_acl_table(tbl_idx, vawd1, vawd2);
376}
377
378void write_acl_mask_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2)
379{
380 unsigned int value, reg;
381 unsigned int max_index;
382
383 if (chip_name == 0x7531)
384 max_index = 128;
385 else
386 max_index = 32;
387
388 printf("Rule_mask_tbl_idx:%d\n", tbl_idx);
389
390 if (tbl_idx >= max_index) {
391 printf(HELP_ACL_MASK_TBL_ADD);
392 return;
393 }
394 reg = REG_VTCR_ADDR;
395 while (1)
396 { // wait until not busy
397 reg_read(reg, &value);
398 if ((value & REG_VTCR_BUSY_MASK) == 0)
399 break;
400 }
401 reg_write(REG_VAWD1_ADDR, vawd1);
402 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
403 reg_write(REG_VAWD2_ADDR, vawd2);
404 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
405 reg = REG_VTCR_ADDR;
406 value = REG_VTCR_BUSY_MASK | (0x09 << REG_VTCR_FUNC_OFFT) | tbl_idx;
407 reg_write(reg, value);
408 printf("write reg: %x, value: %x\n", reg, value);
409 while (1)
410 { // wait until not busy
411 reg_read(reg, &value);
412 if ((value & REG_VTCR_BUSY_MASK) == 0)
413 break;
414 }
415}
416
417void acl_mask_table_add(int argc, char *argv[])
418{
419 unsigned int vawd1, vawd2;
420 unsigned char tbl_idx;
421
422 tbl_idx = atoi(argv[3]);
423 vawd1 = strtoul(argv[4], (char **)NULL, 16);
424 vawd2 = strtoul(argv[5], (char **)NULL, 16);
425 write_acl_mask_table(tbl_idx, vawd1, vawd2);
426}
427
428void write_acl_rule_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2)
429{
430 unsigned int value, reg;
431 unsigned int max_index;
432
433 if (chip_name == 0x7531)
434 max_index = 128;
435 else
436 max_index = 32;
437
438 printf("Rule_control_tbl_idx:%d\n", tbl_idx);
439
440 if (tbl_idx >= max_index) { /*Check the input parameters is right or not.*/
441 printf(HELP_ACL_RULE_TBL_ADD);
442 return;
443 }
444 reg = REG_VTCR_ADDR;
445
446 while (1)
447 { // wait until not busy
448 reg_read(reg, &value);
449 if ((value & REG_VTCR_BUSY_MASK) == 0) {
450 break;
451 }
452 }
453 reg_write(REG_VAWD1_ADDR, vawd1);
454 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
455 reg_write(REG_VAWD2_ADDR, vawd2);
456 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
457 reg = REG_VTCR_ADDR;
458 value = REG_VTCR_BUSY_MASK | (0x0B << REG_VTCR_FUNC_OFFT) | tbl_idx;
459 reg_write(reg, value);
460 printf("write reg: %x, value: %x\n", reg, value);
461
462 while (1)
463 { // wait until not busy
464 reg_read(reg, &value);
465 if ((value & REG_VTCR_BUSY_MASK) == 0) {
466 break;
467 }
468 }
469}
470
471void acl_rule_table_add(int argc, char *argv[])
472{
473 unsigned int vawd1, vawd2;
474 unsigned char tbl_idx;
475
476 tbl_idx = atoi(argv[3]);
477 vawd1 = strtoul(argv[4], (char **)NULL, 16);
478 vawd2 = strtoul(argv[5], (char **)NULL, 16);
479 write_acl_rule_table(tbl_idx, vawd1, vawd2);
480}
481
482void write_rate_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2)
483{
484 unsigned int value, reg;
485 unsigned int max_index = 32;
486
487 printf("Rule_action_tbl_idx:%d\n", tbl_idx);
488
489 if (tbl_idx >= max_index) {
490 printf(HELP_ACL_RATE_TBL_ADD);
491 return;
492 }
493
494 reg = REG_VTCR_ADDR;
495 while (1) { // wait until not busy
496 reg_read(reg, &value);
497 if ((value & REG_VTCR_BUSY_MASK) == 0)
498 break;
499 }
500
501 reg_write(REG_VAWD1_ADDR, vawd1);
502 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
503 reg_write(REG_VAWD2_ADDR, vawd2);
504 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
505 reg = REG_VTCR_ADDR;
506 value = REG_VTCR_BUSY_MASK | (0x0D << REG_VTCR_FUNC_OFFT) | tbl_idx;
507 reg_write(reg, value);
508 printf("write reg: %x, value: %x\n", reg, value);
509
510 while (1) { // wait until not busy
511 reg_read(reg, &value);
512 if ((value & REG_VTCR_BUSY_MASK) == 0)
513 break;
514 }
515}
516
517void acl_rate_table_add(int argc, char *argv[])
518{
519 unsigned int vawd1, vawd2;
520 unsigned char tbl_idx;
521
522 tbl_idx = atoi(argv[3]);
523 vawd1 = strtoul(argv[4], (char **)NULL, 16);
524 vawd2 = strtoul(argv[5], (char **)NULL, 16);
525
526 write_rate_table(tbl_idx, vawd1, vawd2);
527}
528
529void write_trTCM_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2)
530{
531 unsigned int value, reg;
532 unsigned int max_index = 32;
533
534 printf("trTCM_tbl_idx:%d\n", tbl_idx);
535
536 if (tbl_idx >= max_index) {
537 printf(HELP_ACL_TRTCM_TBL_ADD);
538 return;
539 }
540
541 reg = REG_VTCR_ADDR;
542 while (1) { // wait until not busy
543 reg_read(reg, &value);
544 if ((value & REG_VTCR_BUSY_MASK) == 0)
545 break;
546 }
547
548 reg_write(REG_VAWD1_ADDR, vawd1);
549 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
550 reg_write(REG_VAWD2_ADDR, vawd2);
551 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
552 reg = REG_VTCR_ADDR;
553 value = REG_VTCR_BUSY_MASK | (0x07 << REG_VTCR_FUNC_OFFT) | tbl_idx;
554 reg_write(reg, value);
555 printf("write reg: %x, value: %x\n", reg, value);
556
557 while (1) { // wait until not busy
558 reg_read(reg, &value);
559 if ((value & REG_VTCR_BUSY_MASK) == 0)
560 break;
561 }
562}
563
564int acl_parameters_pre_del(int len1, int len2, int argc, char *argv[], int *port)
565{
566 int i;
567
568 *port = 0;
569 if (argc < len1) {
570 printf("insufficient arguments!\n");
571 return -1;
572 }
573
574 if (len2 == 12)
575 {
576 if (!argv[4] || strlen(argv[4]) != len2) {
577 printf("The [%s] format error, should be of length %d\n",argv[4], len2);
578 return -1;
579 }
580 }
581
582 if (!argv[5] || strlen(argv[5]) != 8) {
583 printf("portsmap format error, should be of length 7\n");
584 return -1;
585 }
586
587 for (i = 0; i < 7; i++) {
588 if (argv[5][i] != '0' && argv[5][i] != '1') {
589 printf("portmap format error, should be of combination of 0 or 1\n");
590 return -1;
591 }
592 *port += (argv[5][i] - '0') * (1 << i);
593 }
594 return 0;
595}
596
597void acl_compare_pattern(int ports, int comparion, int base, int word, unsigned char table_index)
598{
599 unsigned int value;
600
601 comparion |= 0xffff0000; //compare mask
602
603 value = ports << 8; //w_port_map
604 value |= 0x1 << 19; //enable
605 value |= base << 16; //mac header
606 value |= word << 1; //word offset
607
608 write_acl_table(table_index, comparion, value);
609}
610
611void acl_mac_add(int argc, char *argv[])
612{
613 unsigned int value;
614 int ports;
615 char tmpstr[5];
616 int ret;
617
618 ret = acl_parameters_pre_del(6, 12, argc, argv, &ports);
619 if (ret < 0)
620 return;
621 //set pattern
622 strncpy(tmpstr, argv[4], 4);
623 tmpstr[4] = '\0';
624 value = strtoul(tmpstr, NULL, 16);
625 acl_compare_pattern(ports, value, 0x0, 0, 0);
626
627 strncpy(tmpstr, argv[4] + 4, 4);
628 tmpstr[4] = '\0';
629 value = strtoul(tmpstr, NULL, 16);
630 acl_compare_pattern(ports, value, 0x0, 1, 1);
631
632 strncpy(tmpstr, argv[4] + 8, 4);
633 tmpstr[4] = '\0';
634 value = strtoul(tmpstr, NULL, 16);
635 acl_compare_pattern(ports, value, 0x0, 2, 2);
636
637 //set mask
638 write_acl_mask_table(0,0x7,0);
639
640 //set action
641 value = 0x7; //drop
642 value |= 1 << 28; //acl intterupt enable
643 value |= 1 << 27; //acl hit count
644 value |= 2 << 24; //acl hit count group index (0~3)
645 write_acl_rule_table(0,value,0);
646}
647
648void acl_dip_meter(int argc, char *argv[])
649{
650 unsigned int value, ip_value, meter;
651 int ports;
652 int ret;
653
654 ip_value = 0;
655 ret = acl_parameters_pre_del(7, -1, argc, argv, &ports);
656 if (ret < 0)
657 return;
658
659 str_to_ip(&ip_value, argv[4]);
660 //set pattern
661 value = (ip_value >> 16);
662 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
663
664 //set pattern
665 value = (ip_value & 0xffff);
666 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
667
668 //set mask
669 write_acl_mask_table(0,0x3,0);
670
671 //set action
672 meter = strtoul(argv[6], NULL, 0);
673 if (((chip_name == 0x7530) && (meter > 1000000)) ||
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 value, value2, ip_value;
699 unsigned int CIR, CBS, PIR, PBS;
700 int ports;
701 int ret;
702
703 ip_value = 0;
704 ret = acl_parameters_pre_del(10, -1, argc, argv, &ports);
705 if (ret < 0)
706 return;
707
708 str_to_ip(&ip_value, argv[4]);
709 //set pattern
710 value = (ip_value >> 16);
711 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
712
713 //set pattern
714 value = (ip_value & 0xffff);
715 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
716
717 //set CBS PBS
718 CIR = strtoul(argv[6], NULL, 0);
719 CBS = strtoul(argv[7], NULL, 0);
720 PIR = strtoul(argv[8], NULL, 0);
721 PBS = strtoul(argv[9], NULL, 0);
722
723 if (CIR > 65535*64 || CBS > 65535 || PIR > 65535*64 || PBS > 65535) {
724 printf("\n**Illegal input parameters**\n");
725 return;
726 }
727
728 value = CBS << 16; //bit16~31
729 value |= PBS; //bit0~15
730 //value |= 1;//valid
731 CIR = CIR >> 6;
732 PIR = PIR >> 6;
733
734 value2 = CIR << 16; //bit16~31
735 value2 |= PIR; //bit0~15
736 write_trTCM_table(0,value,value2);
737
738 //set pattern
739 write_acl_mask_table(0,0x3,0);
740
741 //set action
742 value = 0x1 << (11 + 1); //TrTCM green meter#0 Low drop
743 value |= 0x2 << (8 + 1); //TrTCM yellow meter#0 Med drop
744 value |= 0x3 << (5 + 1); //TrTCM red meter#0 Hig drop
745 value |= 0x1 << 0; //TrTCM drop pcd select
746 write_acl_rule_table(0,0,value);
747}
748
749void acl_ethertype(int argc, char *argv[])
750{
751 unsigned int value, ethertype;
752 int ports;
753 int ret;
754
755 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
756 if (ret < 0)
757 return;
758 printf("ports:0x%x\n",ports);
759 ethertype = strtoul(argv[4], NULL, 16);
760 //set pattern
761 value = ethertype;
762 acl_compare_pattern(ports, value, 0x0, 0x6, 0);
763
764 //set pattern
765 write_acl_mask_table(0,0x1,0);
766
767 //set action(drop)
768 value = 0x7; //default. Nodrop
769 value |= 1 << 28; //acl intterupt enable
770 value |= 1 << 27; //acl hit count
771
772 write_acl_rule_table(0,value,0);
773}
774
775void acl_dip_modify(int argc, char *argv[])
776{
777 unsigned int value, ip_value;
778 int ports;
779 int priority;
780 int ret;
781
782 ip_value = 0;
783 priority = strtoul(argv[6], NULL, 16);
784 if (priority < 0 || priority > 7) {
785 printf("\n**Illegal priority value!**\n");
786 return;
787 }
788
789 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
790 if (ret < 0)
791 return;
792
793 str_to_ip(&ip_value, argv[4]);
794 //set pattern
795 value = (ip_value >> 16);
796 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
797
798 //set pattern
799 value = (ip_value & 0xffff);
800 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
801
802 //set pattern
803 write_acl_mask_table(0,0x3,0);
804
805 //set action
806 value = 0x0; //default. Nodrop
807 value |= 1 << 28; //acl intterupt enable
808 value |= 1 << 27; //acl hit count
809 value |= priority << 4; //acl UP
810 write_acl_rule_table(0,value,0);
811}
812
813void acl_dip_pppoe(int argc, char *argv[])
814{
815 unsigned int value, ip_value;
816 int ports;
817 int ret;
818
819 ip_value = 0;
820 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
821 if (ret < 0)
822 return;
823
824 str_to_ip(&ip_value, argv[4]);
825 //set pattern
826 value = (ip_value >> 16);
827 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
828
829 //set pattern
830 value = (ip_value & 0xffff);
831 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
832
833 //set pattern
834 write_acl_mask_table(0,0x3,0);
835
836 //set action
837 value = 0x0; //default. Nodrop
838 value |= 1 << 28; //acl intterupt enable
839 value |= 1 << 27; //acl hit count
840 value |= 1 << 20; //pppoe header remove
841 value |= 1 << 21; //SA MAC SWAP
842 value |= 1 << 22; //DA MAC SWAP
843 write_acl_rule_table(0,value,7);
844}
845
846void acl_dip_add(int argc, char *argv[])
847{
848 unsigned int value, ip_value;
849 int ports;
850 int ret;
851
852 ip_value = 0;
853 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
854 if (ret < 0)
855 return;
856
857 str_to_ip(&ip_value, argv[4]);
858 //set pattern
859 value = (ip_value >> 16);
860 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
861
862 //set pattern
863 value = (ip_value & 0xffff);
864 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
865
866 //set pattern
867 write_acl_mask_table(0,0x3,0);
868
869 //set action
870 //value = 0x0; //default
871 value = 0x7; //drop
872 value |= 1 << 28; //acl intterupt enable
873 value |= 1 << 27; //acl hit count
874 value |= 2 << 24; //acl hit count group index (0~3)
875 write_acl_rule_table(0,value,0);
876}
877
878void acl_l4_add(int argc, char *argv[])
879{
880 unsigned int value;
881 int ports;
882 int ret;
883
884 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
885 if (ret < 0)
886 return;
887
888 //set pattern
889 value = strtoul(argv[4], NULL, 16);
890 acl_compare_pattern(ports, value, 0x5, 0x0, 0);
891
892 //set rue mask
893 write_acl_mask_table(0,0x1,0);
894 //set action
895 value = 0x7; //drop
896 //value |= 1;//valid
897 write_acl_rule_table(0,value,0);
898}
899
900void acl_sp_add(int argc, char *argv[])
901{
902 unsigned int value;
903 int ports;
904 int ret;
905
906 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
907 if (ret < 0)
908 return;
909 //set pattern
910 value = strtoul(argv[4], NULL, 0);
911 acl_compare_pattern(ports, value, 0x4, 0x0, 0);
912
913 //set rue mask
914 write_acl_mask_table(0,0x1,0);
915
916 //set action
917 value = 0x7; //drop
918 //value |= 1;//valid
919 write_acl_rule_table(0,value,0);
920}
921
922void acl_port_enable(int argc, char *argv[])
923{
924 unsigned int value, reg;
925 unsigned char acl_port, acl_en;
926
927 acl_port = atoi(argv[3]);
928 acl_en = atoi(argv[4]);
929
930 printf("acl_port:%d, acl_en:%d\n", acl_port, acl_en);
931
932 /*Check the input parameters is right or not.*/
933 if ((acl_port > SWITCH_MAX_PORT) || (acl_en > 1)) {
934 printf(HELP_ACL_SETPORTEN);
935 return;
936 }
937
938 reg = REG_PCR_P0_ADDR + (0x100 * acl_port); // 0x2004[10]
939 reg_read(reg, &value);
940 value &= (~REG_PORT_ACL_EN_MASK);
941 value |= (acl_en << REG_PORT_ACL_EN_OFFT);
942
943 printf("write reg: %x, value: %x\n", reg, value);
944 reg_write(reg, value);
945}
946
947static void dip_dump_internal(int type)
948{
949 unsigned int i, j, value, mac, mac2, value2;
950 char tmpstr[16];
951 int table_size = 0;
952 int hit_value1 = 0;
953 int hit_value2 = 0;
954
955 if(type == GENERAL_TABLE) {
956 table_size = 0x800;
957 reg_write(REG_ATC_ADDR, 0x8104); //dip search command
958 } else {
959 table_size = 0x40;
960 reg_write(REG_ATC_ADDR, 0x811c); //dip search command
961 }
962 printf("hash port(0:6) rsp_cnt flag timer dip-address ATRD\n");
963 for (i = 0; i < table_size; i++) {
964 while (1)
965 {
966 reg_read(REG_ATC_ADDR, &value);
967 if(type == GENERAL_TABLE) {
968 hit_value1 = value & (0x1 << 13);
969 hit_value2 = 1;
970 }else {
971 hit_value1 = value & (0x1 << 13);
972 hit_value2 = value & (0x1 << 28);
973 }
974
975 if (hit_value1 && hit_value2 ) { //search_rdy
976 reg_read(REG_ATRD_ADDR, &value2);
977 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
978
979 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
980 j = (value2 >> 4) & 0xff; //r_port_map
981 printf("%c", (j & 0x01) ? '1' : '-');
982 printf("%c", (j & 0x02) ? '1' : '-');
983 printf("%c", (j & 0x04) ? '1' : '-');
984 printf("%c ", (j & 0x08) ? '1' : '-');
985 printf("%c", (j & 0x10) ? '1' : '-');
986 printf("%c", (j & 0x20) ? '1' : '-');
987 printf("%c", (j & 0x40) ? '1' : '-');
988
989 reg_read(REG_TSRA2_ADDR, &mac2);
990
991 printf(" 0x%4x", (mac2 & 0xffff)); //RESP_CNT
992 printf(" 0x%2x", ((mac2 >> 16) & 0xff)); //RESP_FLAG
993 printf(" %3d", ((mac2 >> 24) & 0xff)); //RESP_TIMER
994 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
995 reg_read(REG_TSRA1_ADDR, &mac);
996 ip_to_str(tmpstr, mac);
997 printf(" %s", tmpstr);
998 printf(" 0x%8x\n", value2); //ATRD
999 //printf("%04x", ((mac2 >> 16) & 0xffff));
1000 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
1001 if (value & 0x4000) {
1002 printf("end of table %d\n", i);
1003 return;
1004 }
1005 break;
1006 }
1007 else if (value & 0x4000) { //at_table_end
1008 printf("found the last entry %d (not ready)\n", i);
1009 return;
1010 }
1011 usleep(5000);
1012 }
1013
1014 if(type == GENERAL_TABLE)
1015 reg_write(REG_ATC_ADDR, 0x8105); //search for next dip address
1016 else
1017 reg_write(REG_ATC_ADDR, 0x811d); //search for next dip address
1018 usleep(5000);
1019 }
1020}
1021
1022void dip_dump(void)
1023{
1024 dip_dump_internal(GENERAL_TABLE);
1025
1026}
1027
1028void dip_add(int argc, char *argv[])
1029{
1030 unsigned int value = 0;
1031 unsigned int i, j;
1032
1033 value = 0;
1034
1035 str_to_ip(&value, argv[3]);
1036
1037 reg_write(REG_ATA1_ADDR, value);
1038 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1039
1040#if 0
1041 reg_write(REG_ATA2_ADDR, value);
1042 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1043#endif
1044 if (!argv[4] || strlen(argv[4]) != 8) {
1045 printf("portmap format error, should be of length 7\n");
1046 return;
1047 }
1048 j = 0;
1049 for (i = 0; i < 7; i++) {
1050 if (argv[4][i] != '0' && argv[4][i] != '1') {
1051 printf("portmap format error, should be of combination of 0 or 1\n");
1052 return;
1053 }
1054 j += (argv[4][i] - '0') * (1 << i);
1055 }
1056 value = j << 4; //w_port_map
1057 value |= (0x3 << 2); //static
1058
1059 reg_write(REG_ATWD_ADDR, value);
1060
1061 usleep(5000);
1062 reg_read(REG_ATWD_ADDR, &value);
1063 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1064
1065 value = 0x8011; //single w_dip_cmd
1066 reg_write(REG_ATC_ADDR, value);
1067
1068 usleep(1000);
1069
1070 for (i = 0; i < 20; i++) {
1071 reg_read(REG_ATC_ADDR, &value);
1072 if ((value & 0x8000) == 0) { //mac address busy
1073 printf("done.\n");
1074 return;
1075 }
1076 usleep(1000);
1077 }
1078 if (i == 20)
1079 printf("timeout.\n");
1080}
1081
1082void dip_del(int argc, char *argv[])
1083{
1084 unsigned int i, value;
1085
1086 value = 0;
1087 str_to_ip(&value, argv[3]);
1088
1089 reg_write(REG_ATA1_ADDR, value);
1090
1091 value = 0;
1092 reg_write(REG_ATA2_ADDR, value);
1093
1094 value = 0; //STATUS=0, delete dip
1095 reg_write(REG_ATWD_ADDR, value);
1096
1097 value = 0x8011; //w_dip_cmd
1098 reg_write(REG_ATC_ADDR, value);
1099
1100 for (i = 0; i < 20; i++) {
1101 reg_read(REG_ATC_ADDR, &value);
1102 if ((value & 0x8000) == 0) { //mac address busy
1103 if (argv[1] != NULL)
1104 printf("done.\n");
1105 return;
1106 }
1107 usleep(1000);
1108 }
1109 if (i == 20)
1110 printf("timeout.\n");
1111}
1112
1113void dip_clear(void)
1114{
1115
1116 unsigned int value;
1117
1118 reg_write(REG_ATC_ADDR, 0x8102); //clear all dip
1119 usleep(5000);
1120 reg_read(REG_ATC_ADDR, &value);
1121 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1122}
1123
1124static void sip_dump_internal(int type)
1125{
1126 unsigned int i, j, value, mac, mac2, value2;
1127 int table_size = 0;
1128 int hit_value1 = 0;
1129 int hit_value2 = 0;
1130 char tmpstr[16];
1131
1132 if (type == GENERAL_TABLE) {
1133 table_size = 0x800;
1134 reg_write(REG_ATC_ADDR, 0x8204); //sip search command
1135 }else {
1136 table_size = 0x40;
1137 reg_write(REG_ATC_ADDR, 0x822c); //sip search command
1138 }
1139 printf("hash port(0:6) dip-address sip-address ATRD\n");
1140 for (i = 0; i < table_size; i++) {
1141 while (1)
1142 {
1143 reg_read(REG_ATC_ADDR, &value);
1144 if(type == GENERAL_TABLE) {
1145 hit_value1 = value & (0x1 << 13);
1146 hit_value2 = 1;
1147 } else {
1148 hit_value1 = value & (0x1 << 13);
1149 hit_value2 = value & (0x1 << 28);
1150 }
1151
1152 if (hit_value1 && hit_value2) { //search_rdy
1153 reg_read(REG_ATRD_ADDR, &value2);
1154 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1155
1156 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1157 j = (value2 >> 4) & 0xff; //r_port_map
1158 printf("%c", (j & 0x01) ? '1' : '-');
1159 printf("%c", (j & 0x02) ? '1' : '-');
1160 printf("%c", (j & 0x04) ? '1' : '-');
1161 printf("%c", (j & 0x08) ? '1' : '-');
1162 printf(" %c", (j & 0x10) ? '1' : '-');
1163 printf("%c", (j & 0x20) ? '1' : '-');
1164 printf("%c", (j & 0x40) ? '1' : '-');
1165
1166 reg_read(REG_TSRA2_ADDR, &mac2);
1167
1168 ip_to_str(tmpstr, mac2);
1169 printf(" %s", tmpstr);
1170
1171 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
1172 reg_read(REG_TSRA1_ADDR, &mac);
1173 ip_to_str(tmpstr, mac);
1174 printf(" %s", tmpstr);
1175 printf(" 0x%x\n", value2);
1176 //printf("%04x", ((mac2 >> 16) & 0xffff));
1177 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
1178 if (value & 0x4000) {
1179 printf("end of table %d\n", i);
1180 return;
1181 }
1182 break;
1183 } else if (value & 0x4000) { //at_table_end
1184 printf("found the last entry %d (not ready)\n", i);
1185 return;
1186 }
1187 usleep(5000);
1188 }
1189
1190 if(type == GENERAL_TABLE)
1191 reg_write(REG_ATC_ADDR, 0x8205); //search for next sip address
1192 else
1193 reg_write(REG_ATC_ADDR, 0x822d); //search for next sip address
1194 usleep(5000);
1195 }
1196}
1197
1198void sip_dump(void)
1199{
1200
1201 sip_dump_internal(GENERAL_TABLE);
1202
1203}
1204
1205
1206void sip_add(int argc, char *argv[])
1207{
1208 unsigned int i, j, value;
1209
1210 value = 0;
1211 str_to_ip(&value, argv[3]); //SIP
1212
1213 reg_write(REG_ATA2_ADDR, value);
1214 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1215
1216 value = 0;
1217
1218 str_to_ip(&value, argv[4]); //DIP
1219 reg_write(REG_ATA1_ADDR, value);
1220 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1221
1222 if (!argv[5] || strlen(argv[5]) != 8) {
1223 printf("portmap format error, should be of length 7\n");
1224 return;
1225 }
1226 j = 0;
1227 for (i = 0; i < 7; i++) {
1228 if (argv[5][i] != '0' && argv[5][i] != '1') {
1229 printf("portmap format error, should be of combination of 0 or 1\n");
1230 return;
1231 }
1232 j += (argv[5][i] - '0') * (1 << i);
1233 }
1234 value = j << 4; //w_port_map
1235 value |= (0x3 << 2); //static
1236
1237 reg_write(REG_ATWD_ADDR, value);
1238
1239 usleep(5000);
1240 reg_read(REG_ATWD_ADDR, &value);
1241 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1242
1243 value = 0x8021; //single w_sip_cmd
1244 reg_write(REG_ATC_ADDR, value);
1245
1246 usleep(1000);
1247
1248 for (i = 0; i < 20; i++) {
1249 reg_read(REG_ATC_ADDR, &value);
1250 if ((value & 0x8000) == 0) { //mac address busy
1251 printf("done.\n");
1252 return;
1253 }
1254 usleep(1000);
1255 }
1256 if (i == 20)
1257 printf("timeout.\n");
1258}
1259
1260void sip_del(int argc, char *argv[])
1261{
1262 unsigned int i, value;
1263
1264 value = 0;
1265 str_to_ip(&value, argv[3]);
1266
1267 reg_write(REG_ATA2_ADDR, value); //SIP
1268
1269 str_to_ip(&value, argv[4]);
1270 reg_write(REG_ATA1_ADDR, value); //DIP
1271
1272 value = 0; //STATUS=0, delete sip
1273 reg_write(REG_ATWD_ADDR, value);
1274
1275 value = 0x8021; //w_sip_cmd
1276 reg_write(REG_ATC_ADDR, value);
1277
1278 for (i = 0; i < 20; i++) {
1279 reg_read(REG_ATC_ADDR, &value);
1280 if ((value & 0x8000) == 0) { //mac address busy
1281 if (argv[1] != NULL)
1282 printf("done.\n");
1283 return;
1284 }
1285 usleep(1000);
1286 }
1287 if (i == 20)
1288 printf("timeout.\n");
1289}
1290
1291void sip_clear(void)
1292{
1293 unsigned int value;
1294
1295 reg_write(REG_ATC_ADDR, 0x8202); //clear all sip
1296 usleep(5000);
1297 reg_read(REG_ATC_ADDR, &value);
1298 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1299}
1300
1301static void table_dump_internal(int type)
1302{
1303 unsigned int i, j, value, mac, mac2, value2;
1304 int table_size = 0;
1305 int table_end = 0;
1306 int hit_value1 = 0;
1307 int hit_value2 = 0;
1308
1309 if (type == GENERAL_TABLE){
1310 table_size = 0x800;
1311 table_end = 0x7FF;
1312 reg_write(REG_ATC_ADDR, 0x8004);
1313 } else {
1314 table_size = 0x40;
1315 table_end = 0x3F;
1316 reg_write(REG_ATC_ADDR, 0x800C);
1317 }
1318 printf("hash port(0:6) fid vid age(s) mac-address filter my_mac\n");
1319 for (i = 0; i < table_size; i++) {
1320 while (1)
1321 {
1322 reg_read(REG_ATC_ADDR, &value);
1323 //printf("ATC = 0x%x\n", value);
1324 if(type == GENERAL_TABLE) {
1325 hit_value1 = value & (0x1 << 13);
1326 hit_value2 = 1;
1327 } else {
1328 hit_value1 = value & (0x1 << 13);
1329 hit_value2 = value & (0x1 << 28);
1330 }
1331
1332 if (hit_value1 && hit_value2 && (((value >> 15) & 0x1) == 0)) {
1333 printf("%03x: ", (value >> 16) & 0xfff);
1334 reg_read(REG_ATRD_ADDR, &value2);
1335 j = (value2 >> 4) & 0xff; //r_port_map
1336 printf("%c", (j & 0x01) ? '1' : '-');
1337 printf("%c", (j & 0x02) ? '1' : '-');
1338 printf("%c", (j & 0x04) ? '1' : '-');
1339 printf("%c", (j & 0x08) ? '1' : '-');
1340 printf("%c", (j & 0x10) ? '1' : '-');
1341 printf("%c", (j & 0x20) ? '1' : '-');
1342 printf("%c", (j & 0x40) ? '1' : '-');
1343 printf("%c", (j & 0x80) ? '1' : '-');
1344
1345 reg_read(REG_TSRA2_ADDR, &mac2);
1346
1347 printf(" %2d", (mac2 >> 12) & 0x7); //FID
1348 printf(" %4d", (mac2 & 0xfff));
1349 if (((value2 >> 24) & 0xff) == 0xFF)
1350 printf(" --- "); //r_age_field:static
1351 else
1352 printf(" %5d ", (((value2 >> 24) & 0xff)+1)*2); //r_age_field
1353 reg_read(REG_TSRA1_ADDR, &mac);
1354 printf(" %08x", mac);
1355 printf("%04x", ((mac2 >> 16) & 0xffff));
1356 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1357 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1358 if ((value & 0x4000) && (((value >> 16) & 0xfff) == table_end)) {
1359 printf("end of table %d\n", i);
1360 return;
1361 }
1362 break;
1363 }
1364 else if ((value & 0x4000) && (((value >> 15) & 0x1) == 0) && (((value >> 16) & 0xfff) == table_end)) { //at_table_end
1365 printf("found the last entry %d (not ready)\n", i);
1366 return;
1367 }
1368 else
1369 usleep(5);
1370 }
1371
1372 if(type == GENERAL_TABLE)
1373 reg_write(REG_ATC_ADDR, 0x8005);//search for next address
1374 else
1375 reg_write(REG_ATC_ADDR, 0x800d);//search for next address
1376 usleep(5);
1377 }
1378}
1379
1380void table_dump(void)
1381{
1382 table_dump_internal(GENERAL_TABLE);
1383
1384}
1385
1386
1387void table_add(int argc, char *argv[])
1388{
1389 unsigned int i, j, value, is_filter, is_mymac;
1390 char tmpstr[9];
1391
1392 is_filter = (argv[1][0] == 'f') ? 1 : 0;
1393 is_mymac = (argv[1][0] == 'm') ? 1 : 0;
1394 if (!argv[2] || strlen(argv[2]) != 12) {
1395 printf("MAC address format error, should be of length 12\n");
1396 return;
1397 }
1398 strncpy(tmpstr, argv[2], 8);
1399 tmpstr[8] = '\0';
1400 value = strtoul(tmpstr, NULL, 16);
1401 reg_write(REG_ATA1_ADDR, value);
1402 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1403
1404 strncpy(tmpstr, argv[2] + 8, 4);
1405 tmpstr[4] = '\0';
1406
1407 value = strtoul(tmpstr, NULL, 16);
1408 value = (value << 16);
1409 value |= (1 << 15); //IVL=1
1410
1411 if (argc > 4) {
1412 j = strtoul(argv[4], NULL, 0);
1413 if (4095 < j) {
1414 printf("wrong vid range, should be within 0~4095\n");
1415 return;
1416 }
1417 value |= j; //vid
1418 }
1419
1420 reg_write(REG_ATA2_ADDR, value);
1421 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1422
1423 if (!argv[3] || strlen(argv[3]) != 8) {
1424 if (is_filter)
1425 argv[3] = "11111111";
1426 else {
1427 printf("portmap format error, should be of length 8\n");
1428 return;
1429 }
1430 }
1431 j = 0;
1432 for (i = 0; i < 7; i++) {
1433 if (argv[3][i] != '0' && argv[3][i] != '1') {
1434 printf("portmap format error, should be of combination of 0 or 1\n");
1435 return;
1436 }
1437 j += (argv[3][i] - '0') * (1 << i);
1438 }
1439 value = j << 4; //w_port_map
1440
1441 if (argc > 5) {
1442 j = strtoul(argv[5], NULL, 0);
1443 if (j < 1 || 255 < j) {
1444 printf("wrong age range, should be within 1~255\n");
1445 return;
1446 }
1447 value |= (j << 24); //w_age_field
1448 value |= (0x1 << 2); //dynamic
1449 } else {
1450 value |= (0xff << 24); //w_age_field
1451 value |= (0x3 << 2); //static
1452 }
1453
1454 if (argc > 6) {
1455 j = strtoul(argv[6], NULL, 0);
1456 if (7 < j) {
1457 printf("wrong eg-tag range, should be within 0~7\n");
1458 return;
1459 }
1460 value |= (j << 13); //EG_TAG
1461 }
1462
1463 if (is_filter)
1464 value |= (7 << 20); //sa_filter
1465
1466 if (is_mymac)
1467 value |= (1 << 23);
1468
1469 reg_write(REG_ATWD_ADDR, value);
1470
1471 usleep(5000);
1472 reg_read(REG_ATWD_ADDR, &value);
1473 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1474
1475 value = 0x8001; //w_mac_cmd
1476 reg_write(REG_ATC_ADDR, value);
1477
1478 usleep(1000);
1479
1480 for (i = 0; i < 20; i++) {
1481 reg_read(REG_ATC_ADDR, &value);
1482 if ((value & 0x8000) == 0) { //mac address busy
1483 printf("done.\n");
1484 return;
1485 }
1486 usleep(1000);
1487 }
1488 if (i == 20)
1489 printf("timeout.\n");
1490}
1491
1492void table_search_mac_vid(int argc, char *argv[])
1493{
1494 unsigned int i, j, value, mac, mac2, value2;
1495 char tmpstr[9];
1496
1497 if (!argv[3] || strlen(argv[3]) != 12) {
1498 printf("MAC address format error, should be of length 12\n");
1499 return;
1500 }
1501 strncpy(tmpstr, argv[3], 8);
1502 tmpstr[8] = '\0';
1503 value = strtoul(tmpstr, NULL, 16);
1504 reg_write(REG_ATA1_ADDR, value);
1505 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1506
1507 strncpy(tmpstr, argv[3] + 8, 4);
1508 tmpstr[4] = '\0';
1509
1510 value = strtoul(tmpstr, NULL, 16);
1511 value = (value << 16);
1512 value |= (1 << 15); //IVL=1
1513
1514 j = strtoul(argv[5], NULL, 0);
1515 if (4095 < j) {
1516 printf("wrong vid range, should be within 0~4095\n");
1517 return;
1518 }
1519 value |= j; //vid
1520
1521 reg_write(REG_ATA2_ADDR, value);
1522 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1523
1524 value = 0x8000; //w_mac_cmd
1525 reg_write(REG_ATC_ADDR, value);
1526
1527 usleep(1000);
1528
1529 for (i = 0; i < 20; i++) {
1530 reg_read(REG_ATC_ADDR, &value);
1531 if ((value & 0x8000) == 0) { //mac address busy
1532 break;
1533 }
1534 usleep(1000);
1535 }
1536 if (i == 20) {
1537 printf("search timeout.\n");
1538 return;
1539 }
1540
1541 if (value & 0x1000) {
1542 printf("search no entry.\n");
1543 return;
1544 }
1545
1546 printf("search done.\n");
1547 printf("hash port(0:6) fid vid age mac-address filter my_mac\n");
1548
1549 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1550 reg_read(REG_ATRD_ADDR, &value2);
1551 j = (value2 >> 4) & 0xff; //r_port_map
1552 printf("%c", (j & 0x01) ? '1' : '-');
1553 printf("%c", (j & 0x02) ? '1' : '-');
1554 printf("%c", (j & 0x04) ? '1' : '-');
1555 printf("%c ", (j & 0x08) ? '1' : '-');
1556 printf("%c", (j & 0x10) ? '1' : '-');
1557 printf("%c", (j & 0x20) ? '1' : '-');
1558 printf("%c", (j & 0x40) ? '1' : '-');
1559 printf("%c", (j & 0x80) ? '1' : '-');
1560
1561 reg_read(REG_TSRA2_ADDR, &mac2);
1562
1563 printf(" %2d", (mac2 >> 12) & 0x7); //FID
1564 printf(" %4d", (mac2 & 0xfff));
1565 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
1566 reg_read(REG_TSRA1_ADDR, &mac);
1567 printf(" %08x", mac);
1568 printf("%04x", ((mac2 >> 16) & 0xffff));
1569 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1570 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1571}
1572
1573void table_search_mac_fid(int argc, char *argv[])
1574{
1575 unsigned int i, j, value, mac, mac2, value2;
1576 char tmpstr[9];
1577
1578 if (!argv[3] || strlen(argv[3]) != 12) {
1579 printf("MAC address format error, should be of length 12\n");
1580 return;
1581 }
1582 strncpy(tmpstr, argv[3], 8);
1583 tmpstr[8] = '\0';
1584 value = strtoul(tmpstr, NULL, 16);
1585 reg_write(REG_ATA1_ADDR, value);
1586 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1587
1588 strncpy(tmpstr, argv[3] + 8, 4);
1589 tmpstr[4] = '\0';
1590
1591 value = strtoul(tmpstr, NULL, 16);
1592 value = (value << 16);
1593 value &= ~(1 << 15); //IVL=0
1594
1595 j = strtoul(argv[5], NULL, 0);
1596 if (7 < j) {
1597 printf("wrong fid range, should be within 0~7\n");
1598 return;
1599 }
1600 value |= (j << 12); //vid
1601
1602 reg_write(REG_ATA2_ADDR, value);
1603 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1604
1605 value = 0x8000; //w_mac_cmd
1606 reg_write(REG_ATC_ADDR, value);
1607
1608 usleep(1000);
1609
1610 for (i = 0; i < 20; i++) {
1611 reg_read(REG_ATC_ADDR, &value);
1612 if ((value & 0x8000) == 0) { //mac address busy
1613 break;
1614 }
1615 usleep(1000);
1616 }
1617 if (i == 20) {
1618 printf("search timeout.\n");
1619 return;
1620 }
1621
1622 if (value & 0x1000) {
1623 printf("search no entry.\n");
1624 return;
1625 }
1626
1627 printf("search done.\n");
1628 printf("hash port(0:6) fid vid age mac-address filter my_mac\n");
1629
1630 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1631 reg_read(REG_ATRD_ADDR, &value2);
1632 j = (value2 >> 4) & 0xff; //r_port_map
1633 printf("%c", (j & 0x01) ? '1' : '-');
1634 printf("%c", (j & 0x02) ? '1' : '-');
1635 printf("%c", (j & 0x04) ? '1' : '-');
1636 printf("%c ", (j & 0x08) ? '1' : '-');
1637 printf("%c", (j & 0x10) ? '1' : '-');
1638 printf("%c", (j & 0x20) ? '1' : '-');
1639 printf("%c", (j & 0x40) ? '1' : '-');
1640 printf("%c", (j & 0x80) ? '1' : '-');
1641
1642 reg_read(REG_TSRA2_ADDR, &mac2);
1643
1644 printf(" %2d", (mac2 >> 12) & 0x7); //FID
1645 printf(" %4d", (mac2 & 0xfff));
1646 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
1647 reg_read(REG_TSRA1_ADDR, &mac);
1648 printf(" %08x", mac);
1649 printf("%04x", ((mac2 >> 16) & 0xffff));
1650 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1651 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1652}
1653
1654void table_del_fid(int argc, char *argv[])
1655{
1656 unsigned int i, j, value;
1657 char tmpstr[9];
1658
1659 if (!argv[3] || strlen(argv[3]) != 12) {
1660 printf("MAC address format error, should be of length 12\n");
1661 return;
1662 }
1663 strncpy(tmpstr, argv[3], 8);
1664 tmpstr[8] = '\0';
1665 value = strtoul(tmpstr, NULL, 16);
1666 reg_write(REG_ATA1_ADDR, value);
1667 strncpy(tmpstr, argv[3] + 8, 4);
1668 tmpstr[4] = '\0';
1669 value = strtoul(tmpstr, NULL, 16);
1670 value = (value << 16);
1671
1672 if (argc > 5) {
1673 j = strtoul(argv[5], NULL, 0);
1674 if (j > 7) {
1675 printf("wrong fid range, should be within 0~7\n");
1676 return;
1677 }
1678 value |= (j << 12); //fid
1679 }
1680
1681 reg_write(REG_ATA2_ADDR, value);
1682
1683 value = 0; //STATUS=0, delete mac
1684 reg_write(REG_ATWD_ADDR, value);
1685
1686 value = 0x8001; //w_mac_cmd
1687 reg_write(REG_ATC_ADDR, value);
1688
1689 for (i = 0; i < 20; i++) {
1690 reg_read(REG_ATC_ADDR, &value);
1691 if ((value & 0x8000) == 0) { //mac address busy
1692 if (argv[1] != NULL)
1693 printf("done.\n");
1694 return;
1695 }
1696 usleep(1000);
1697 }
1698 if (i == 20)
1699 printf("timeout.\n");
1700}
1701
1702void table_del_vid(int argc, char *argv[])
1703{
1704 unsigned int i, j, value;
1705 char tmpstr[9];
1706
1707 if (!argv[3] || strlen(argv[3]) != 12) {
1708 printf("MAC address format error, should be of length 12\n");
1709 return;
1710 }
1711 strncpy(tmpstr, argv[3], 8);
1712 tmpstr[8] = '\0';
1713 value = strtoul(tmpstr, NULL, 16);
1714 reg_write(REG_ATA1_ADDR, value);
1715
1716 strncpy(tmpstr, argv[3] + 8, 4);
1717 tmpstr[4] = '\0';
1718 value = strtoul(tmpstr, NULL, 16);
1719 value = (value << 16);
1720
1721 j = strtoul(argv[5], NULL, 0);
1722 if (j > 4095) {
1723 printf("wrong fid range, should be within 0~4095\n");
1724 return;
1725 }
1726 value |= j; //vid
1727 value |= 1 << 15;
1728 reg_write(REG_ATA2_ADDR, value);
1729
1730 value = 0; //STATUS=0, delete mac
1731 reg_write(REG_ATWD_ADDR, value);
1732
1733 value = 0x8001; //w_mac_cmd
1734 reg_write(REG_ATC_ADDR, value);
1735
1736 for (i = 0; i < 20; i++) {
1737 reg_read(REG_ATC_ADDR, &value);
1738 if ((value & 0x8000) == 0) { //mac address busy
1739 if (argv[1] != NULL)
1740 printf("done.\n");
1741 return;
1742 }
1743 usleep(1000);
1744 }
1745 if (i == 20)
1746 printf("timeout.\n");
1747}
1748
1749void table_clear(void)
1750{
1751 unsigned int value;
1752 reg_write(REG_ATC_ADDR, 0x8002);
1753 usleep(5000);
1754 reg_read(REG_ATC_ADDR, &value);
1755
1756 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1757}
1758
1759void set_mirror_to(int argc, char *argv[])
1760{
1761 unsigned int value;
1762 int idx;
1763
1764 idx = strtoul(argv[3], NULL, 0);
1765 if (idx < 0 || MAX_PORT < idx) {
1766 printf("wrong port member, should be within 0~%d\n", MAX_PORT);
1767 return;
1768 }
1769 if (chip_name == 0x7530) {
1770
1771 reg_read(REG_MFC_ADDR, &value);
1772 value |= 0x1 << 3;
1773 value &= 0xfffffff8;
1774 value |= idx << 0;
1775
1776 reg_write(REG_MFC_ADDR, value);
1777 } else {
1778
1779 reg_read(REG_CFC_ADDR, &value);
1780 value &= (~REG_CFC_MIRROR_EN_MASK);
1781 value |= (1 << REG_CFC_MIRROR_EN_OFFT);
1782 value &= (~REG_CFC_MIRROR_PORT_MASK);
1783 value |= (idx << REG_CFC_MIRROR_PORT_OFFT);
1784 reg_write(REG_CFC_ADDR, value);
1785 }
1786}
1787
1788void set_mirror_from(int argc, char *argv[])
1789{
1790 unsigned int offset, value;
1791 int idx, mirror;
1792
1793 idx = strtoul(argv[3], NULL, 0);
1794 mirror = strtoul(argv[4], NULL, 0);
1795
1796 if (idx < 0 || MAX_PORT < idx) {
1797 printf("wrong port member, should be within 0~%d\n", MAX_PORT);
1798 return;
1799 }
1800
1801 if (mirror < 0 || 3 < mirror) {
1802 printf("wrong mirror setting, should be within 0~3\n");
1803 return;
1804 }
1805
1806 offset = (0x2004 | (idx << 8));
1807 reg_read(offset, &value);
1808
1809 value &= 0xfffffcff;
1810 value |= mirror << 8;
1811
1812 reg_write(offset, value);
1813}
1814
1815void vlan_dump(int argc, char *argv[])
1816{
1817 unsigned int i, j, value, value2;
1818 int eg_tag = 0;
1819
1820 if (argc == 4) {
1821 if (!strncmp(argv[3], "egtag", 6))
1822 eg_tag = 1;
1823 }
1824
1825 if (eg_tag)
1826 printf(" vid fid portmap s-tag\teg_tag(0:untagged 2:tagged)\n");
1827 else
1828 printf(" vid fid portmap s-tag\n");
1829
1830 for (i = 1; i < 4095; i++) {
1831 value = (0x80000000 + i); //r_vid_cmd
1832 reg_write(REG_VTCR_ADDR, value);
1833
1834 for (j = 0; j < 20; j++) {
1835 reg_read(REG_VTCR_ADDR, &value);
1836 if ((value & 0x80000000) == 0) { //mac address busy
1837 break;
1838 }
1839 usleep(1000);
1840 }
1841 if (j == 20)
1842 printf("timeout.\n");
1843
1844 reg_read(REG_VAWD1_ADDR, &value);
1845 reg_read(REG_VAWD2_ADDR, &value2);
1846 //printf("REG_VAWD1_ADDR value%d is 0x%x\n\r", i, value);
1847 //printf("REG_VAWD2_ADDR value%d is 0x%x\n\r", i, value2);
1848
1849 if ((value & 0x01) != 0) {
1850 printf(" %4d ", i);
1851 printf(" %2d ", ((value & 0xe) >> 1));
1852 printf(" %c", (value & 0x00010000) ? '1' : '-');
1853 printf("%c", (value & 0x00020000) ? '1' : '-');
1854 printf("%c", (value & 0x00040000) ? '1' : '-');
1855 printf("%c", (value & 0x00080000) ? '1' : '-');
1856 printf("%c", (value & 0x00100000) ? '1' : '-');
1857 printf("%c", (value & 0x00200000) ? '1' : '-');
1858 printf("%c", (value & 0x00400000) ? '1' : '-');
1859 printf("%c", (value & 0x00800000) ? '1' : '-');
1860 printf(" %4d", ((value & 0xfff0) >> 4));
1861 if (eg_tag) {
1862 printf("\t");
1863 if ((value & (0x3 << 28)) == (0x3 << 28)) {
1864 /* VTAG_EN=1 and EG_CON=1 */
1865 printf("CONSISTENT");
1866 } else if (value & (0x1 << 28)) {
1867 /* VTAG_EN=1 */
1868 printf("%d", (value2 & 0x0003) >> 0);
1869 printf("%d", (value2 & 0x000c) >> 2);
1870 printf("%d", (value2 & 0x0030) >> 4);
1871 printf("%d", (value2 & 0x00c0) >> 6);
1872 printf("%d", (value2 & 0x0300) >> 8);
1873 printf("%d", (value2 & 0x0c00) >> 10);
1874 printf("%d", (value2 & 0x3000) >> 12);
1875 printf("%d", (value2 & 0xc000) >> 14);
1876 } else {
1877 /* VTAG_EN=0 */
1878 printf("DISABLED");
1879 }
1880 }
1881 printf("\n");
1882 } else {
1883 /*print 16 vid for reference information*/
1884 if (i <= 16) {
1885 printf(" %4d ", i);
1886 printf(" %2d ", ((value & 0xe) >> 1));
1887 printf(" invalid\n");
1888 }
1889 }
1890 }
1891}
1892
1893
1894static long timespec_diff_us(struct timespec start, struct timespec end)
1895{
1896 struct timespec temp;
1897 unsigned long duration = 0;
1898
1899 if ((end.tv_nsec - start.tv_nsec) < 0) {
1900 temp.tv_sec = end.tv_sec - start.tv_sec - 1;
1901 temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
1902 } else {
1903 temp.tv_sec = end.tv_sec - start.tv_sec;
1904 temp.tv_nsec = end.tv_nsec - start.tv_nsec;
1905 }
1906 /* calculate second part*/
1907 duration += temp.tv_sec * 1000000;
1908 /* calculate ns part*/
1909 duration += temp.tv_nsec >> 10;
1910
1911 return duration;
1912}
1913
1914
1915void vlan_clear(int argc, char *argv[])
1916{
1917 unsigned int value;
1918 int vid;
1919 unsigned long duration_us = 0;
1920 struct timespec start, end;
1921
1922 for (vid = 0; vid < 4096; vid++) {
1923 clock_gettime(CLOCK_REALTIME, &start);
1924 value = 0; //invalid
1925 reg_write(REG_VAWD1_ADDR, value);
1926
1927 value = (0x80001000 + vid); //w_vid_cmd
1928 reg_write(REG_VTCR_ADDR, value);
1929 while (duration_us <= 1000) {
1930 reg_read(REG_VTCR_ADDR, &value);
1931 if ((value & 0x80000000) == 0) { //table busy
1932 break;
1933 }
1934 clock_gettime(CLOCK_REALTIME, &end);
1935 duration_us = timespec_diff_us(start, end);
1936 }
1937 if (duration_us > 1000)
1938 printf("config vlan timeout: %ld.\n", duration_us);
1939 }
1940}
1941
1942void vlan_set(int argc, char *argv[])
1943{
1944 unsigned int vlan_mem = 0;
1945 unsigned int value = 0;
1946 unsigned int value2 = 0;
1947 int i, vid, fid;
1948 int stag = 0;
1949 unsigned long eg_con = 0;
1950 unsigned int eg_tag = 0;
1951
1952 if (argc < 5) {
1953 printf("insufficient arguments!\n");
1954 return;
1955 }
1956
1957 fid = strtoul(argv[3], NULL, 0);
1958 if (fid < 0 || fid > 7) {
1959 printf("wrong filtering db id range, should be within 0~7\n");
1960 return;
1961 }
1962 value |= (fid << 1);
1963
1964 vid = strtoul(argv[4], NULL, 0);
1965 if (vid < 0 || 0xfff < vid) {
1966 printf("wrong vlan id range, should be within 0~4095\n");
1967 return;
1968 }
1969
1970 if (strlen(argv[5]) != 8) {
1971 printf("portmap format error, should be of length 7\n");
1972 return;
1973 }
1974
1975 vlan_mem = 0;
1976 for (i = 0; i < 8; i++) {
1977 if (argv[5][i] != '0' && argv[5][i] != '1') {
1978 printf("portmap format error, should be of combination of 0 or 1\n");
1979 return;
1980 }
1981 vlan_mem += (argv[5][i] - '0') * (1 << i);
1982 }
1983
1984 /* VLAN stag */
1985 if (argc > 6) {
1986 stag = strtoul(argv[6], NULL, 16);
1987 if (stag < 0 || 0xfff < stag) {
1988 printf("wrong stag id range, should be within 0~4095\n");
1989 return;
1990 }
1991 //printf("STAG is 0x%x\n", stag);
1992 }
1993
1994 /* set vlan member */
1995 value |= (vlan_mem << 16);
1996 value |= (1 << 30); //IVL=1
1997 value |= ((stag & 0xfff) << 4); //stag
1998 value |= 1; //valid
1999
2000 if (argc > 7) {
2001 eg_con = strtoul(argv[7], NULL, 2);
2002 eg_con = !!eg_con;
2003 value |= (eg_con << 29); //eg_con
2004 value |= (1 << 28); //eg tag control enable
2005 }
2006
2007 if (argc > 8 && !eg_con) {
2008 if (strlen(argv[8]) != 8) {
2009 printf("egtag portmap format error, should be of length 7\n");
2010 return;
2011 }
2012
2013 for (i = 0; i < 8; i++) {
2014 if (argv[8][i] < '0' || argv[8][i] > '3') {
2015 printf("egtag portmap format error, should be of combination of 0 or 3\n");
2016 return;
2017 }
2018 //eg_tag += (argv[8][i] - '0') * (1 << i * 2);
2019 eg_tag |= (argv[8][i] - '0') << (i * 2);
2020 }
2021
2022 value |= (1 << 28); //eg tag control enable
2023 value2 &= ~(0xffff);
2024 value2 |= eg_tag;
2025 }
2026 reg_write(REG_VAWD1_ADDR, value);
2027 reg_write(REG_VAWD2_ADDR, value2);
2028 //printf("VAWD1=0x%08x VAWD2=0x%08x ", value, value2);
2029
2030 value = (0x80001000 + vid); //w_vid_cmd
2031 reg_write(REG_VTCR_ADDR, value);
2032 //printf("VTCR=0x%08x\n", value);
2033
2034 for (i = 0; i < 300; i++) {
2035 usleep(1000);
2036 reg_read(REG_VTCR_ADDR, &value);
2037 if ((value & 0x80000000) == 0) //table busy
2038 break;
2039 }
2040
2041 if (i == 300)
2042 printf("config vlan timeout.\n");
2043}
2044
2045void igmp_on(int argc, char *argv[])
2046{
2047 unsigned int leaky_en = 0;
2048 unsigned int wan_num = 4;
2049 unsigned int port, offset, value;
2050 char cmd[80];
2051 int ret;
2052
2053 if (argc > 3)
2054 leaky_en = strtoul(argv[3], NULL, 10);
2055 if (argc > 4)
2056 wan_num = strtoul(argv[4], NULL, 10);
2057
2058 if (leaky_en == 1) {
2059 if (wan_num == 4) {
2060 /* reg_write(0x2410, 0x810000c8); */
2061 reg_read(0x2410, &value);
2062 reg_write(0x2410, value | (1 << 3));
2063 /* reg_write(0x2010, 0x810000c0); */
2064 reg_read(0x2010, &value);
2065 reg_write(0x2010, value & (~(1 << 3)));
2066 reg_write(REG_ISC_ADDR, 0x10027d10);
2067 } else {
2068 /* reg_write(0x2010, 0x810000c8); */
2069 reg_read(0x2010, &value);
2070 reg_write(0x2010, value | (1 << 3));
2071 /* reg_write(0x2410, 0x810000c0); */
2072 reg_read(0x2410, &value);
2073 reg_write(0x2410, value & (~(1 << 3)));
2074 reg_write(REG_ISC_ADDR, 0x01027d01);
2075 }
2076 }
2077 else
2078 reg_write(REG_ISC_ADDR, 0x10027d60);
2079
2080 reg_write(0x1c, 0x08100810);
2081 reg_write(0x2008, 0xb3ff);
2082 reg_write(0x2108, 0xb3ff);
2083 reg_write(0x2208, 0xb3ff);
2084 reg_write(0x2308, 0xb3ff);
2085 reg_write(0x2408, 0xb3ff);
2086 reg_write(0x2608, 0xb3ff);
2087 /* Enable Port ACL
2088 * reg_write(0x2P04, 0xff0403);
2089 */
2090 for (port = 0; port <= 6; port++) {
2091 offset = 0x2004 + port * 0x100;
2092 reg_read(offset, &value);
2093 reg_write(offset, value | (1 << 10));
2094 }
2095
2096 /*IGMP query only p4 -> p5*/
2097 reg_write(0x94, 0x00ff0002);
2098 if (wan_num == 4)
2099 reg_write(0x98, 0x000a1008);
2100 else
2101 reg_write(0x98, 0x000a0108);
2102 reg_write(0x90, 0x80005000);
2103 reg_write(0x94, 0xff001100);
2104 if (wan_num == 4)
2105 reg_write(0x98, 0x000B1000);
2106 else
2107 reg_write(0x98, 0x000B0100);
2108 reg_write(0x90, 0x80005001);
2109 reg_write(0x94, 0x3);
2110 reg_write(0x98, 0x0);
2111 reg_write(0x90, 0x80009000);
2112 reg_write(0x94, 0x1a002080);
2113 reg_write(0x98, 0x0);
2114 reg_write(0x90, 0x8000b000);
2115
2116 /*IGMP p5 -> p4*/
2117 reg_write(0x94, 0x00ff0002);
2118 reg_write(0x98, 0x000a2008);
2119 reg_write(0x90, 0x80005002);
2120 reg_write(0x94, 0x4);
2121 reg_write(0x98, 0x0);
2122 reg_write(0x90, 0x80009001);
2123 if (wan_num == 4)
2124 reg_write(0x94, 0x1a001080);
2125 else
2126 reg_write(0x94, 0x1a000180);
2127 reg_write(0x98, 0x0);
2128 reg_write(0x90, 0x8000b001);
2129
2130 /*IGMP p0~p3 -> p6*/
2131 reg_write(0x94, 0x00ff0002);
2132 if (wan_num == 4)
2133 reg_write(0x98, 0x000a0f08);
2134 else
2135 reg_write(0x98, 0x000a1e08);
2136 reg_write(0x90, 0x80005003);
2137 reg_write(0x94, 0x8);
2138 reg_write(0x98, 0x0);
2139 reg_write(0x90, 0x80009002);
2140 reg_write(0x94, 0x1a004080);
2141 reg_write(0x98, 0x0);
2142 reg_write(0x90, 0x8000b002);
2143
2144 /*IGMP query only p6 -> p0~p3*/
2145 reg_write(0x94, 0x00ff0002);
2146 reg_write(0x98, 0x000a4008);
2147 reg_write(0x90, 0x80005004);
2148 reg_write(0x94, 0xff001100);
2149 reg_write(0x98, 0x000B4000);
2150 reg_write(0x90, 0x80005005);
2151 reg_write(0x94, 0x30);
2152 reg_write(0x98, 0x0);
2153 reg_write(0x90, 0x80009003);
2154 if (wan_num == 4)
2155 reg_write(0x94, 0x1a000f80);
2156 else
2157 reg_write(0x94, 0x1a001e80);
2158 reg_write(0x98, 0x0);
2159 reg_write(0x90, 0x8000b003);
2160
2161 /*Force eth2 to receive all igmp packets*/
2162 snprintf(cmd, sizeof(cmd), "echo 2 > /sys/devices/virtual/net/%s/brif/%s/multicast_router", BR_DEVNAME, ETH_DEVNAME);
2163 ret = system(cmd);
2164 if (ret)
2165 printf("Failed to set /sys/devices/virtual/net/%s/brif/%s/multicast_router\n",
2166 BR_DEVNAME, ETH_DEVNAME);
2167}
2168
2169void igmp_disable(int argc, char *argv[])
2170{
2171 unsigned int reg_offset, value;
2172 int port_num;
2173
2174 if (argc < 4) {
2175 printf("insufficient arguments!\n");
2176 return;
2177 }
2178 port_num = strtoul(argv[3], NULL, 0);
2179 if (port_num < 0 || 6 < port_num) {
2180 printf("wrong port range, should be within 0~6\n");
2181 return;
2182 }
2183
2184 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2185 reg_offset = 0x2008;
2186 reg_offset |= (port_num << 8);
2187 value = 0x8000;
2188
2189 reg_write(reg_offset, value);
2190}
2191
2192void igmp_enable(int argc, char *argv[])
2193{
2194 unsigned int reg_offset, value;
2195 int port_num;
2196
2197 if (argc < 4) {
2198 printf("insufficient arguments!\n");
2199 return;
2200 }
2201 port_num = strtoul(argv[3], NULL, 0);
2202 if (port_num < 0 || 6 < port_num) {
2203 printf("wrong port range, should be within 0~6\n");
2204 return;
2205 }
2206
2207 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2208 reg_offset = 0x2008;
2209 reg_offset |= (port_num << 8);
2210 value = 0x9755;
2211 reg_write(reg_offset, value);
2212}
2213
2214void igmp_off()
2215{
2216 unsigned int value;
2217 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2218 reg_read(REG_ISC_ADDR, &value);
2219 value &= ~(1 << 18); //disable
2220 reg_write(REG_ISC_ADDR, value);
2221
2222 /*restore wan port multicast leaky vlan function: default disabled*/
2223 reg_read(0x2010, &value);
2224 reg_write(0x2010, value & (~(1 << 3)));
2225 reg_read(0x2410, &value);
2226 reg_write(0x2410, value & (~(1 << 3)));
2227
2228 printf("config igmpsnoop off.\n");
2229}
2230
2231void switch_reset(int argc, char *argv[])
2232{
2233 unsigned int value = 0;
2234 /*Software Register Reset and Software System Reset */
2235 reg_write(0x7000, 0x3);
2236 reg_read(0x7000, &value);
2237 printf("SYS_CTRL(0x7000) register value =0x%x \n", value);
2238 if (chip_name == 0x7531) {
2239 reg_write(0x7c0c, 0x11111111);
2240 reg_read(0x7c0c, &value);
2241 printf("GPIO Mode (0x7c0c) select value =0x%x \n", value);
2242 }
2243 printf("Switch Software Reset !!! \n");
2244}
2245
2246int phy_set_fc(int argc, char *argv[])
2247{
2248 unsigned int port, pause_capable;
2249 unsigned int phy_value;
2250
2251 port = atoi(argv[3]);
2252 pause_capable = atoi(argv[4]);
2253
2254 /*Check the input parameters is right or not.*/
2255 if (port > MAX_PORT - 2 || pause_capable > 1) {
2256 printf("Illegal parameter (port:0~4, full_duplex_pause_capable:0|1)\n");
2257 return -1;
2258 }
2259 printf("port=%d, full_duplex_pause_capable:%d\n", port, pause_capable);
2260 mii_mgr_read(port, 4, &phy_value);
2261 printf("read phy_value:0x%x\r\n", phy_value);
2262 phy_value &= (~(0x1 << 10));
2263 phy_value &= (~(0x1 << 11));
2264 if (pause_capable == 1) {
2265 phy_value |= (0x1 << 10);
2266 phy_value |= (0x1 << 11);
2267 }
2268 mii_mgr_write(port, 4, phy_value);
2269 printf("write phy_value:0x%x\r\n", phy_value);
2270 return 0;
2271} /*end phy_set_fc*/
2272
2273int phy_set_an(int argc, char *argv[])
2274{
2275 unsigned int port, auto_negotiation_en;
2276 unsigned int phy_value;
2277
2278 port = atoi(argv[3]);
2279 auto_negotiation_en = atoi(argv[4]);
2280
2281 /*Check the input parameters is right or not.*/
2282 if (port > MAX_PORT - 2 || auto_negotiation_en > 1) {
2283 printf("Illegal parameter (port:0~4, auto_negotiation_en:0|1)\n");
2284 return -1;
2285 }
2286 printf("port=%d, auto_negotiation_en:%d\n", port, auto_negotiation_en);
2287 mii_mgr_read(port, 0, &phy_value);
2288 printf("read phy_value:0x%x\r\n", phy_value);
2289 phy_value &= (~(1 << 12));
2290 phy_value |= (auto_negotiation_en << 12);
2291 mii_mgr_write(port, 0, phy_value);
2292 printf("write phy_value:0x%x\r\n", phy_value);
2293 return 0;
2294} /*end phy_set_an*/
2295
2296int set_mac_pfc(int argc, char *argv[])
2297{
2298 unsigned int value;
2299 int port, enable = 0;
2300
2301 port = atoi(argv[3]);
2302 enable = atoi(argv[4]);
2303 printf("enable: %d\n", enable);
2304 if (port < 0 || port > 6 || enable < 0 || enable > 1) {
2305 printf("Illegal parameter (port:0~6, enable|diable:0|1) \n");
2306 return -1;
2307 }
2308 if (chip_name == 0x7531) {
2309 reg_read(REG_PFC_CTRL_ADDR, &value);
2310 value &= ~(1 << port);
2311 value |= (enable << port);
2312 printf("write reg: %x, value: %x\n", REG_PFC_CTRL_ADDR, value);
2313 reg_write(REG_PFC_CTRL_ADDR, value);
2314 }
2315 else
2316 printf("\nCommand not support by this chip.\n");
2317 return 0;
2318}
2319
2320int global_set_mac_fc(int argc, char *argv[])
2321{
2322 unsigned char enable = 0;
2323 unsigned int value, reg;
2324
2325 if (chip_name == 0x7530) {
2326 enable = atoi(argv[3]);
2327 printf("enable: %d\n", enable);
2328
2329 /*Check the input parameters is right or not.*/
2330 if (enable > 1) {
2331 printf(HELP_MACCTL_FC);
2332 return -1;
2333 }
2334 reg_write(0x7000, 0x3);
2335 reg = REG_GFCCR0_ADDR;
2336 reg_read(REG_GFCCR0_ADDR, &value);
2337 value &= (~REG_FC_EN_MASK);
2338 value |= (enable << REG_FC_EN_OFFT);
2339 printf("write reg: %x, value: %x\n", reg, value);
2340 reg_write(REG_GFCCR0_ADDR, value);
2341 } else
2342 printf("\r\nCommand not support by this chip.\n");
2343 return 0;
2344} /*end mac_set_fc*/
2345
2346int qos_sch_select(int argc, char *argv[])
2347{
2348 unsigned char port, queue;
2349 unsigned char type = 0;
2350 unsigned int value, reg;
2351
2352 if (argc < 7)
2353 return -1;
2354
2355 port = atoi(argv[3]);
2356 queue = atoi(argv[4]);
2357 type = atoi(argv[6]);
2358
2359 if (port > 6 || queue > 7) {
2360 printf("\n Illegal input parameters\n");
2361 return -1;
2362 }
2363
2364 if ((type != 0 && type != 1 && type != 2)) {
2365 printf(HELP_QOS_TYPE);
2366 return -1;
2367 }
2368
2369 printf("\r\nswitch qos type: %d.\n",type);
2370
2371 if (!strncmp(argv[5], "min", 4)) {
2372
2373 if (type == 0) {
2374 /*min sharper-->round roubin, disable min sharper rate limit*/
2375 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2376 reg_read(reg, &value);
2377 value = 0x0;
2378 reg_write(reg, value);
2379 } else if (type == 1) {
2380 /*min sharper-->sp, disable min sharper rate limit*/
2381 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2382 reg_read(reg, &value);
2383 value = 0x0;
2384 value |= (1 << 31);
2385 reg_write(reg, value);
2386 } else {
2387 printf("min sharper only support: rr or sp\n");
2388 return -1;
2389 }
2390 } else if (!strncmp(argv[5], "max", 4)) {
2391 if (type == 1) {
2392 /*max sharper-->sp, disable max sharper rate limit*/
2393 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2394 reg_read(reg, &value);
2395 value = 0x0;
2396 value |= (1 << 31);
2397 reg_write(reg, value);
2398 } else if (type == 2) {
2399 /*max sharper-->wfq, disable max sharper rate limit*/
2400 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2401 reg_read(reg, &value);
2402 value = 0x0;
2403 reg_write(reg, value);
2404 } else {
2405 printf("max sharper only support: wfq or sp\n");
2406 return -1;
2407 }
2408 } else {
2409 printf("\r\nIllegal sharper:%s\n",argv[5]);
2410 return -1;
2411 }
2412 printf("reg:0x%x--value:0x%x\n",reg,value);
2413
2414 return 0;
2415}
2416
2417void get_upw(unsigned int *value, unsigned char base)
2418{
2419 *value &= (~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
2420 (0x7 << 16) | (0x7 << 20)));
2421 switch (base)
2422 {
2423 case 0: /* port-based 0x2x40[18:16] */
2424 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2425 (0x2 << 12) | (0x7 << 16) | (0x2 << 20));
2426 break;
2427 case 1: /* tagged-based 0x2x40[10:8] */
2428 *value |= ((0x2 << 0) | (0x2 << 4) | (0x7 << 8) |
2429 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2430 break;
2431 case 2: /* DSCP-based 0x2x40[14:12] */
2432 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2433 (0x7 << 12) | (0x2 << 16) | (0x2 << 20));
2434 break;
2435 case 3: /* acl-based 0x2x40[2:0] */
2436 *value |= ((0x7 << 0) | (0x2 << 4) | (0x2 << 8) |
2437 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2438 break;
2439 case 4: /* arl-based 0x2x40[22:20] */
2440 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2441 (0x2 << 12) | (0x2 << 16) | (0x7 << 20));
2442 break;
2443 case 5: /* stag-based 0x2x40[6:4] */
2444 *value |= ((0x2 << 0) | (0x7 << 4) | (0x2 << 8) |
2445 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2446 break;
2447 default:
2448 break;
2449 }
2450}
2451
2452void qos_set_base(int argc, char *argv[])
2453{
2454 unsigned char base = 0;
2455 unsigned char port;
2456 unsigned int value;
2457
2458 if (argc < 5)
2459 return;
2460
2461 port = atoi(argv[3]);
2462 base = atoi(argv[4]);
2463
2464 if (base > 6) {
2465 printf(HELP_QOS_BASE);
2466 return;
2467 }
2468
2469 if (port > 6) {
2470 printf("Illegal port index:%d\n",port);
2471 return;
2472 }
2473
2474 printf("\r\nswitch qos base : %d. (port-based:0, tag-based:1,\
2475 dscp-based:2, acl-based:3, arl-based:4, stag-based:5)\n",
2476 base);
2477 if (chip_name == 0x7530) {
2478
2479 reg_read(0x44, &value);
2480 get_upw(&value, base);
2481 reg_write(0x44, value);
2482 printf("reg: 0x44, value: 0x%x\n", value);
2483
2484 } else if (chip_name == 0x7531) {
2485
2486 reg_read(GSW_UPW(port), &value);
2487 get_upw(&value, base);
2488 reg_write(GSW_UPW(port), value);
2489 printf("reg:0x%x, value: 0x%x\n",GSW_UPW(port),value);
2490
2491 } else {
2492 printf("unknown switch device");
2493 return;
2494 }
2495}
2496
2497void qos_wfq_set_weight(int argc, char *argv[])
2498{
2499 int port, weight[8], i;
2500 unsigned char queue;
2501 unsigned int reg, value;
2502
2503 port = atoi(argv[3]);
2504
2505 for (i = 0; i < 8; i++) {
2506 weight[i] = atoi(argv[i + 4]);
2507 }
2508
2509 /* MT7530 total 7 port */
2510 if (port < 0 || port > 6) {
2511 printf(HELP_QOS_PORT_WEIGHT);
2512 return;
2513 }
2514
2515 for (i = 0; i < 8; i++) {
2516 if (weight[i] < 1 || weight[i] > 16) {
2517 printf(HELP_QOS_PORT_WEIGHT);
2518 return;
2519 }
2520 }
2521 printf("port: %x, q0: %x, q1: %x, q2: %x, q3: %x, \
2522 q4: %x, q5: %x, q6: %x, q7: %x\n",
2523 port, weight[0], weight[1], weight[2], weight[3], weight[4],
2524 weight[5], weight[6], weight[7]);
2525
2526 for (queue = 0; queue < 8; queue++) {
2527 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2528 reg_read(reg, &value);
2529 value &= (~(0xf << 24)); //bit24~27
2530 value |= (((weight[queue] - 1) & 0xf) << 24);
2531 printf("reg: %x, value: %x\n", reg, value);
2532 reg_write(reg, value);
2533 }
2534}
2535
2536void qos_set_portpri(int argc, char *argv[])
2537{
2538 unsigned char port, prio;
2539 unsigned int value;
2540
2541 port = atoi(argv[3]);
2542 prio = atoi(argv[4]);
2543
2544