blob: 92f0e12fbd09f7b6e6ea5cb63df16e0ffad585cc [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001/*
2* switch_fun.c: switch function sets
3*/
4#include <stdio.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <string.h>
8#include <stdbool.h>
9#include <sys/ioctl.h>
10#include <sys/socket.h>
11#include <linux/if.h>
12#include <stdbool.h>
13#include <time.h>
14
15#include "switch_extend.h"
16#include "switch_netlink.h"
17#include "switch_ioctl.h"
18#include "switch_fun.h"
19
20#define leaky_bucket 0
21
22static int getnext(char *src, int separator, char *dest)
23{
24 char *c;
25 int len;
26
27 if ((src == NULL) || (dest == NULL))
28 return -1;
29
30 c = strchr(src, separator);
31 if (c == NULL)
32 return -1;
33
34 len = c - src;
35 strncpy(dest, src, len);
36 dest[len] = '\0';
37 return len + 1;
38}
39
40static int str_to_ip(unsigned int *ip, char *str)
41{
42 int i;
43 int len;
44 char *ptr = str;
45 char buf[128];
46 unsigned char c[4];
47
48 for (i = 0; i < 3; ++i) {
49 if ((len = getnext(ptr, '.', buf)) == -1)
50 return 1;
51 c[i] = atoi(buf);
52 ptr += len;
53 }
54 c[3] = atoi(ptr);
55 *ip = (c[0] << 24) + (c[1] << 16) + (c[2] << 8) + c[3];
56 return 0;
57}
58
59/*convert IP address from number to string */
60static void ip_to_str(char *str, unsigned int ip)
61{
62 unsigned char *ptr = (unsigned char *)&ip;
63 unsigned char c[4];
64
65 c[0] = *(ptr);
66 c[1] = *(ptr + 1);
67 c[2] = *(ptr + 2);
68 c[3] = *(ptr + 3);
69 /*sprintf(str, "%d.%d.%d.%d", c[0], c[1], c[2], c[3]);*/
70 sprintf(str, "%d.%d.%d.%d", c[3], c[2], c[1], c[0]);
71}
72
73int reg_read(unsigned int offset, unsigned int *value)
74{
75 int ret = -1;
76
77 if (nl_init_flag == true) {
78 ret = reg_read_netlink(attres, offset, value);
79 } else {
80 if (attres->dev_id == -1)
81 ret = reg_read_ioctl(offset, value);
82 }
83 if (ret < 0) {
84 printf("Read fail\n");
85 *value = 0;
86 return ret;
87 }
88
89 return 0;
90}
91
92int reg_write(unsigned int offset, unsigned int value)
93{
94 int ret = -1;
95
96 if (nl_init_flag == true) {
97 ret = reg_write_netlink(attres, offset, value);
98 } else {
99 if (attres->dev_id == -1)
100 ret = reg_write_ioctl(offset, value);
101 }
102 if (ret < 0) {
103 printf("Write fail\n");
104 exit_free();
105 exit(0);
106 }
107 return 0;
108}
109
110int mii_mgr_read(unsigned int port_num, unsigned int reg, unsigned int *value)
111{
112 int ret;
113
114 if (port_num > 31) {
115 printf("Invalid Port or PHY addr \n");
116 return -1;
117 }
118
119 if (nl_init_flag == true)
120 ret = phy_cl22_read_netlink(attres, port_num, reg, value);
121 else
122 ret = mii_mgr_cl22_read_ioctl(port_num, reg, value);
123
124 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800125 printf("Phy cl22 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800126 exit_free();
127 exit(0);
128 }
129
130 return 0;
131}
132
133int mii_mgr_write(unsigned int port_num, unsigned int reg, unsigned int value)
134{
135 int ret;
136
137 if (port_num > 31) {
138 printf("Invalid Port or PHY addr \n");
139 return -1;
140 }
141
142 if (nl_init_flag == true)
143 ret = phy_cl22_write_netlink(attres, port_num, reg, value);
144 else
145 ret = mii_mgr_cl22_write_ioctl(port_num, reg, value);
146
147 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800148 printf("Phy cl22 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800149 exit_free();
150 exit(0);
151 }
152
153 return 0;
154}
155
156int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int *value)
157{
158 int ret;
159
160 if (port_num > 31) {
161 printf("Invalid Port or PHY addr \n");
162 return -1;
163 }
164
165 if (nl_init_flag == true)
166 ret = phy_cl45_read_netlink(attres, port_num, dev, reg, value);
167 else
168 ret = mii_mgr_cl45_read_ioctl(port_num, dev, reg, value);
169
170 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800171 printf("Phy cl45 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800172 exit_free();
173 exit(0);
174 }
175
176 return 0;
177}
178
179int mii_mgr_c45_write(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int value)
180{
181 int ret;
182
183 if (port_num > 31) {
184 printf("Invalid Port or PHY addr \n");
185 return -1;
186 }
187
188 if (nl_init_flag == true)
189 ret = phy_cl45_write_netlink(attres, port_num, dev, reg, value);
190 else
191 ret = mii_mgr_cl45_write_ioctl(port_num, dev, reg, value);
192
193 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800194 printf("Phy cl45 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800195 exit_free();
196 exit(0);
197 }
198
199 return 0;
200}
201
202
203int phy_dump(int phy_addr)
204{
205 int ret;
206
207 if (nl_init_flag == true)
208 ret = phy_dump_netlink(attres, phy_addr);
209 else
210 ret = phy_dump_ioctl(phy_addr);
211
212 if (ret < 0) {
213 printf("Phy dump fail\n");
214 exit_free();
215 exit(0);
216 }
217
218 return 0;
219}
220
221void phy_crossover(int argc, char *argv[])
222{
223 unsigned int port_num = strtoul(argv[2], NULL, 10);
224 unsigned int value;
225 int ret;
226
227 if (port_num > 4) {
228 printf("invaild value, port_name:0~4\n");
229 return;
230 }
231
232 if (nl_init_flag == true)
233 ret = phy_cl45_read_netlink(attres, port_num, 0x1E, MT7530_T10_TEST_CONTROL, &value);
234 else
235 ret = mii_mgr_cl45_read_ioctl(port_num, 0x1E, MT7530_T10_TEST_CONTROL, &value);
236 if (ret < 0) {
237 printf("phy_cl45 read fail\n");
238 exit_free();
239 exit(0);
240 }
241
242 printf("mii_mgr_cl45:");
243 printf("Read: port#=%d, device=0x%x, reg=0x%x, value=0x%x\n", port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
244
245 if (!strncmp(argv[3], "auto", 5))
246 {
247 value &= (~(0x3 << 3));
248 } else if (!strncmp(argv[3], "mdi", 4)) {
249 value &= (~(0x3 << 3));
250 value |= (0x2 << 3);
251 } else if (!strncmp(argv[3], "mdix", 5)) {
252 value |= (0x3 << 3);
253 } else {
254 printf("invaild parameter\n");
255 return;
256 }
257 printf("Write: port#=%d, device=0x%x, reg=0x%x. value=0x%x\n", port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
258
259 if (nl_init_flag == true)
260 ret = phy_cl45_write_netlink(attres, port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
261 else
262 ret = mii_mgr_cl45_write_ioctl(port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
263
264 if (ret < 0) {
265 printf("phy_cl45 write fail\n");
266 exit_free();
267 exit(0);
268 }
269}
270
271int rw_phy_token_ring(int argc, char *argv[])
272{
273 int ch_addr, node_addr, data_addr;
274 unsigned int tr_reg_control;
275 unsigned int val_l = 0;
276 unsigned int val_h = 0;
277 unsigned int port_num;
278
279 if (argc < 4)
280 return -1;
281
282 if (argv[2][0] == 'r') {
283 if (argc != 7)
284 return -1;
285 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
286 port_num = strtoul(argv[3], NULL, 0);
287 if (port_num > MAX_PORT) {
288 printf("Illegal port index and port:0~6\n");
289 return -1;
290 }
291 ch_addr = strtoul(argv[4], NULL, 0);
292 node_addr = strtoul(argv[5], NULL, 0);
293 data_addr = strtoul(argv[6], NULL, 0);
294 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n", port_num, ch_addr, node_addr, data_addr);
295 tr_reg_control = (1 << 15) | (1 << 13) | (ch_addr << 11) | (node_addr << 7) | (data_addr << 1);
296 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
297 mii_mgr_read(port_num, 17, &val_l);
298 mii_mgr_read(port_num, 18, &val_h);
299 printf("switch trreg read tr_reg_control=%x, value_H=%x, value_L=%x\n", tr_reg_control, val_h, val_l);
300 } else if (argv[2][0] == 'w') {
301 if (argc != 9)
302 return -1;
303 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
304 port_num = strtoul(argv[3], NULL, 0);
305 if (port_num > MAX_PORT) {
306 printf("\n**Illegal port index and port:0~6\n");
307 return -1;
308 }
309 ch_addr = strtoul(argv[4], NULL, 0);
310 node_addr = strtoul(argv[5], NULL, 0);
311 data_addr = strtoul(argv[6], NULL, 0);
312 val_h = strtoul(argv[7], NULL, 0);
313 val_l = strtoul(argv[8], NULL, 0);
314 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n", port_num, ch_addr, node_addr, data_addr);
315 tr_reg_control = (1 << 15) | (0 << 13) | (ch_addr << 11) | (node_addr << 7) | (data_addr << 1);
316 mii_mgr_write(port_num, 17, val_l);
317 mii_mgr_write(port_num, 18, val_h);
318 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
319 printf("switch trreg Write tr_reg_control=%x, value_H=%x, value_L=%x\n", tr_reg_control, val_h, val_l);
320 } else
321 return -1;
322 return 0;
323}
324
325void write_acl_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2)
326{
327 unsigned int value, reg;
328 unsigned int max_index;
329
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 if (port >= 7 || prio > 7) {
2545 printf(HELP_QOS_PORT_PRIO);
2546 return;
2547 }
2548
2549 reg_read(GSW_PCR(port), &value);
2550 value &= (~(0x7 << 24));
2551 value |= (prio << 24);
2552 reg_write(GSW_PCR(port), value);
2553 printf("write reg: %x, value: %x\n", GSW_PCR(port), value);
2554}
2555
2556void qos_set_dscppri(int argc, char *argv[])
2557{
2558 unsigned char prio, dscp, pim_n, pim_offset;
2559 unsigned int reg, value;
2560
2561 dscp = atoi(argv[3]);
2562 prio = atoi(argv[4]);
2563
2564 if (dscp > 63 || prio > 7) {
2565 printf(HELP_QOS_DSCP_PRIO);
2566 return;
2567 }
2568
2569 pim_n = dscp / 10;
2570 pim_offset = (dscp - pim_n * 10) * 3;
2571 reg = 0x0058 + pim_n * 4;
2572 reg_read(reg, &value);
2573 value &= (~(0x7 << pim_offset));
2574 value |= ((prio & 0x7) << pim_offset);
2575 reg_write(reg, value);
2576 printf("write reg: %x, value: %x\n", reg, value);
2577}
2578
2579void qos_pri_mapping_queue(int argc, char *argv[])
2580{
2581 unsigned char prio, queue, pem_n, port;
2582 unsigned int reg, value;
2583
2584 if (argc < 6)
2585 return;
2586
2587 port = atoi(argv[3]);
2588 prio = atoi(argv[4]);
2589 queue = atoi(argv[5]);
2590
2591 if (prio > 7 || queue > 7) {
2592 printf(HELP_QOS_PRIO_QMAP);
2593 return;
2594 }
2595 if (chip_name == 0x7530) {
2596 pem_n = prio / 2;
2597 reg = pem_n * 0x4 + 0x48;
2598 reg_read(reg, &value);
2599 if (prio % 2) {
2600 value &= (~(0x7 << 24));
2601 value |= ((queue & 0x7) << 24);
2602 } else {
2603 value &= (~(0x7 << 8));
2604 value |= ((queue & 0x7) << 8);
2605 }
2606 reg_write(reg, value);
2607 printf("write reg: %x, value: %x\n", reg, value);
2608 } else if (chip_name == 0x7531) {
2609 pem_n = prio / 2;
2610 reg = GSW_PEM(pem_n) + 0x100 * port;
2611 reg_read(reg, &value);
2612 if (prio % 2) { // 1 1
2613 value &= (~(0x7 << 25));
2614 value |= ((queue & 0x7) << 25);
2615 } else { // 0 0
2616 value &= (~(0x7 << 9));
2617 value |= ((queue & 0x7) << 9);
2618 }
2619 reg_write(reg, value);
2620 printf("write reg: %x, value: %x\n", reg, value);
2621 }
2622 else {
2623 printf("unknown switch device");
2624 return;
2625 }
2626}
2627
2628static int macMT753xVlanSetVid(unsigned char index, unsigned char active,
2629 unsigned short vid, unsigned char portMap, unsigned char tagPortMap,
2630 unsigned char ivl_en, unsigned char fid, unsigned short stag)
2631{
2632 unsigned int value = 0;
2633 unsigned int value2 = 0;
2634 unsigned int reg;
2635 int i;
2636
2637 printf("index: %x, active: %x, vid: %x, portMap: %x, \
2638 tagPortMap: %x, ivl_en: %x, fid: %x, stag: %x\n",
2639 index, active, vid, portMap, tagPortMap, ivl_en, fid, stag);
2640
2641 value = (portMap << 16);
2642 value |= (stag << 4);
2643 value |= (ivl_en << 30);
2644 value |= (fid << 1);
2645 value |= (active ? 1 : 0);
2646
2647 // total 7 ports
2648 for (i = 0; i < 7; i++) {
2649 if (tagPortMap & (1 << i))
2650 value2 |= 0x2 << (i * 2);
2651 }
2652
2653 if (value2)
2654 value |= (1 << 28); // eg_tag
2655
2656 reg = 0x98; // VAWD2
2657 reg_write(reg, value2);
2658
2659 reg = 0x94; // VAWD1
2660 reg_write(reg, value);
2661
2662 reg = 0x90; // VTCR
2663 value = (0x80001000 + vid);
2664 reg_write(reg, value);
2665
2666 reg = 0x90; // VTCR
2667 while (1) {
2668 reg_read(reg, &value);
2669 if ((value & 0x80000000) == 0) //table busy
2670 break;
2671 }
2672
2673 /* switch clear */
2674 reg = 0x80;
2675 reg_write(reg, 0x8002);
2676 usleep(5000);
2677 reg_read(reg, &value);
2678
2679 printf("SetVid: index:%d active:%d vid:%d portMap:%x tagPortMap:%x\r\n",
2680 index, active, vid, portMap, tagPortMap);
2681 return 0;
2682
2683} /*end macMT753xVlanSetVid*/
2684/*
2685static int macMT753xVlanGetVtbl(unsigned short index)
2686{
2687 unsigned int reg, value, vawd1, vawd2;
2688
2689 reg = 0x90; // VTCR
2690 value = (0x80000000 + index);
2691
2692 reg_write(reg, value);
2693
2694 reg = 0x90; // VTCR
2695 while (1) {
2696 reg_read(reg, &value);
2697 if ((value & 0x80000000) == 0) //table busy
2698 break;
2699 }
2700
2701 reg = 0x94; // VAWD1
2702 reg_read(reg, &vawd1);
2703
2704 reg = 0x98; // VAWD2
2705 reg_read(reg, &vawd2);
2706
2707 if (vawd1 & 0x1) {
2708 fprintf(stderr, "%d.%s vid:%d fid:%d portMap:0x%x \
2709 tagMap:0x%x stag:0x%x ivl_en:0x%x\r\n",
2710 index, (vawd1 & 0x1) ? "on" : "off", index, ((vawd1 & 0xe) >> 1),
2711 (vawd1 & 0xff0000) >> 16, vawd2, (vawd1 & 0xfff0) >> 0x4, (vawd1 >> 30) & 0x1);
2712 }
2713 return 0;
2714} */ /*end macMT753xVlanGetVtbl*/
2715
2716static int macMT753xVlanSetPvid(unsigned char port, unsigned short pvid)
2717{
2718 unsigned int value;
2719 unsigned int reg;
2720
2721 /*Parameters is error*/
2722 if (port > 6)
2723 return -1;
2724
2725 reg = 0x2014 + (port * 0x100);
2726 reg_read(reg, &value);
2727 value &= ~0xfff;
2728 value |= pvid;
2729 reg_write(reg, value);
2730
2731 /* switch clear */
2732 reg = 0x80;
2733 reg_write(reg, 0x8002);
2734 usleep(5000);
2735 reg_read(reg, &value);
2736
2737 printf("SetPVID: port:%d pvid:%d\r\n", port, pvid);
2738 return 0;
2739}
2740/*
2741static int macMT753xVlanGetPvid(unsigned char port)
2742{
2743 unsigned int value;
2744 unsigned int reg;
2745
2746 if (port > 6)
2747 return -1;
2748 reg = 0x2014 + (port * 0x100);
2749 reg_read(reg, &value);
2750 return (value & 0xfff);
2751} */
2752/*
2753static int macMT753xVlanDisp(void)
2754{
2755 unsigned int i = 0;
2756 unsigned int reg, value;
2757
2758 reg = 0x2604;
2759 reg_read(reg, &value);
2760 value &= 0x30000000;
2761
2762 fprintf(stderr, "VLAN function is %s\n", value ? ETHCMD_ENABLE : ETHCMD_DISABLE);
2763 fprintf(stderr, "PVID e0:%02d e1:%02d e2:%02d e3:%02d e4:%02d e5:%02d e6:%02d\n",
2764 macMT753xVlanGetPvid(0), macMT753xVlanGetPvid(1), macMT753xVlanGetPvid(2),
2765 macMT753xVlanGetPvid(3), macMT753xVlanGetPvid(4), macMT753xVlanGetPvid(5), macMT753xVlanGetPvid(6));
2766
2767 for (i = 0; i < MAX_VID_VALUE; i++)
2768 macMT753xVlanGetVtbl(i);
2769
2770 return 0;
2771}*/ /*end macMT753xVlanDisp*/
2772
2773void doVlanSetPvid(int argc, char *argv[])
2774{
2775 unsigned char port = 0;
2776 unsigned short pvid = 0;
2777
2778 port = atoi(argv[3]);
2779 pvid = atoi(argv[4]);
2780 /*Check the input parameters is right or not.*/
2781 if ((port >= SWITCH_MAX_PORT) || (pvid > MAX_VID_VALUE)) {
2782 printf(HELP_VLAN_PVID);
2783 return;
2784 }
2785
2786 macMT753xVlanSetPvid(port, pvid);
2787
2788 printf("port:%d pvid:%d,vlancap: max_port:%d maxvid:%d\r\n",
2789 port, pvid, SWITCH_MAX_PORT, MAX_VID_VALUE);
2790} /*end doVlanSetPvid*/
2791
2792void doVlanSetVid(int argc, char *argv[])
2793{
2794 unsigned char index = 0;
2795 unsigned char active = 0;
2796 unsigned char portMap = 0;
2797 unsigned char tagPortMap = 0;
2798 unsigned short vid = 0;
2799
2800 unsigned char ivl_en = 0;
2801 unsigned char fid = 0;
2802 unsigned short stag = 0;
2803
2804 index = atoi(argv[3]);
2805 active = atoi(argv[4]);
2806 vid = atoi(argv[5]);
2807
2808 /*Check the input parameters is right or not.*/
2809 if ((index >= MAX_VLAN_RULE) || (vid >= 4096) || (active > ACTIVED)) {
2810 printf(HELP_VLAN_VID);
2811 return;
2812 }
2813
2814 /*CPU Port is always the membership*/
2815 portMap = atoi(argv[6]);
2816 tagPortMap = atoi(argv[7]);
2817
2818 printf("subcmd parameter argc = %d\r\n", argc);
2819 if (argc >= 9) {
2820 ivl_en = atoi(argv[8]);
2821 if (argc >= 10) {
2822 fid = atoi(argv[9]);
2823 if (argc >= 11)
2824 stag = atoi(argv[10]);
2825 }
2826 }
2827 macMT753xVlanSetVid(index, active, vid, portMap, tagPortMap,
2828 ivl_en, fid, stag);
2829 printf("index:%d active:%d vid:%d\r\n", index, active, vid);
2830} /*end doVlanSetVid*/
2831
2832void doVlanSetAccFrm(int argc, char *argv[])
2833{
2834 unsigned char port = 0;
2835 unsigned char type = 0;
2836 unsigned int value;
2837 unsigned int reg;
2838
2839 port = atoi(argv[3]);
2840 type = atoi(argv[4]);
2841
2842 printf("port: %d, type: %d\n", port, type);
2843
2844 /*Check the input parameters is right or not.*/
2845 if ((port > SWITCH_MAX_PORT) || (type > REG_PVC_ACC_FRM_RELMASK)) {
2846 printf(HELP_VLAN_ACC_FRM);
2847 return;
2848 }
2849
2850 reg = REG_PVC_P0_ADDR + port * 0x100;
2851 reg_read(reg, &value);
2852 value &= (~REG_PVC_ACC_FRM_MASK);
2853 value |= ((unsigned int)type << REG_PVC_ACC_FRM_OFFT);
2854
2855 printf("write reg: %x, value: %x\n", reg, value);
2856 reg_write(reg, value);
2857} /*end doVlanSetAccFrm*/
2858
2859void doVlanSetPortAttr(int argc, char *argv[])
2860{
2861 unsigned char port = 0;
2862 unsigned char attr = 0;
2863 unsigned int value;
2864 unsigned int reg;
2865
2866 port = atoi(argv[3]);
2867 attr = atoi(argv[4]);
2868
2869 printf("port: %x, attr: %x\n", port, attr);
2870
2871 /*Check the input parameters is right or not.*/
2872 if (port > SWITCH_MAX_PORT || attr > 3) {
2873 printf(HELP_VLAN_PORT_ATTR);
2874 return;
2875 }
2876
2877 reg = 0x2010 + port * 0x100;
2878 reg_read(reg, &value);
2879 value &= (0xffffff3f);
2880 value |= (attr << 6);
2881
2882 printf("write reg: %x, value: %x\n", reg, value);
2883 reg_write(reg, value);
2884}
2885
2886void doVlanSetPortMode(int argc, char *argv[])
2887{
2888 unsigned char port = 0;
2889 unsigned char mode = 0;
2890 unsigned int value;
2891 unsigned int reg;
2892 port = atoi(argv[3]);
2893 mode = atoi(argv[4]);
2894 printf("port: %x, mode: %x\n", port, mode);
2895
2896 /*Check the input parameters is right or not.*/
2897 if (port > SWITCH_MAX_PORT || mode > 3) {
2898 printf(HELP_VLAN_PORT_MODE);
2899 return;
2900 }
2901
2902 reg = 0x2004 + port * 0x100;
2903 reg_read(reg, &value);
2904 value &= (~((1 << 0) | (1 << 1)));
2905 value |= (mode & 0x3);
2906 printf("write reg: %x, value: %x\n", reg, value);
2907 reg_write(reg, value);
2908}
2909
2910void doVlanSetEgressTagPCR(int argc, char *argv[])
2911{
2912 unsigned char port = 0;
2913 unsigned char eg_tag = 0;
2914 unsigned int value;
2915 unsigned int reg;
2916
2917 port = atoi(argv[3]);
2918 eg_tag = atoi(argv[4]);
2919
2920 printf("port: %d, eg_tag: %d\n", port, eg_tag);
2921
2922 /*Check the input parameters is right or not.*/
2923 if ((port > SWITCH_MAX_PORT) || (eg_tag > REG_PCR_EG_TAG_RELMASK)) {
2924 printf(HELP_VLAN_EGRESS_TAG_PCR);
2925 return;
2926 }
2927
2928 reg = REG_PCR_P0_ADDR + port * 0x100;
2929 reg_read(reg, &value);
2930 value &= (~REG_PCR_EG_TAG_MASK);
2931 value |= ((unsigned int)eg_tag << REG_PCR_EG_TAG_OFFT);
2932
2933 printf("write reg: %x, value: %x\n", reg, value);
2934 reg_write(reg, value);
2935
2936} /*end doVlanSetEgressTagPCR*/
2937
2938void doVlanSetEgressTagPVC(int argc, char *argv[])
2939{
2940 unsigned char port = 0;
2941 unsigned char eg_tag = 0;
2942 unsigned int value;
2943 unsigned int reg;
2944
2945 port = atoi(argv[3]);
2946 eg_tag = atoi(argv[4]);
2947
2948 printf("port: %d, eg_tag: %d\n", port, eg_tag);
2949
2950 /*Check the input parameters is right or not.*/
2951 if ((port > SWITCH_MAX_PORT) || (eg_tag > REG_PVC_EG_TAG_RELMASK)) {
2952 printf(HELP_VLAN_EGRESS_TAG_PVC);
2953 return;
2954 }
2955
2956 reg = REG_PVC_P0_ADDR + port * 0x100;
2957 reg_read(reg, &value);
2958 value &= (~REG_PVC_EG_TAG_MASK);
2959 value |= ((unsigned int)eg_tag << REG_PVC_EG_TAG_OFFT);
2960
2961 printf("write reg: %x, value: %x\n", reg, value);
2962 reg_write(reg, value);
2963} /*end doVlanSetEgressTagPVC*/
2964
2965void doArlAging(int argc, char *argv[])
2966{
2967 unsigned char aging_en = 0;
2968 unsigned int time = 0, aging_cnt = 0, aging_unit = 0, value, reg;
2969 ;
2970
2971 aging_en = atoi(argv[3]);
2972 time = atoi(argv[4]);
2973 printf("aging_en: %x, aging time: %x\n", aging_en, time);
2974
2975 /*Check the input parameters is right or not.*/
2976 if ((aging_en != 0 && aging_en != 1) || (time <= 0 || time > 65536)) {
2977 printf(HELP_ARL_AGING);
2978 return;
2979 }
2980
2981 reg = 0xa0;
2982 reg_read(reg, &value);
2983 value &= (~(1 << 20));
2984 if (!aging_en) {
2985 value |= (1 << 20);
2986 }
2987
2988 aging_unit = (time / 0x100) + 1;
2989 aging_cnt = (time / aging_unit);
2990 aging_unit--;
2991 aging_cnt--;
2992
2993 value &= (0xfff00000);
2994 value |= ((aging_cnt << 12) | aging_unit);
2995
2996 printf("aging_unit: %x, aging_cnt: %x\n", aging_unit, aging_cnt);
2997 printf("write reg: %x, value: %x\n", reg, value);
2998
2999 reg_write(reg, value);
3000}
3001
3002void doMirrorEn(int argc, char *argv[])
3003{
3004 unsigned char mirror_en;
3005 unsigned char mirror_port;
3006 unsigned int value, reg;
3007
3008 mirror_en = atoi(argv[3]);
3009 mirror_port = atoi(argv[4]);
3010
3011 printf("mirror_en: %d, mirror_port: %d\n", mirror_en, mirror_port);
3012
3013 /*Check the input parameters is right or not.*/
3014 if ((mirror_en > 1) || (mirror_port > REG_CFC_MIRROR_PORT_RELMASK)) {
3015 printf(HELP_MIRROR_EN);
3016 return;
3017 }
3018
3019 reg = REG_CFC_ADDR;
3020 reg_read(reg, &value);
3021 value &= (~REG_CFC_MIRROR_EN_MASK);
3022 value |= (mirror_en << REG_CFC_MIRROR_EN_OFFT);
3023 value &= (~REG_CFC_MIRROR_PORT_MASK);
3024 value |= (mirror_port << REG_CFC_MIRROR_PORT_OFFT);
3025
3026 printf("write reg: %x, value: %x\n", reg, value);
3027 reg_write(reg, value);
3028
3029} /*end doMirrorEn*/
3030
3031void doMirrorPortBased(int argc, char *argv[])
3032{
3033 unsigned char port, port_tx_mir, port_rx_mir, vlan_mis, acl_mir, igmp_mir;
3034 unsigned int value, reg;
3035
3036 port = atoi(argv[3]);
3037 port_tx_mir = atoi(argv[4]);
3038 port_rx_mir = atoi(argv[5]);
3039 acl_mir = atoi(argv[6]);
3040 vlan_mis = atoi(argv[7]);
3041 igmp_mir = atoi(argv[8]);
3042
3043 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);
3044
3045 /*Check the input parameters is right or not.*/
3046 //if((port >= vlanCap->max_port_no) || (port_tx_mir > 1) || (port_rx_mir > 1) || (acl_mir > 1) || (vlan_mis > 1)){
3047 if ((port >= 7) || (port_tx_mir > 1) || (port_rx_mir > 1) || (acl_mir > 1) || (vlan_mis > 1)) { // also allow CPU port (port6)
3048 printf(HELP_MIRROR_PORTBASED);
3049 return;
3050 }
3051
3052 reg = REG_PCR_P0_ADDR + port * 0x100;
3053 reg_read(reg, &value);
3054 value &= ~(REG_PORT_TX_MIR_MASK | REG_PORT_RX_MIR_MASK | REG_PCR_ACL_MIR_MASK | REG_PCR_VLAN_MIS_MASK);
3055 value |= (port_tx_mir << REG_PORT_TX_MIR_OFFT) + (port_rx_mir << REG_PORT_RX_MIR_OFFT);
3056 value |= (acl_mir << REG_PCR_ACL_MIR_OFFT) + (vlan_mis << REG_PCR_VLAN_MIS_OFFT);
3057
3058 printf("write reg: %x, value: %x\n", reg, value);
3059 reg_write(reg, value);
3060
3061 reg = REG_PIC_P0_ADDR + port * 0x100;
3062 reg_read(reg, &value);
3063 value &= ~(REG_PIC_IGMP_MIR_MASK);
3064 value |= (igmp_mir << REG_PIC_IGMP_MIR_OFFT);
3065
3066 printf("write reg: %x, value: %x\n", reg, value);
3067 reg_write(reg, value);
3068
3069} /*end doMirrorPortBased*/
3070
3071void doStp(int argc, char *argv[])
3072{
3073 unsigned char port = 0;
3074 unsigned char fid = 0;
3075 unsigned char state = 0;
3076 unsigned int value;
3077 unsigned int reg;
3078
3079 port = atoi(argv[2]);
3080 fid = atoi(argv[3]);
3081 state = atoi(argv[4]);
3082
3083 printf("port: %d, fid: %d, state: %d\n", port, fid, state);
3084
3085 /*Check the input parameters is right or not.*/
3086 if ((port > MAX_PORT + 1) || (fid > 7) || (state > 3)) {
3087 printf(HELP_STP);
3088 return;
3089 }
3090
3091 reg = REG_SSC_P0_ADDR + port * 0x100;
3092 reg_read(reg, &value);
3093 value &= (~(3 << (fid << 2)));
3094 value |= ((unsigned int)state << (fid << 2));
3095
3096 printf("write reg: %x, value: %x\n", reg, value);
3097 reg_write(reg, value);
3098}
3099
3100int ingress_rate_set(int on_off, unsigned int port, unsigned int bw)
3101{
3102 unsigned int reg, value;
3103
3104 reg = 0x1800 + (0x100 * port);
3105 value = 0;
3106 /*token-bucket*/
3107 if (on_off == 1) {
3108 if (chip_name == 0x7530) {
3109 if (bw > 1000000) {
3110 printf("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",bw);
3111 return -1;
3112 }
3113 value = ((bw / 32) << 16) + (1 << 15) + (7 << 8) + (1 << 7) + 0x0f;
3114 } else if (chip_name == 0x7531) {
3115 if (bw > 2500000) {
3116 printf("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",bw);
3117 return -1;
3118 }
3119 if (bw/32 >= 65536) //supoort 2.5G case
3120 value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (1 << 12) + (7 << 8) + 0xf;
3121 else
3122 value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (7 << 8) + 0xf;
3123 }
3124 else
3125 printf("unknow chip\n");
3126 }
3127
3128#if leaky_bucket
3129 reg_read(reg, &value);
3130 value &= 0xffff0000;
3131 if (on_off == 1)
3132 {
3133 value |= on_off << 15;
3134 //7530 same as 7531
3135 if (bw < 100) {
3136 value |= (0x0 << 8);
3137 value |= bw;
3138 } else if (bw < 1000) {
3139 value |= (0x1 << 8);
3140 value |= bw / 10;
3141 } else if (bw < 10000) {
3142 value |= (0x2 << 8);
3143 value |= bw / 100;
3144 } else if (bw < 100000) {
3145 value |= (0x3 << 8);
3146 value |= bw / 1000;
3147 } else {
3148 value |= (0x4 << 8);
3149 value |= bw / 10000;
3150 }
3151 }
3152#endif
3153 reg_write(reg, value);
3154 reg = 0x1FFC;
3155 reg_read(reg, &value);
3156 value = 0x110104;
3157 reg_write(reg, value);
3158 return 0;
3159}
3160
3161int egress_rate_set(int on_off, int port, int bw)
3162{
3163 unsigned int reg, value;
3164
3165 reg = 0x1040 + (0x100 * port);
3166 value = 0;
3167 /*token-bucket*/
3168 if (on_off == 1) {
3169 if (chip_name == 0x7530) {
3170 if (bw < 0 || bw > 1000000) {
3171 printf("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",bw);
3172 return -1;
3173 }
3174 value = ((bw / 32) << 16) + (1 << 15) + (7 << 8) + (1 << 7) + 0xf;
3175 } else if (chip_name == 0x7531) {
3176 if (bw < 0 || bw > 2500000) {
3177 printf("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",bw);
3178 return -1;
3179 }
3180 if (bw/32 >= 65536) //support 2.5G cases
3181 value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (1 << 12) + (7 << 8) + 0xf;
3182 else
3183 value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (7 << 8) + 0xf;
3184 }
3185 else
3186 printf("unknow chip\n");
3187 }
3188 reg_write(reg, value);
3189 reg = 0x10E0;
3190 reg_read(reg, &value);
3191 value &= 0x18;
3192 reg_write(reg, value);
3193
3194 return 0;
3195}
3196
3197void rate_control(int argc, char *argv[])
3198{
3199 unsigned char dir = 0;
3200 unsigned char port = 0;
3201 unsigned int rate = 0;
3202
3203 dir = atoi(argv[2]);
3204 port = atoi(argv[3]);
3205 rate = atoi(argv[4]);
3206
3207 if (port > 6)
3208 return;
3209
3210 if (dir == 1) //ingress
3211 ingress_rate_set(1, port, rate);
3212 else if (dir == 0) //egress
3213 egress_rate_set(1, port, rate);
3214 else
3215 return;
3216}
3217
3218int collision_pool_enable(int argc, char *argv[])
3219{
3220
3221 unsigned char enable;
3222 unsigned int value, reg;
3223
3224 enable = atoi(argv[3]);
3225
3226
3227 printf("collision pool enable: %d \n", enable);
3228
3229 /*Check the input parameters is right or not.*/
3230 if (enable > 1) {
3231 printf(HELP_COLLISION_POOL_EN);
3232 return -1;
3233 }
3234
3235 if (chip_name == 0x7531) {
3236 reg = REG_CPGC_ADDR;
3237 if(enable == 1) {
3238 /* active reset */
3239 reg_read(reg, &value);
3240 value &= (~REG_CPCG_COL_RST_N_MASK);
3241 reg_write(reg, value);
3242
3243 /* enanble clock */
3244 reg_read(reg, &value);
3245 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3246 value |= (1 << REG_CPCG_COL_CLK_EN_OFFT);
3247 reg_write(reg, value);
3248
3249 /* inactive reset */
3250 reg_read(reg, &value);
3251 value &= (~REG_CPCG_COL_RST_N_MASK);
3252 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3253 reg_write(reg, value);
3254
3255 /* enable collision pool */
3256 reg_read(reg, &value);
3257 value &= (~REG_CPCG_COL_EN_MASK);
3258 value |= (1 << REG_CPCG_COL_EN_OFFT);
3259 reg_write(reg, value);
3260
3261 reg_read(reg, &value);
3262 printf("write reg: %x, value: %x\n", reg, value);
3263 }else {
3264
3265 /* disable collision pool */
3266 reg_read(reg, &value);
3267 value &= (~REG_CPCG_COL_EN_MASK);
3268 reg_write(reg, value);
3269
3270 /* active reset */
3271 reg_read(reg, &value);
3272 value &= (~REG_CPCG_COL_RST_N_MASK);
3273 reg_write(reg, value);
3274
3275 /* inactive reset */
3276 reg_read(reg, &value);
3277 value &= (~REG_CPCG_COL_RST_N_MASK);
3278 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3279 reg_write(reg, value);
3280
3281 /* disable clock */
3282 reg_read(reg, &value);
3283 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3284 reg_write(reg, value);
3285
3286 reg_read(reg, &value);
3287 printf("write reg: %x, value: %x\n", reg, value);
3288
3289 }
3290 }else{
3291 printf("\nCommand not support by this chip.\n");
3292}
3293
3294 return 0;
3295}
3296
3297void collision_pool_mac_dump()
3298{
3299 unsigned int value, reg;
3300
3301 if (chip_name == 0x7531) {
3302 reg = REG_CPGC_ADDR;
3303 reg_read(reg, &value);
3304 if(value & REG_CPCG_COL_EN_MASK)
3305 table_dump_internal(COLLISION_TABLE);
3306 else
3307 printf("\ncollision pool is disabled, please enable it before use this command.\n");
3308 }else {
3309 printf("\nCommand not support by this chip.\n");
3310 }
3311}
3312
3313void collision_pool_dip_dump()
3314{
3315 unsigned int value, reg;
3316
3317 if (chip_name == 0x7531) {
3318 reg = REG_CPGC_ADDR;
3319 reg_read(reg, &value);
3320 if(value & REG_CPCG_COL_EN_MASK)
3321 dip_dump_internal(COLLISION_TABLE);
3322 else
3323 printf("\ncollision pool is disabled, please enable it before use this command.\n");
3324 }else {
3325 printf("\nCommand not support by this chip.\n");
3326 }
3327
3328
3329}
3330
3331void collision_pool_sip_dump()
3332{
3333 unsigned int value, reg;
3334
3335 if (chip_name == 0x7531) {
3336 reg = REG_CPGC_ADDR;
3337 reg_read(reg, &value);
3338 if(value & REG_CPCG_COL_EN_MASK)
3339 sip_dump_internal(COLLISION_TABLE);
3340 else
3341 printf("\ncollision pool is disabled, please enable it before use this command.\n");
3342 }else {
3343 printf("\nCommand not support by this chip.\n");
3344 }
3345
3346
3347}
3348
3349void pfc_get_rx_counter(int argc, char *argv[])
3350{
3351 int port;
3352 unsigned int value, reg;
3353 unsigned int user_pri;
3354
3355 port = strtoul(argv[3], NULL, 0);
3356 if (port < 0 || 6 < port) {
3357 printf("wrong port range, should be within 0~6\n");
3358 return;
3359 }
3360
3361 if (chip_name == 0x7531) {
3362 reg= PFC_RX_COUNTER_L(port);
3363 reg_read(reg, &value);
3364 user_pri = value & 0xff;
3365 printf("\n port %d rx pfc (up=0)pause on counter is %d.\n", port,user_pri);
3366 user_pri = (value & 0xff00) >> 8;
3367 printf("\n port %d rx pfc (up=1)pause on counter is %d.\n", port,user_pri);
3368 user_pri = (value & 0xff0000) >> 16;
3369 printf("\n port %d rx pfc (up=2)pause on counter is %d.\n", port,user_pri);
3370 user_pri = (value & 0xff000000) >> 24;
3371 printf("\n port %d rx pfc (up=3)pause on counter is %d.\n", port,user_pri);
3372
3373 reg= PFC_RX_COUNTER_H(port);
3374 reg_read(reg, &value);
3375 user_pri = value & 0xff;
3376 printf("\n port %d rx pfc (up=4)pause on counter is %d.\n", port,user_pri);
3377 user_pri = (value & 0xff00) >> 8;
3378 printf("\n port %d rx pfc (up=5)pause on counter is %d.\n", port,user_pri);
3379 user_pri = (value & 0xff0000) >> 16;
3380 printf("\n port %d rx pfc (up=6)pause on counter is %d.\n", port,user_pri);
3381 user_pri = (value & 0xff000000) >> 24;
3382 printf("\n port %d rx pfc (up=7)pause on counter is %d.\n", port,user_pri);
3383
3384 /* for rx counter could be updated successfully */
3385 reg_read(PMSR_P(port), &value);
3386 reg_read(PMSR_P(port), &value);
3387 }else {
3388 printf("\nCommand not support by this chip.\n");
3389 }
3390
3391}
3392
3393void pfc_get_tx_counter(int argc, char *argv[])
3394{
3395 int port;
3396 unsigned int value, reg;
3397 unsigned int user_pri;
3398
3399 port = strtoul(argv[3], NULL, 0);
3400 if (port < 0 || 6 < port) {
3401 printf("wrong port range, should be within 0~6\n");
3402 return;
3403 }
3404
3405 if (chip_name == 0x7531) {
3406 reg= PFC_TX_COUNTER_L(port);
3407 reg_read(reg, &value);
3408 user_pri = value & 0xff;
3409 printf("\n port %d tx pfc (up=0)pause on counter is %d.\n", port,user_pri);
3410 user_pri = (value & 0xff00) >> 8;
3411 printf("\n port %d tx pfc (up=1)pause on counter is %d.\n", port,user_pri);
3412 user_pri = (value & 0xff0000) >> 16;
3413 printf("\n port %d tx pfc (up=2)pause on counter is %d.\n", port,user_pri);
3414 user_pri = (value & 0xff000000) >> 24;
3415 printf("\n port %d tx pfc (up=3)pause on counter is %d.\n", port,user_pri);
3416
3417 reg= PFC_TX_COUNTER_H(port);
3418 reg_read(reg, &value);
3419 user_pri = value & 0xff;
3420 printf("\n port %d tx pfc (up=4)pause on counter is %d.\n", port,user_pri);
3421 user_pri = (value & 0xff00) >> 8;
3422 printf("\n port %d tx pfc (up=5)pause on counter is %d.\n", port,user_pri);
3423 user_pri = (value & 0xff0000) >> 16;
3424 printf("\n port %d tx pfc (up=6)pause on counter is %d.\n", port,user_pri);
3425 user_pri = (value & 0xff000000) >> 24;
3426 printf("\n port %d tx pfc (up=7)pause on counter is %d.\n", port,user_pri);
3427
3428 /* for tx counter could be updated successfully */
3429 reg_read(PMSR_P(port), &value);
3430 reg_read(PMSR_P(port), &value);
3431 }else {
3432 printf("\nCommand not support by this chip.\n");
3433 }
3434}
3435
3436void read_output_queue_counters()
3437{
3438 unsigned int port=0;
3439 unsigned int value, output_queue;
3440 unsigned int base=0x220;
3441
3442 for (port = 0; port < 7; port++) {
3443 reg_write(0x7038, base + (port *4));
3444 reg_read(0x7034, &value);
3445 output_queue = value & 0xff;
3446 printf("\n port %d output queue 0 counter is %d.\n", port,output_queue);
3447 output_queue = (value & 0xff00) >> 8;
3448 printf("\n port %d output queue 1 counter is %d.\n", port,output_queue);
3449
3450 reg_write(0x7038, base + (port *4) + 1);
3451 reg_read(0x7034, &value);
3452 output_queue = value & 0xff;
3453 printf("\n port %d output queue 2 counter is %d.\n", port,output_queue);
3454 output_queue = (value & 0xff00) >> 8;
3455 printf("\n port %d output queue 3 counter is %d.\n", port,output_queue);
3456
3457 reg_write(0x7038, base + (port *4) + 2);
3458 reg_read(0x7034, &value);
3459 output_queue = value & 0xff;
3460 printf("\n port %d output queue 4 counter is %d.\n", port,output_queue);
3461 output_queue = (value & 0xff00) >> 8;
3462 printf("\n port %d output queue 5 counter is %d.\n", port,output_queue);
3463
3464 reg_write(0x7038, base + (port *4) + 3);
3465 reg_read(0x7034, &value);
3466 output_queue = value & 0xff;
3467 printf("\n port %d output queue 6 counter is %d.\n", port,output_queue);
3468 output_queue = (value & 0xff00) >> 8;
3469 printf("\n port %d output queue 7 counter is %d.\n", port,output_queue);
3470 }
3471}
3472
3473void read_free_page_counters()
3474{
3475 unsigned int value;
3476 unsigned int free_page,free_page_last_read;
3477 unsigned int fc_free_blk_lothd,fc_free_blk_hithd;
3478 unsigned int fc_port_blk_thd,fc_port_blk_hi_thd;
3479 unsigned int queue[8]={0};
3480
3481 if (chip_name == 0x7531) {
3482 /* get system free page link counter*/
3483 reg_read(0x1fc0, &value);
3484 free_page = value & 0xFFF;
3485 free_page_last_read = (value & 0xFFF0000) >> 16;
3486
3487 /* get system flow control waterwark */
3488 reg_read(0x1fe0, &value);
3489 fc_free_blk_lothd = value & 0x3FF;
3490 fc_free_blk_hithd = (value & 0x3FF0000) >> 16;
3491
3492 /* get port flow control waterwark */
3493 reg_read(0x1fe4, &value);
3494 fc_port_blk_thd = value & 0x3FF;
3495 fc_port_blk_hi_thd = (value & 0x3FF0000) >> 16;
3496
3497 /* get queue flow control waterwark */
3498 reg_read(0x1fe8, &value);
3499 queue[0]= value & 0x3F;
3500 queue[1]= (value & 0x3F00) >> 8;
3501 queue[2]= (value & 0x3F0000) >> 16;
3502 queue[3]= (value & 0x3F000000) >> 24;
3503 reg_read(0x1fec, &value);
3504 queue[4]= value & 0x3F;
3505 queue[5]= (value & 0x3F00) >> 8;
3506 queue[6]= (value & 0x3F0000) >> 16;
3507 queue[7]= (value & 0x3F000000) >> 24;
3508 } else {
3509 /* get system free page link counter*/
3510 reg_read(0x1fc0, &value);
3511 free_page = value & 0x3FF;
3512 free_page_last_read = (value & 0x3FF0000) >> 16;
3513
3514 /* get system flow control waterwark */
3515 reg_read(0x1fe0, &value);
3516 fc_free_blk_lothd = value & 0xFF;
3517 fc_free_blk_hithd = (value & 0xFF00) >> 8;
3518
3519 /* get port flow control waterwark */
3520 reg_read(0x1fe0, &value);
3521 fc_port_blk_thd = (value & 0xFF0000) >> 16;
3522 reg_read(0x1ff4, &value);
3523 fc_port_blk_hi_thd = (value & 0xFF00) >> 8;
3524
3525 /* get queue flow control waterwark */
3526 reg_read(0x1fe4, &value);
3527 queue[0]= value & 0xF;
3528 queue[1]= (value & 0xF0) >> 4;
3529 queue[2]= (value & 0xF00) >> 8;
3530 queue[3]= (value & 0xF000) >>12;
3531 queue[4]= (value & 0xF0000) >>16;
3532 queue[5]= (value & 0xF00000) >> 20;
3533 queue[6]= (value & 0xF000000) >> 24;
3534 queue[7]= (value & 0xF0000000) >> 28;
3535 }
3536
3537 printf("<===Free Page=======Current=======Last Read access=====> \n ");
3538 printf(" \n ");
3539 printf(" page counter %u %u \n ",free_page,free_page_last_read);
3540 printf(" \n ");
3541 printf("========================================================= \n ");
3542 printf("<===Type=======High threshold======Low threshold=========\n ");
3543 printf(" \n ");
3544 printf(" system: %u %u \n", fc_free_blk_hithd*2, fc_free_blk_lothd*2);
3545 printf(" port: %u %u \n", fc_port_blk_hi_thd*2, fc_port_blk_thd*2);
3546 printf(" queue 0: %u NA \n", queue[0]);
3547 printf(" queue 1: %u NA \n", queue[1]);
3548 printf(" queue 2: %u NA \n", queue[2]);
3549 printf(" queue 3: %u NA \n", queue[3]);
3550 printf(" queue 4: %u NA \n", queue[4]);
3551 printf(" queue 5: %u NA \n", queue[5]);
3552 printf(" queue 6: %u NA \n", queue[6]);
3553 printf(" queue 7: %u NA \n", queue[7]);
3554 printf("=========================================================\n ");
3555}
3556
3557void eee_enable(int argc, char *argv[])
3558{
3559 unsigned long enable;
3560 unsigned int value;
3561 unsigned int eee_cap;
3562 unsigned int eee_en_bitmap = 0;
3563 unsigned long port_map;
3564 long port_num = -1;
3565 int p;
3566
3567 if (argc < 3)
3568 goto error;
3569
3570 /*Check the input parameters is right or not.*/
3571 if (!strncmp(argv[2], "enable", 7))
3572 enable = 1;
3573 else if (!strncmp(argv[2], "disable", 8))
3574 enable = 0;
3575 else
3576 goto error;
3577
3578 if (argc > 3) {
3579 if (strlen(argv[3]) == 1) {
3580 port_num = strtol(argv[3], (char **)NULL, 10);
3581 if (port_num < 0 || port_num > MAX_PHY_PORT - 1) {
3582 printf("Illegal port index and port:0~4\n");
3583 goto error;
3584 }
3585 port_map = 1 << port_num;
3586 } else if (strlen(argv[3]) == 5) {
3587 port_map = 0;
3588 for (p = 0; p < MAX_PHY_PORT; p++) {
3589 if (argv[3][p] != '0' && argv[3][p] != '1') {
3590 printf("portmap format error, should be combination of 0 or 1\n");
3591 goto error;
3592 }
3593 port_map |= ((argv[3][p] - '0') << p);
3594 }
3595 } else {
3596 printf("port_no or portmap format error, should be length of 1 or 5\n");
3597 goto error;
3598 }
3599 } else {
3600 port_map = 0x1f;
3601 }
3602
3603 eee_cap = (enable)? 6: 0;
3604 for (p = 0; p < MAX_PHY_PORT; p++) {
3605 /* port_map describe p0p1p2p3p4 from left to rignt */
3606 if(!!(port_map & (1 << p)))
3607 mii_mgr_c45_write(p, 0x7, 0x3c, eee_cap);
3608
3609 mii_mgr_c45_read(p, 0x7, 0x3c, &value);
3610 /* mt7531: Always readback eee_cap = 0 when global EEE switch
3611 * is turned off.
3612 */
3613 if (value | eee_cap)
3614 eee_en_bitmap |= (1 << (MAX_PHY_PORT - 1 - p));
3615 }
3616
3617 /* Turn on/off global EEE switch */
3618 if (chip_name == 0x7531) {
3619 mii_mgr_c45_read(0, 0x1f, 0x403, &value);
3620 if (eee_en_bitmap)
3621 value |= (1 << 6);
3622 else
3623 value &= ~(1 << 6);
3624 mii_mgr_c45_write(0, 0x1f, 0x403, value);
3625 } else {
3626 printf("\nCommand not support by this chip.\n");
3627 }
3628
3629 printf("EEE(802.3az) %s", (enable)? "enable": "disable");
3630 if (argc == 4) {
3631 if (port_num >= 0)
3632 printf(" port%ld", port_num);
3633 else
3634 printf(" port_map: %s", argv[3]);
3635 } else {
3636 printf(" all ports");
3637 }
3638 printf("\n");
3639
3640 return;
3641error:
3642 printf(HELP_EEE_EN);
3643 return;
3644}
3645
3646void eee_dump(int argc, char *argv[])
3647{
3648 unsigned int cap, lp_cap;
3649 long port = -1;
3650 int p;
3651
3652 if (argc > 3) {
3653 if (strlen(argv[3]) > 1) {
3654 printf("port# format error, should be of length 1\n");
3655 return;
3656 }
3657
3658 port = strtol(argv[3], (char **)NULL, 0);
3659 if (port < 0 || port > MAX_PHY_PORT) {
3660 printf("port# format error, should be 0 to %d\n",
3661 MAX_PHY_PORT);
3662 return;
3663 }
3664 }
3665
3666 for (p = 0; p < MAX_PHY_PORT; p++) {
3667 if (port >= 0 && p != port)
3668 continue;
3669
3670 mii_mgr_c45_read(p, 0x7, 0x3c, &cap);
3671 mii_mgr_c45_read(p, 0x7, 0x3d, &lp_cap);
3672 printf("port%d EEE cap=0x%02x, link partner EEE cap=0x%02x",
3673 p, cap, lp_cap);
3674
3675 if (port >= 0 && p == port) {
3676 mii_mgr_c45_read(p, 0x3, 0x1, &cap);
3677 printf(", st=0x%03x", cap);
3678 }
3679 printf("\n");
3680 }
3681}
3682
3683void dump_each_port(unsigned int base)
3684{
3685 unsigned int pkt_cnt = 0;
3686 int i = 0;
3687
3688 for (i = 0; i < 7; i++) {
3689 reg_read((base) + (i * 0x100), &pkt_cnt);
3690 printf("%8u ", pkt_cnt);
3691 }
3692 printf("\n");
3693}
3694
3695void read_mib_counters()
3696{
3697 printf("===================== %8s %8s %8s %8s %8s %8s %8s\n",
3698 "Port0", "Port1", "Port2", "Port3", "Port4", "Port5", "Port6");
3699 printf("Tx Drop Packet :");
3700 dump_each_port(0x4000);
3701 printf("Tx CRC Error :");
3702 dump_each_port(0x4004);
3703 printf("Tx Unicast Packet :");
3704 dump_each_port(0x4008);
3705 printf("Tx Multicast Packet :");
3706 dump_each_port(0x400C);
3707 printf("Tx Broadcast Packet :");
3708 dump_each_port(0x4010);
3709 printf("Tx Collision Event :");
3710 dump_each_port(0x4014);
3711 printf("Tx Pause Packet :");
3712 dump_each_port(0x402C);
3713 printf("Rx Drop Packet :");
3714 dump_each_port(0x4060);
3715 printf("Rx Filtering Packet :");
3716 dump_each_port(0x4064);
3717 printf("Rx Unicast Packet :");
3718 dump_each_port(0x4068);
3719 printf("Rx Multicast Packet :");
3720 dump_each_port(0x406C);
3721 printf("Rx Broadcast Packet :");
3722 dump_each_port(0x4070);
3723 printf("Rx Alignment Error :");
3724 dump_each_port(0x4074);
3725 printf("Rx CRC Error :");
3726 dump_each_port(0x4078);
3727 printf("Rx Undersize Error :");
3728 dump_each_port(0x407C);
3729 printf("Rx Fragment Error :");
3730 dump_each_port(0x4080);
3731 printf("Rx Oversize Error :");
3732 dump_each_port(0x4084);
3733 printf("Rx Jabber Error :");
3734 dump_each_port(0x4088);
3735 printf("Rx Pause Packet :");
3736 dump_each_port(0x408C);
3737}
3738
3739void clear_mib_counters()
3740{
3741 reg_write(0x4fe0, 0xf0);
3742 read_mib_counters();
3743 reg_write(0x4fe0, 0x800000f0);
3744}
3745
3746
3747void exit_free()
3748{
3749 free(attres);
3750 attres = NULL;
3751 switch_ioctl_fini();
3752 mt753x_netlink_free();
3753}