blob: 6dd7fc52310f592d03b604eb86e4d484ad633638 [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001/*
2* switch_fun.c: switch function sets
3*/
4#include <stdio.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <string.h>
8#include <stdbool.h>
9#include <sys/ioctl.h>
10#include <sys/socket.h>
11#include <linux/if.h>
12#include <stdbool.h>
13#include <time.h>
developer997ed6b2024-03-26 14:03:42 +080014#include <errno.h>
developerfd40db22021-04-29 10:08:25 +080015
16#include "switch_extend.h"
17#include "switch_netlink.h"
18#include "switch_ioctl.h"
19#include "switch_fun.h"
20
21#define leaky_bucket 0
22
developerbe40a9e2024-03-07 21:44:26 +080023struct switch_func_s mt753x_switch_func = {
24 .pf_table_dump = table_dump,
25 .pf_table_clear = table_clear,
26 .pf_switch_reset = switch_reset,
27 .pf_doArlAging = doArlAging,
28 .pf_read_mib_counters = read_mib_counters,
29 .pf_clear_mib_counters = clear_mib_counters,
30 .pf_read_output_queue_counters = read_output_queue_counters,
31 .pf_read_free_page_counters = read_free_page_counters,
32 .pf_rate_control = rate_control,
33 .pf_igress_rate_set = ingress_rate_set,
34 .pf_egress_rate_set = egress_rate_set,
35 .pf_table_add = table_add,
36 .pf_table_del_fid = table_del_fid,
37 .pf_table_del_vid = table_del_vid,
38 .pf_table_search_mac_fid = table_search_mac_fid,
39 .pf_table_search_mac_vid = table_search_mac_vid,
40 .pf_global_set_mac_fc = global_set_mac_fc,
41 .pf_set_mac_pfc = set_mac_pfc,
42 .pf_qos_sch_select = qos_sch_select,
43 .pf_qos_set_base = qos_set_base,
44 .pf_qos_wfq_set_weight = qos_wfq_set_weight,
45 .pf_qos_set_portpri = qos_set_portpri,
46 .pf_qos_set_dscppri = qos_set_dscppri,
47 .pf_qos_pri_mapping_queue = qos_pri_mapping_queue,
48 .pf_doStp = doStp,
49 .pf_sip_dump = sip_dump,
50 .pf_sip_add = sip_add,
51 .pf_sip_del = sip_del,
52 .pf_sip_clear = sip_clear,
53 .pf_dip_dump = dip_dump,
54 .pf_dip_add = dip_add,
55 .pf_dip_del = dip_del,
56 .pf_dip_clear = dip_clear,
57 .pf_set_mirror_to = set_mirror_to,
58 .pf_set_mirror_from = set_mirror_from,
59 .pf_doMirrorEn = doMirrorEn,
60 .pf_doMirrorPortBased = doMirrorPortBased,
61 .pf_acl_dip_add = acl_dip_add,
62 .pf_acl_dip_modify = acl_dip_modify,
63 .pf_acl_dip_pppoe = acl_dip_pppoe,
64 .pf_acl_dip_trtcm = acl_dip_trtcm,
65 .pf_acl_dip_meter = acl_dip_meter,
66 .pf_acl_mac_add = acl_mac_add,
67 .pf_acl_ethertype = acl_ethertype,
68 .pf_acl_sp_add = acl_sp_add,
69 .pf_acl_l4_add = acl_l4_add,
70 .pf_acl_port_enable = acl_port_enable,
71 .pf_acl_table_add = acl_table_add,
72 .pf_acl_mask_table_add = acl_mask_table_add,
73 .pf_acl_rule_table_add = acl_rule_table_add,
74 .pf_acl_rate_table_add = acl_rate_table_add,
75 .pf_vlan_dump = vlan_dump,
76 .pf_vlan_set = vlan_set,
77 .pf_vlan_clear = vlan_clear,
78 .pf_doVlanSetVid = doVlanSetVid,
79 .pf_doVlanSetPvid = doVlanSetPvid,
80 .pf_doVlanSetAccFrm = doVlanSetAccFrm,
81 .pf_doVlanSetPortAttr = doVlanSetPortAttr,
82 .pf_doVlanSetPortMode = doVlanSetPortMode,
83 .pf_doVlanSetEgressTagPCR = doVlanSetEgressTagPCR,
84 .pf_doVlanSetEgressTagPVC = doVlanSetEgressTagPVC,
85 .pf_igmp_on = igmp_on,
86 .pf_igmp_off = igmp_off,
87 .pf_igmp_enable = igmp_enable,
88 .pf_igmp_disable = igmp_disable,
89 .pf_collision_pool_enable = collision_pool_enable,
90 .pf_collision_pool_mac_dump = collision_pool_mac_dump,
91 .pf_collision_pool_dip_dump = collision_pool_dip_dump,
92 .pf_collision_pool_sip_dump = collision_pool_sip_dump,
93 .pf_pfc_get_rx_counter = pfc_get_rx_counter,
94 .pf_pfc_get_tx_counter = pfc_get_tx_counter,
95 .pf_eee_enable = eee_enable,
96 .pf_eee_dump = eee_dump,
97};
98
developerfd40db22021-04-29 10:08:25 +080099static int getnext(char *src, int separator, char *dest)
100{
101 char *c;
102 int len;
103
104 if ((src == NULL) || (dest == NULL))
105 return -1;
106
107 c = strchr(src, separator);
108 if (c == NULL)
109 return -1;
110
111 len = c - src;
112 strncpy(dest, src, len);
113 dest[len] = '\0';
114 return len + 1;
115}
116
117static int str_to_ip(unsigned int *ip, char *str)
118{
119 int i;
120 int len;
121 char *ptr = str;
122 char buf[128];
123 unsigned char c[4];
124
125 for (i = 0; i < 3; ++i) {
126 if ((len = getnext(ptr, '.', buf)) == -1)
127 return 1;
128 c[i] = atoi(buf);
129 ptr += len;
130 }
131 c[3] = atoi(ptr);
132 *ip = (c[0] << 24) + (c[1] << 16) + (c[2] << 8) + c[3];
133 return 0;
134}
135
136/*convert IP address from number to string */
developer546b2792024-06-15 20:31:38 +0800137static void ip_to_str(char *str, size_t size, unsigned int ip)
developerfd40db22021-04-29 10:08:25 +0800138{
139 unsigned char *ptr = (unsigned char *)&ip;
140 unsigned char c[4];
developer546b2792024-06-15 20:31:38 +0800141 int ret;
142
143 if (str == NULL || size == 0) {
144 printf("convert IP address failed\n");
145 return;
146 }
developerfd40db22021-04-29 10:08:25 +0800147
148 c[0] = *(ptr);
149 c[1] = *(ptr + 1);
150 c[2] = *(ptr + 2);
151 c[3] = *(ptr + 3);
developer546b2792024-06-15 20:31:38 +0800152
153 ret = snprintf(str, size, "%d.%d.%d.%d", c[3], c[2], c[1], c[0]);
154 if (ret < 0) {
155 printf("Encoding error in snprintf\n");
156 return;
157 } else if ((size_t)ret >= size) {
158 printf("Required size %d, provided size %zu\n", ret, size);
159 return;
160 }
developerfd40db22021-04-29 10:08:25 +0800161}
162
163int reg_read(unsigned int offset, unsigned int *value)
164{
165 int ret = -1;
166
167 if (nl_init_flag == true) {
168 ret = reg_read_netlink(attres, offset, value);
169 } else {
170 if (attres->dev_id == -1)
171 ret = reg_read_ioctl(offset, value);
172 }
173 if (ret < 0) {
174 printf("Read fail\n");
175 *value = 0;
176 return ret;
177 }
178
179 return 0;
180}
181
182int reg_write(unsigned int offset, unsigned int value)
183{
184 int ret = -1;
185
186 if (nl_init_flag == true) {
187 ret = reg_write_netlink(attres, offset, value);
188 } else {
189 if (attres->dev_id == -1)
190 ret = reg_write_ioctl(offset, value);
191 }
192 if (ret < 0) {
193 printf("Write fail\n");
194 exit_free();
195 exit(0);
196 }
197 return 0;
198}
199
200int mii_mgr_read(unsigned int port_num, unsigned int reg, unsigned int *value)
201{
202 int ret;
203
204 if (port_num > 31) {
205 printf("Invalid Port or PHY addr \n");
206 return -1;
207 }
208
209 if (nl_init_flag == true)
210 ret = phy_cl22_read_netlink(attres, port_num, reg, value);
211 else
212 ret = mii_mgr_cl22_read_ioctl(port_num, reg, value);
213
214 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800215 printf("Phy cl22 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800216 exit_free();
217 exit(0);
218 }
219
220 return 0;
221}
222
223int mii_mgr_write(unsigned int port_num, unsigned int reg, unsigned int value)
224{
225 int ret;
226
227 if (port_num > 31) {
228 printf("Invalid Port or PHY addr \n");
229 return -1;
230 }
231
232 if (nl_init_flag == true)
233 ret = phy_cl22_write_netlink(attres, port_num, reg, value);
234 else
235 ret = mii_mgr_cl22_write_ioctl(port_num, reg, value);
236
237 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800238 printf("Phy cl22 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800239 exit_free();
240 exit(0);
241 }
242
243 return 0;
244}
245
developerbe40a9e2024-03-07 21:44:26 +0800246int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg,
247 unsigned int *value)
developerfd40db22021-04-29 10:08:25 +0800248{
249 int ret;
250
251 if (port_num > 31) {
252 printf("Invalid Port or PHY addr \n");
253 return -1;
254 }
255
256 if (nl_init_flag == true)
257 ret = phy_cl45_read_netlink(attres, port_num, dev, reg, value);
258 else
259 ret = mii_mgr_cl45_read_ioctl(port_num, dev, reg, value);
260
261 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800262 printf("Phy cl45 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800263 exit_free();
264 exit(0);
265 }
266
267 return 0;
268}
269
developerbe40a9e2024-03-07 21:44:26 +0800270int mii_mgr_c45_write(unsigned int port_num, unsigned int dev, unsigned int reg,
271 unsigned int value)
developerfd40db22021-04-29 10:08:25 +0800272{
273 int ret;
274
275 if (port_num > 31) {
276 printf("Invalid Port or PHY addr \n");
277 return -1;
278 }
279
280 if (nl_init_flag == true)
281 ret = phy_cl45_write_netlink(attres, port_num, dev, reg, value);
282 else
283 ret = mii_mgr_cl45_write_ioctl(port_num, dev, reg, value);
284
285 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800286 printf("Phy cl45 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800287 exit_free();
288 exit(0);
289 }
290
291 return 0;
292}
293
developerfd40db22021-04-29 10:08:25 +0800294int phy_dump(int phy_addr)
295{
296 int ret;
297
298 if (nl_init_flag == true)
299 ret = phy_dump_netlink(attres, phy_addr);
300 else
301 ret = phy_dump_ioctl(phy_addr);
302
303 if (ret < 0) {
304 printf("Phy dump fail\n");
305 exit_free();
306 exit(0);
307 }
308
309 return 0;
310}
311
312void phy_crossover(int argc, char *argv[])
313{
314 unsigned int port_num = strtoul(argv[2], NULL, 10);
developerbe40a9e2024-03-07 21:44:26 +0800315 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +0800316 int ret;
317
318 if (port_num > 4) {
319 printf("invaild value, port_name:0~4\n");
320 return;
321 }
322
323 if (nl_init_flag == true)
developerbe40a9e2024-03-07 21:44:26 +0800324 ret =
325 phy_cl45_read_netlink(attres, port_num, 0x1E,
326 MT7530_T10_TEST_CONTROL, &value);
developerfd40db22021-04-29 10:08:25 +0800327 else
developerbe40a9e2024-03-07 21:44:26 +0800328 ret =
329 mii_mgr_cl45_read_ioctl(port_num, 0x1E,
330 MT7530_T10_TEST_CONTROL, &value);
developerfd40db22021-04-29 10:08:25 +0800331 if (ret < 0) {
332 printf("phy_cl45 read fail\n");
333 exit_free();
334 exit(0);
335 }
336
337 printf("mii_mgr_cl45:");
developerbe40a9e2024-03-07 21:44:26 +0800338 printf("Read: port#=%d, device=0x%x, reg=0x%x, value=0x%x\n", port_num,
339 0x1E, MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800340
developerbe40a9e2024-03-07 21:44:26 +0800341 if (!strncmp(argv[3], "auto", 5)) {
developerfd40db22021-04-29 10:08:25 +0800342 value &= (~(0x3 << 3));
343 } else if (!strncmp(argv[3], "mdi", 4)) {
344 value &= (~(0x3 << 3));
345 value |= (0x2 << 3);
346 } else if (!strncmp(argv[3], "mdix", 5)) {
347 value |= (0x3 << 3);
348 } else {
349 printf("invaild parameter\n");
350 return;
351 }
developerbe40a9e2024-03-07 21:44:26 +0800352 printf("Write: port#=%d, device=0x%x, reg=0x%x. value=0x%x\n", port_num,
353 0x1E, MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800354
355 if (nl_init_flag == true)
developerbe40a9e2024-03-07 21:44:26 +0800356 ret =
357 phy_cl45_write_netlink(attres, port_num, 0x1E,
358 MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800359 else
developerbe40a9e2024-03-07 21:44:26 +0800360 ret =
361 mii_mgr_cl45_write_ioctl(port_num, 0x1E,
362 MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800363
364 if (ret < 0) {
365 printf("phy_cl45 write fail\n");
366 exit_free();
367 exit(0);
368 }
369}
370
371int rw_phy_token_ring(int argc, char *argv[])
372{
373 int ch_addr, node_addr, data_addr;
374 unsigned int tr_reg_control;
375 unsigned int val_l = 0;
376 unsigned int val_h = 0;
377 unsigned int port_num;
378
379 if (argc < 4)
380 return -1;
381
382 if (argv[2][0] == 'r') {
383 if (argc != 7)
384 return -1;
developerbe40a9e2024-03-07 21:44:26 +0800385 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
developerfd40db22021-04-29 10:08:25 +0800386 port_num = strtoul(argv[3], NULL, 0);
387 if (port_num > MAX_PORT) {
388 printf("Illegal port index and port:0~6\n");
389 return -1;
390 }
391 ch_addr = strtoul(argv[4], NULL, 0);
392 node_addr = strtoul(argv[5], NULL, 0);
393 data_addr = strtoul(argv[6], NULL, 0);
developerbe40a9e2024-03-07 21:44:26 +0800394 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n",
395 port_num, ch_addr, node_addr, data_addr);
396 tr_reg_control =
397 (1 << 15) | (1 << 13) | (ch_addr << 11) | (node_addr << 7) |
398 (data_addr << 1);
399 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
developerfd40db22021-04-29 10:08:25 +0800400 mii_mgr_read(port_num, 17, &val_l);
401 mii_mgr_read(port_num, 18, &val_h);
developerbe40a9e2024-03-07 21:44:26 +0800402 printf
403 ("switch trreg read tr_reg_control=%x, value_H=%x, value_L=%x\n",
404 tr_reg_control, val_h, val_l);
developerfd40db22021-04-29 10:08:25 +0800405 } else if (argv[2][0] == 'w') {
406 if (argc != 9)
407 return -1;
developerbe40a9e2024-03-07 21:44:26 +0800408 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
developerfd40db22021-04-29 10:08:25 +0800409 port_num = strtoul(argv[3], NULL, 0);
410 if (port_num > MAX_PORT) {
411 printf("\n**Illegal port index and port:0~6\n");
412 return -1;
413 }
414 ch_addr = strtoul(argv[4], NULL, 0);
415 node_addr = strtoul(argv[5], NULL, 0);
416 data_addr = strtoul(argv[6], NULL, 0);
417 val_h = strtoul(argv[7], NULL, 0);
418 val_l = strtoul(argv[8], NULL, 0);
developerbe40a9e2024-03-07 21:44:26 +0800419 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n",
420 port_num, ch_addr, node_addr, data_addr);
421 tr_reg_control =
422 (1 << 15) | (0 << 13) | (ch_addr << 11) | (node_addr << 7) |
423 (data_addr << 1);
developerfd40db22021-04-29 10:08:25 +0800424 mii_mgr_write(port_num, 17, val_l);
425 mii_mgr_write(port_num, 18, val_h);
developerbe40a9e2024-03-07 21:44:26 +0800426 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
427 printf
428 ("switch trreg Write tr_reg_control=%x, value_H=%x, value_L=%x\n",
429 tr_reg_control, val_h, val_l);
developerfd40db22021-04-29 10:08:25 +0800430 } else
431 return -1;
432 return 0;
433}
434
developerbe40a9e2024-03-07 21:44:26 +0800435void write_acl_table(unsigned char tbl_idx, unsigned int vawd1,
436 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800437{
developerbe40a9e2024-03-07 21:44:26 +0800438 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800439 unsigned int max_index;
440
developer8c3871b2022-07-01 14:07:53 +0800441 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800442 max_index = 256;
443 else
444 max_index = 64;
445
446 printf("Pattern_acl_tbl_idx:%d\n", tbl_idx);
447
448 if (tbl_idx >= max_index) {
449 printf(HELP_ACL_ACL_TBL_ADD);
450 return;
451 }
452
453 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800454 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800455 reg_read(reg, &value);
456 if ((value & REG_VTCR_BUSY_MASK) == 0) {
457 break;
458 }
459 }
460 reg_write(REG_VAWD1_ADDR, vawd1);
461 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
462 reg_write(REG_VAWD2_ADDR, vawd2);
463 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
464 reg = REG_VTCR_ADDR;
465 value = REG_VTCR_BUSY_MASK | (0x05 << REG_VTCR_FUNC_OFFT) | tbl_idx;
466 reg_write(reg, value);
467 printf("write reg: %x, value: %x\n", reg, value);
468
developerbe40a9e2024-03-07 21:44:26 +0800469 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800470 reg_read(reg, &value);
471 if ((value & REG_VTCR_BUSY_MASK) == 0)
472 break;
473 }
474}
475
476void acl_table_add(int argc, char *argv[])
477{
developerbe40a9e2024-03-07 21:44:26 +0800478 unsigned int vawd1 = 0, vawd2 = 0;
479 unsigned char tbl_idx = 0;
developer546b2792024-06-15 20:31:38 +0800480 char *endptr;
developerfd40db22021-04-29 10:08:25 +0800481
developer546b2792024-06-15 20:31:38 +0800482 errno = 0;
483 tbl_idx = strtoul(argv[3], &endptr, 10);
484 if (errno != 0 || *endptr != '\0') {
485 printf("Error: wrong ACL rule table index\n");
486 return;
487 }
488
489 errno = 0;
490 vawd1 = strtoul(argv[4], &endptr, 16);
491 if (errno != 0 || *endptr != '\0') {
492 printf("Error: wrong ACL rule table write data 1\n");
493 return;
494 }
495
496 errno = 0;
497 vawd2 = strtoul(argv[5], &endptr, 16);
498 if (errno != 0 || *endptr != '\0') {
499 printf("Error: wrong ACL rule table write data 2\n");
500 return;
501 }
502
developerfd40db22021-04-29 10:08:25 +0800503 write_acl_table(tbl_idx, vawd1, vawd2);
504}
505
developerbe40a9e2024-03-07 21:44:26 +0800506void write_acl_mask_table(unsigned char tbl_idx, unsigned int vawd1,
507 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800508{
developerbe40a9e2024-03-07 21:44:26 +0800509 unsigned int value = 0, reg = 0;
510 unsigned int max_index = 0;
developerfd40db22021-04-29 10:08:25 +0800511
developer8c3871b2022-07-01 14:07:53 +0800512 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800513 max_index = 128;
514 else
515 max_index = 32;
516
517 printf("Rule_mask_tbl_idx:%d\n", tbl_idx);
518
519 if (tbl_idx >= max_index) {
520 printf(HELP_ACL_MASK_TBL_ADD);
521 return;
522 }
523 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800524 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800525 reg_read(reg, &value);
526 if ((value & REG_VTCR_BUSY_MASK) == 0)
527 break;
528 }
529 reg_write(REG_VAWD1_ADDR, vawd1);
530 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
531 reg_write(REG_VAWD2_ADDR, vawd2);
532 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
533 reg = REG_VTCR_ADDR;
534 value = REG_VTCR_BUSY_MASK | (0x09 << REG_VTCR_FUNC_OFFT) | tbl_idx;
535 reg_write(reg, value);
536 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +0800537 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800538 reg_read(reg, &value);
539 if ((value & REG_VTCR_BUSY_MASK) == 0)
540 break;
541 }
542}
543
544void acl_mask_table_add(int argc, char *argv[])
545{
developerbe40a9e2024-03-07 21:44:26 +0800546 unsigned int vawd1 = 0, vawd2 = 0;
547 unsigned char tbl_idx = 0;
developer546b2792024-06-15 20:31:38 +0800548 char *endptr;
developerfd40db22021-04-29 10:08:25 +0800549
developer546b2792024-06-15 20:31:38 +0800550 errno = 0;
551 tbl_idx = strtoul(argv[3], &endptr, 10);
552 if (errno != 0 || *endptr != '\0') {
553 printf("Error: wrong ACL mask table index\n");
554 return;
555 }
556
557 errno = 0;
558 vawd1 = strtoul(argv[4], &endptr, 16);
559 if (errno != 0 || *endptr != '\0') {
560 printf("Error: wrong ACL mask table write data 1\n");
561 return;
562 }
563
564 errno = 0;
565 vawd2 = strtoul(argv[5], &endptr, 16);
566 if (errno != 0 || *endptr != '\0') {
567 printf("Error: wrong ACL mask table write data 2\n");
568 return;
569 }
570
developerfd40db22021-04-29 10:08:25 +0800571 write_acl_mask_table(tbl_idx, vawd1, vawd2);
572}
573
developerbe40a9e2024-03-07 21:44:26 +0800574void write_acl_rule_table(unsigned char tbl_idx, unsigned int vawd1,
575 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800576{
developerbe40a9e2024-03-07 21:44:26 +0800577 unsigned int value = 0, reg = 0;
578 unsigned int max_index = 0;
developerfd40db22021-04-29 10:08:25 +0800579
developer8c3871b2022-07-01 14:07:53 +0800580 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800581 max_index = 128;
582 else
583 max_index = 32;
584
585 printf("Rule_control_tbl_idx:%d\n", tbl_idx);
586
developerbe40a9e2024-03-07 21:44:26 +0800587 if (tbl_idx >= max_index) { /* Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +0800588 printf(HELP_ACL_RULE_TBL_ADD);
589 return;
590 }
591 reg = REG_VTCR_ADDR;
592
developerbe40a9e2024-03-07 21:44:26 +0800593 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800594 reg_read(reg, &value);
595 if ((value & REG_VTCR_BUSY_MASK) == 0) {
596 break;
597 }
598 }
599 reg_write(REG_VAWD1_ADDR, vawd1);
600 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
601 reg_write(REG_VAWD2_ADDR, vawd2);
602 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
603 reg = REG_VTCR_ADDR;
604 value = REG_VTCR_BUSY_MASK | (0x0B << REG_VTCR_FUNC_OFFT) | tbl_idx;
605 reg_write(reg, value);
606 printf("write reg: %x, value: %x\n", reg, value);
607
developerbe40a9e2024-03-07 21:44:26 +0800608 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800609 reg_read(reg, &value);
610 if ((value & REG_VTCR_BUSY_MASK) == 0) {
611 break;
612 }
613 }
614}
615
616void acl_rule_table_add(int argc, char *argv[])
617{
developerbe40a9e2024-03-07 21:44:26 +0800618 unsigned int vawd1 = 0, vawd2 = 0;
619 unsigned char tbl_idx = 0;
developer546b2792024-06-15 20:31:38 +0800620 char *endptr;
621
622 errno = 0;
623 tbl_idx = strtoul(argv[3], &endptr, 10);
624 if (errno != 0 || *endptr != '\0') {
625 printf("Error: wrong ACL rule control table index\n");
626 return;
627 }
628
629 errno = 0;
630 vawd1 = strtoul(argv[4], &endptr, 16);
631 if (errno != 0 || *endptr != '\0') {
632 printf("Error: wrong ACL rule control table write data 1\n");
633 return;
634 }
635
636 errno = 0;
637 vawd2 = strtoul(argv[5], &endptr, 16);
638 if (errno != 0 || *endptr != '\0') {
639 printf("Error: wrong ACL rule control table write data 2\n");
640 return;
641 }
developerfd40db22021-04-29 10:08:25 +0800642
developerfd40db22021-04-29 10:08:25 +0800643 write_acl_rule_table(tbl_idx, vawd1, vawd2);
644}
645
developerbe40a9e2024-03-07 21:44:26 +0800646void write_rate_table(unsigned char tbl_idx, unsigned int vawd1,
647 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800648{
developerbe40a9e2024-03-07 21:44:26 +0800649 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800650 unsigned int max_index = 32;
651
652 printf("Rule_action_tbl_idx:%d\n", tbl_idx);
653
654 if (tbl_idx >= max_index) {
655 printf(HELP_ACL_RATE_TBL_ADD);
656 return;
657 }
658
659 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800660 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800661 reg_read(reg, &value);
662 if ((value & REG_VTCR_BUSY_MASK) == 0)
663 break;
664 }
665
666 reg_write(REG_VAWD1_ADDR, vawd1);
667 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
668 reg_write(REG_VAWD2_ADDR, vawd2);
669 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
670 reg = REG_VTCR_ADDR;
671 value = REG_VTCR_BUSY_MASK | (0x0D << REG_VTCR_FUNC_OFFT) | tbl_idx;
672 reg_write(reg, value);
673 printf("write reg: %x, value: %x\n", reg, value);
674
developerbe40a9e2024-03-07 21:44:26 +0800675 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800676 reg_read(reg, &value);
677 if ((value & REG_VTCR_BUSY_MASK) == 0)
678 break;
679 }
680}
681
682void acl_rate_table_add(int argc, char *argv[])
683{
developerbe40a9e2024-03-07 21:44:26 +0800684 unsigned int vawd1 = 0, vawd2 = 0;
685 unsigned char tbl_idx = 0;
developer546b2792024-06-15 20:31:38 +0800686 char *endptr;
developerfd40db22021-04-29 10:08:25 +0800687
developer546b2792024-06-15 20:31:38 +0800688 errno = 0;
689 tbl_idx = strtoul(argv[3], &endptr, 10);
690 if (errno != 0 || *endptr != '\0') {
691 printf("Error: wrong ACL rate control table index\n");
692 return;
693 }
694
695 errno = 0;
696 vawd1 = strtoul(argv[4], &endptr, 16);
697 if (errno != 0 || *endptr != '\0') {
698 printf("Error: wrong ACL rate control table write data 1\n");
699 return;
700 }
701
702 errno = 0;
703 vawd2 = strtoul(argv[5], &endptr, 16);
704 if (errno != 0 || *endptr != '\0') {
705 printf("Error: wrong ACL rate control table write data 2\n");
706 return;
707 }
developerfd40db22021-04-29 10:08:25 +0800708
709 write_rate_table(tbl_idx, vawd1, vawd2);
710}
711
developerbe40a9e2024-03-07 21:44:26 +0800712void write_trTCM_table(unsigned char tbl_idx, unsigned int vawd1,
713 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800714{
developerbe40a9e2024-03-07 21:44:26 +0800715 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800716 unsigned int max_index = 32;
717
718 printf("trTCM_tbl_idx:%d\n", tbl_idx);
719
720 if (tbl_idx >= max_index) {
721 printf(HELP_ACL_TRTCM_TBL_ADD);
722 return;
723 }
724
725 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800726 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800727 reg_read(reg, &value);
728 if ((value & REG_VTCR_BUSY_MASK) == 0)
729 break;
730 }
731
732 reg_write(REG_VAWD1_ADDR, vawd1);
733 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
734 reg_write(REG_VAWD2_ADDR, vawd2);
735 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
736 reg = REG_VTCR_ADDR;
737 value = REG_VTCR_BUSY_MASK | (0x07 << REG_VTCR_FUNC_OFFT) | tbl_idx;
738 reg_write(reg, value);
739 printf("write reg: %x, value: %x\n", reg, value);
740
developerbe40a9e2024-03-07 21:44:26 +0800741 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800742 reg_read(reg, &value);
743 if ((value & REG_VTCR_BUSY_MASK) == 0)
744 break;
745 }
746}
747
developerbe40a9e2024-03-07 21:44:26 +0800748int acl_parameters_pre_del(int len1, int len2, int argc, char *argv[],
749 int *port)
developerfd40db22021-04-29 10:08:25 +0800750{
developerbe40a9e2024-03-07 21:44:26 +0800751 int i = 0;
developerfd40db22021-04-29 10:08:25 +0800752
753 *port = 0;
754 if (argc < len1) {
755 printf("insufficient arguments!\n");
756 return -1;
757 }
758
developerbe40a9e2024-03-07 21:44:26 +0800759 if (len2 == 12) {
developerfd40db22021-04-29 10:08:25 +0800760 if (!argv[4] || strlen(argv[4]) != len2) {
developerbe40a9e2024-03-07 21:44:26 +0800761 printf
762 ("The [%s] format error, should be of length %d\n",
763 argv[4], len2);
developerfd40db22021-04-29 10:08:25 +0800764 return -1;
765 }
766 }
767
768 if (!argv[5] || strlen(argv[5]) != 8) {
769 printf("portsmap format error, should be of length 7\n");
770 return -1;
771 }
772
773 for (i = 0; i < 7; i++) {
774 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +0800775 printf
776 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +0800777 return -1;
778 }
779 *port += (argv[5][i] - '0') * (1 << i);
780 }
781 return 0;
782}
783
developerbe40a9e2024-03-07 21:44:26 +0800784void acl_compare_pattern(int ports, int comparion, int base, int word,
785 unsigned char table_index)
developerfd40db22021-04-29 10:08:25 +0800786{
developerbe40a9e2024-03-07 21:44:26 +0800787 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +0800788
developerbe40a9e2024-03-07 21:44:26 +0800789 comparion |= 0xffff0000; //compare mask
developerfd40db22021-04-29 10:08:25 +0800790
developerbe40a9e2024-03-07 21:44:26 +0800791 value = ports << 8; //w_port_map
792 value |= 0x1 << 19; //enable
793 value |= base << 16; //mac header
794 value |= word << 1; //word offset
developerfd40db22021-04-29 10:08:25 +0800795
796 write_acl_table(table_index, comparion, value);
797}
798
799void acl_mac_add(int argc, char *argv[])
800{
developerbe40a9e2024-03-07 21:44:26 +0800801 unsigned int value = 0;
802 int ports = 0;
developerfd40db22021-04-29 10:08:25 +0800803 char tmpstr[5];
804 int ret;
developer546b2792024-06-15 20:31:38 +0800805 char *endptr;
developerfd40db22021-04-29 10:08:25 +0800806
807 ret = acl_parameters_pre_del(6, 12, argc, argv, &ports);
808 if (ret < 0)
809 return;
developerbe40a9e2024-03-07 21:44:26 +0800810 /* Set pattern */
developerfd40db22021-04-29 10:08:25 +0800811 strncpy(tmpstr, argv[4], 4);
812 tmpstr[4] = '\0';
developer546b2792024-06-15 20:31:38 +0800813 errno = 0;
814 value = strtoul(tmpstr, &endptr, 16);
815 if (errno != 0 || *endptr != '\0')
816 goto error;
817
developerfd40db22021-04-29 10:08:25 +0800818 acl_compare_pattern(ports, value, 0x0, 0, 0);
819
820 strncpy(tmpstr, argv[4] + 4, 4);
821 tmpstr[4] = '\0';
developer546b2792024-06-15 20:31:38 +0800822 errno = 0;
823 value = strtoul(tmpstr, &endptr, 16);
824 if (errno != 0 || *endptr != '\0')
825 goto error;
developerfd40db22021-04-29 10:08:25 +0800826 acl_compare_pattern(ports, value, 0x0, 1, 1);
827
828 strncpy(tmpstr, argv[4] + 8, 4);
829 tmpstr[4] = '\0';
developer546b2792024-06-15 20:31:38 +0800830 errno = 0;
831 value = strtoul(tmpstr, &endptr, 16);
832 if (errno != 0 || *endptr != '\0')
833 goto error;
developerfd40db22021-04-29 10:08:25 +0800834 acl_compare_pattern(ports, value, 0x0, 2, 2);
835
836 //set mask
developerbe40a9e2024-03-07 21:44:26 +0800837 write_acl_mask_table(0, 0x7, 0);
developerfd40db22021-04-29 10:08:25 +0800838
839 //set action
developerbe40a9e2024-03-07 21:44:26 +0800840 value = 0x7; //drop
841 value |= 1 << 28; //acl intterupt enable
842 value |= 1 << 27; //acl hit count
843 value |= 2 << 24; //acl hit count group index (0~3)
844 write_acl_rule_table(0, value, 0);
developer546b2792024-06-15 20:31:38 +0800845 return;
846
847error:
848 printf("Error: string converting\n");
849 return;
developerfd40db22021-04-29 10:08:25 +0800850}
851
852void acl_dip_meter(int argc, char *argv[])
853{
developerbe40a9e2024-03-07 21:44:26 +0800854 unsigned int value = 0, ip_value = 0, meter = 0;
855 int ports = 0;
developerfd40db22021-04-29 10:08:25 +0800856 int ret;
857
858 ip_value = 0;
859 ret = acl_parameters_pre_del(7, -1, argc, argv, &ports);
860 if (ret < 0)
861 return;
862
863 str_to_ip(&ip_value, argv[4]);
864 //set pattern
865 value = (ip_value >> 16);
866 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
867
868 //set pattern
869 value = (ip_value & 0xffff);
870 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
871
872 //set mask
developerbe40a9e2024-03-07 21:44:26 +0800873 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800874
875 //set action
876 meter = strtoul(argv[6], NULL, 0);
877 if (((chip_name == 0x7530) && (meter > 1000000)) ||
developerbe40a9e2024-03-07 21:44:26 +0800878 ((chip_name == 0x7531) && (meter > 2500000)) ||
879 ((chip_name == 0x7988) && (meter > 4000000))) {
developer8c3871b2022-07-01 14:07:53 +0800880 printf("\n**Illegal meter input, and 7530: 0~1000000Kpbs, 7531: 0~2500000Kpbs, 7988: 0~4000000Kpbs**\n");
developerfd40db22021-04-29 10:08:25 +0800881 return;
882 }
developer8c3871b2022-07-01 14:07:53 +0800883 if (((chip_name == 0x7531 || chip_name == 0x7988) && (meter > 1000000))) {
developerbe40a9e2024-03-07 21:44:26 +0800884 reg_read(0xc, &value);
developerfd40db22021-04-29 10:08:25 +0800885 value |= 0x1 << 30;
developerbe40a9e2024-03-07 21:44:26 +0800886 reg_write(0xC, value);
887 printf("AGC: 0x%x\n", value);
888 value = meter / 1000; //uint is 1Mbps
developerfd40db22021-04-29 10:08:25 +0800889 } else {
developerbe40a9e2024-03-07 21:44:26 +0800890 reg_read(0xc, &value);
developerfd40db22021-04-29 10:08:25 +0800891 value &= ~(0x1 << 30);
developerbe40a9e2024-03-07 21:44:26 +0800892 reg_write(0xC, value);
893 printf("AGC: 0x%x\n", value);
894 value = meter >> 6; //uint is 64Kbps
developerfd40db22021-04-29 10:08:25 +0800895 }
developerbe40a9e2024-03-07 21:44:26 +0800896 value |= 0x1 << 15; //enable rate control
897 printf("Acl rate control:0x%x\n", value);
developerfd40db22021-04-29 10:08:25 +0800898 write_rate_table(0, value, 0);
899}
900
901void acl_dip_trtcm(int argc, char *argv[])
902{
903 unsigned int value, value2, ip_value;
904 unsigned int CIR, CBS, PIR, PBS;
905 int ports;
906 int ret;
907
908 ip_value = 0;
909 ret = acl_parameters_pre_del(10, -1, argc, argv, &ports);
910 if (ret < 0)
911 return;
912
913 str_to_ip(&ip_value, argv[4]);
914 //set pattern
915 value = (ip_value >> 16);
916 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
917
918 //set pattern
919 value = (ip_value & 0xffff);
920 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
921
922 //set CBS PBS
923 CIR = strtoul(argv[6], NULL, 0);
924 CBS = strtoul(argv[7], NULL, 0);
925 PIR = strtoul(argv[8], NULL, 0);
926 PBS = strtoul(argv[9], NULL, 0);
927
developerbe40a9e2024-03-07 21:44:26 +0800928 if (CIR > 65535 * 64 || CBS > 65535 || PIR > 65535 * 64 || PBS > 65535) {
developerfd40db22021-04-29 10:08:25 +0800929 printf("\n**Illegal input parameters**\n");
930 return;
931 }
932
developerbe40a9e2024-03-07 21:44:26 +0800933 value = CBS << 16; //bit16~31
934 value |= PBS; //bit0~15
935 //value |= 1;//valid
developerfd40db22021-04-29 10:08:25 +0800936 CIR = CIR >> 6;
937 PIR = PIR >> 6;
938
developerbe40a9e2024-03-07 21:44:26 +0800939 value2 = CIR << 16; //bit16~31
940 value2 |= PIR; //bit0~15
941 write_trTCM_table(0, value, value2);
developerfd40db22021-04-29 10:08:25 +0800942
943 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800944 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800945
946 //set action
developerbe40a9e2024-03-07 21:44:26 +0800947 value = 0x1 << (11 + 1); //TrTCM green meter#0 Low drop
948 value |= 0x2 << (8 + 1); //TrTCM yellow meter#0 Med drop
949 value |= 0x3 << (5 + 1); //TrTCM red meter#0 Hig drop
950 value |= 0x1 << 0; //TrTCM drop pcd select
951 write_acl_rule_table(0, 0, value);
developerfd40db22021-04-29 10:08:25 +0800952}
953
954void acl_ethertype(int argc, char *argv[])
955{
956 unsigned int value, ethertype;
957 int ports;
958 int ret;
959
960 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
961 if (ret < 0)
962 return;
developerbe40a9e2024-03-07 21:44:26 +0800963 printf("ports:0x%x\n", ports);
developerfd40db22021-04-29 10:08:25 +0800964 ethertype = strtoul(argv[4], NULL, 16);
965 //set pattern
966 value = ethertype;
967 acl_compare_pattern(ports, value, 0x0, 0x6, 0);
968
969 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800970 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +0800971
972 //set action(drop)
developerbe40a9e2024-03-07 21:44:26 +0800973 value = 0x7; //default. Nodrop
974 value |= 1 << 28; //acl intterupt enable
975 value |= 1 << 27; //acl hit count
developerfd40db22021-04-29 10:08:25 +0800976
developerbe40a9e2024-03-07 21:44:26 +0800977 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +0800978}
979
980void acl_dip_modify(int argc, char *argv[])
981{
982 unsigned int value, ip_value;
983 int ports;
984 int priority;
985 int ret;
986
987 ip_value = 0;
988 priority = strtoul(argv[6], NULL, 16);
989 if (priority < 0 || priority > 7) {
990 printf("\n**Illegal priority value!**\n");
991 return;
992 }
993
994 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
995 if (ret < 0)
996 return;
997
998 str_to_ip(&ip_value, argv[4]);
999 //set pattern
1000 value = (ip_value >> 16);
1001 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
1002
1003 //set pattern
1004 value = (ip_value & 0xffff);
1005 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
1006
1007 //set pattern
developerbe40a9e2024-03-07 21:44:26 +08001008 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +08001009
1010 //set action
developerbe40a9e2024-03-07 21:44:26 +08001011 value = 0x0; //default. Nodrop
1012 value |= 1 << 28; //acl intterupt enable
1013 value |= 1 << 27; //acl hit count
1014 value |= priority << 4; //acl UP
1015 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001016}
1017
1018void acl_dip_pppoe(int argc, char *argv[])
1019{
1020 unsigned int value, ip_value;
1021 int ports;
1022 int ret;
1023
1024 ip_value = 0;
1025 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1026 if (ret < 0)
1027 return;
1028
1029 str_to_ip(&ip_value, argv[4]);
1030 //set pattern
1031 value = (ip_value >> 16);
1032 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
1033
1034 //set pattern
1035 value = (ip_value & 0xffff);
1036 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
1037
1038 //set pattern
developerbe40a9e2024-03-07 21:44:26 +08001039 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +08001040
1041 //set action
developerbe40a9e2024-03-07 21:44:26 +08001042 value = 0x0; //default. Nodrop
1043 value |= 1 << 28; //acl intterupt enable
1044 value |= 1 << 27; //acl hit count
1045 value |= 1 << 20; //pppoe header remove
1046 value |= 1 << 21; //SA MAC SWAP
1047 value |= 1 << 22; //DA MAC SWAP
1048 write_acl_rule_table(0, value, 7);
developerfd40db22021-04-29 10:08:25 +08001049}
1050
1051void acl_dip_add(int argc, char *argv[])
1052{
1053 unsigned int value, ip_value;
1054 int ports;
1055 int ret;
1056
1057 ip_value = 0;
1058 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1059 if (ret < 0)
1060 return;
1061
1062 str_to_ip(&ip_value, argv[4]);
1063 //set pattern
1064 value = (ip_value >> 16);
1065 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
1066
1067 //set pattern
1068 value = (ip_value & 0xffff);
1069 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
1070
1071 //set pattern
developerbe40a9e2024-03-07 21:44:26 +08001072 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +08001073
1074 //set action
1075 //value = 0x0; //default
developerbe40a9e2024-03-07 21:44:26 +08001076 value = 0x7; //drop
1077 value |= 1 << 28; //acl intterupt enable
1078 value |= 1 << 27; //acl hit count
1079 value |= 2 << 24; //acl hit count group index (0~3)
1080 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001081}
1082
1083void acl_l4_add(int argc, char *argv[])
1084{
developerbe40a9e2024-03-07 21:44:26 +08001085 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001086 int ports;
1087 int ret;
1088
1089 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1090 if (ret < 0)
1091 return;
1092
1093 //set pattern
1094 value = strtoul(argv[4], NULL, 16);
1095 acl_compare_pattern(ports, value, 0x5, 0x0, 0);
1096
1097 //set rue mask
developerbe40a9e2024-03-07 21:44:26 +08001098 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +08001099 //set action
developerbe40a9e2024-03-07 21:44:26 +08001100 value = 0x7; //drop
1101 //value |= 1;//valid
1102 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001103}
1104
1105void acl_sp_add(int argc, char *argv[])
1106{
developerbe40a9e2024-03-07 21:44:26 +08001107 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001108 int ports;
1109 int ret;
1110
1111 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1112 if (ret < 0)
1113 return;
1114 //set pattern
1115 value = strtoul(argv[4], NULL, 0);
1116 acl_compare_pattern(ports, value, 0x4, 0x0, 0);
1117
1118 //set rue mask
developerbe40a9e2024-03-07 21:44:26 +08001119 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +08001120
1121 //set action
developerbe40a9e2024-03-07 21:44:26 +08001122 value = 0x7; //drop
1123 //value |= 1;//valid
1124 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001125}
1126
1127void acl_port_enable(int argc, char *argv[])
1128{
developerbe40a9e2024-03-07 21:44:26 +08001129 unsigned int value = 0, reg = 0;
1130 unsigned char acl_port = 0, acl_en = 0;
developer546b2792024-06-15 20:31:38 +08001131 char *endptr;
developerfd40db22021-04-29 10:08:25 +08001132
developer546b2792024-06-15 20:31:38 +08001133 errno = 0;
1134 acl_port = strtoul(argv[3], &endptr, 10);
1135 if (errno != 0 || *endptr != '\0' || acl_port > MAX_PORT) {
1136 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
1137 return;
1138 }
developerfd40db22021-04-29 10:08:25 +08001139
developer546b2792024-06-15 20:31:38 +08001140 errno = 0;
1141 acl_en = strtoul(argv[4], &endptr, 10);
1142 if (errno != 0 || *endptr != '\0' || acl_en > 1) {
developerfd40db22021-04-29 10:08:25 +08001143 printf(HELP_ACL_SETPORTEN);
1144 return;
1145 }
1146
developer546b2792024-06-15 20:31:38 +08001147 printf("acl_port:%d, acl_en:%d\n", acl_port, acl_en);
1148
developerbe40a9e2024-03-07 21:44:26 +08001149 reg = REG_PCR_P0_ADDR + (0x100 * acl_port); // 0x2004[10]
developerfd40db22021-04-29 10:08:25 +08001150 reg_read(reg, &value);
1151 value &= (~REG_PORT_ACL_EN_MASK);
1152 value |= (acl_en << REG_PORT_ACL_EN_OFFT);
1153
1154 printf("write reg: %x, value: %x\n", reg, value);
1155 reg_write(reg, value);
1156}
1157
1158static void dip_dump_internal(int type)
1159{
1160 unsigned int i, j, value, mac, mac2, value2;
developerbe40a9e2024-03-07 21:44:26 +08001161 char tmpstr[16] = { 0 };
developerfd40db22021-04-29 10:08:25 +08001162 int table_size = 0;
1163 int hit_value1 = 0;
1164 int hit_value2 = 0;
1165
developerbe40a9e2024-03-07 21:44:26 +08001166 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001167 table_size = 0x800;
developerbe40a9e2024-03-07 21:44:26 +08001168 reg_write(REG_ATC_ADDR, 0x8104); //dip search command
1169 } else {
developerfd40db22021-04-29 10:08:25 +08001170 table_size = 0x40;
developerbe40a9e2024-03-07 21:44:26 +08001171 reg_write(REG_ATC_ADDR, 0x811c); //dip search command
developerfd40db22021-04-29 10:08:25 +08001172 }
developerbe40a9e2024-03-07 21:44:26 +08001173 printf
1174 ("hash port(0:6) rsp_cnt flag timer dip-address ATRD\n");
developerfd40db22021-04-29 10:08:25 +08001175 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001176 while (1) {
developerfd40db22021-04-29 10:08:25 +08001177 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001178 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001179 hit_value1 = value & (0x1 << 13);
1180 hit_value2 = 1;
developerbe40a9e2024-03-07 21:44:26 +08001181 } else {
developerfd40db22021-04-29 10:08:25 +08001182 hit_value1 = value & (0x1 << 13);
1183 hit_value2 = value & (0x1 << 28);
1184 }
1185
developerbe40a9e2024-03-07 21:44:26 +08001186 if (hit_value1 && hit_value2) { //search_rdy
developerfd40db22021-04-29 10:08:25 +08001187 reg_read(REG_ATRD_ADDR, &value2);
1188 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1189
developerbe40a9e2024-03-07 21:44:26 +08001190 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1191 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001192 printf("%c", (j & 0x01) ? '1' : '-');
1193 printf("%c", (j & 0x02) ? '1' : '-');
1194 printf("%c", (j & 0x04) ? '1' : '-');
1195 printf("%c ", (j & 0x08) ? '1' : '-');
1196 printf("%c", (j & 0x10) ? '1' : '-');
1197 printf("%c", (j & 0x20) ? '1' : '-');
1198 printf("%c", (j & 0x40) ? '1' : '-');
1199
1200 reg_read(REG_TSRA2_ADDR, &mac2);
1201
developerbe40a9e2024-03-07 21:44:26 +08001202 printf(" 0x%4x", (mac2 & 0xffff)); //RESP_CNT
1203 printf(" 0x%2x", ((mac2 >> 16) & 0xff)); //RESP_FLAG
1204 printf(" %3d", ((mac2 >> 24) & 0xff)); //RESP_TIMER
1205 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001206 reg_read(REG_TSRA1_ADDR, &mac);
developer546b2792024-06-15 20:31:38 +08001207 ip_to_str(tmpstr, sizeof(tmpstr), mac);
developerfd40db22021-04-29 10:08:25 +08001208 printf(" %s", tmpstr);
developerbe40a9e2024-03-07 21:44:26 +08001209 printf(" 0x%8x\n", value2); //ATRD
1210 //printf("%04x", ((mac2 >> 16) & 0xffff));
1211 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
developerfd40db22021-04-29 10:08:25 +08001212 if (value & 0x4000) {
1213 printf("end of table %d\n", i);
1214 return;
1215 }
1216 break;
developerbe40a9e2024-03-07 21:44:26 +08001217 } else if (value & 0x4000) { //at_table_end
1218 printf("found the last entry %d (not ready)\n",
1219 i);
developerfd40db22021-04-29 10:08:25 +08001220 return;
1221 }
1222 usleep(5000);
1223 }
1224
developerbe40a9e2024-03-07 21:44:26 +08001225 if (type == GENERAL_TABLE)
1226 reg_write(REG_ATC_ADDR, 0x8105); //search for next dip address
developerfd40db22021-04-29 10:08:25 +08001227 else
developerbe40a9e2024-03-07 21:44:26 +08001228 reg_write(REG_ATC_ADDR, 0x811d); //search for next dip address
developerfd40db22021-04-29 10:08:25 +08001229 usleep(5000);
1230 }
1231}
1232
developerbe40a9e2024-03-07 21:44:26 +08001233void dip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001234{
1235 dip_dump_internal(GENERAL_TABLE);
1236
1237}
1238
1239void dip_add(int argc, char *argv[])
1240{
1241 unsigned int value = 0;
developerbe40a9e2024-03-07 21:44:26 +08001242 unsigned int i = 0, j = 0;
developerfd40db22021-04-29 10:08:25 +08001243
1244 value = 0;
1245
1246 str_to_ip(&value, argv[3]);
1247
1248 reg_write(REG_ATA1_ADDR, value);
1249 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1250
1251#if 0
1252 reg_write(REG_ATA2_ADDR, value);
1253 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1254#endif
1255 if (!argv[4] || strlen(argv[4]) != 8) {
1256 printf("portmap format error, should be of length 7\n");
1257 return;
1258 }
1259 j = 0;
1260 for (i = 0; i < 7; i++) {
1261 if (argv[4][i] != '0' && argv[4][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001262 printf
1263 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001264 return;
1265 }
1266 j += (argv[4][i] - '0') * (1 << i);
1267 }
developerbe40a9e2024-03-07 21:44:26 +08001268 value = j << 4; //w_port_map
1269 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001270
1271 reg_write(REG_ATWD_ADDR, value);
1272
1273 usleep(5000);
1274 reg_read(REG_ATWD_ADDR, &value);
1275 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1276
developerbe40a9e2024-03-07 21:44:26 +08001277 value = 0x8011; //single w_dip_cmd
developerfd40db22021-04-29 10:08:25 +08001278 reg_write(REG_ATC_ADDR, value);
1279
1280 usleep(1000);
1281
1282 for (i = 0; i < 20; i++) {
1283 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001284 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001285 printf("done.\n");
1286 return;
1287 }
1288 usleep(1000);
1289 }
1290 if (i == 20)
1291 printf("timeout.\n");
1292}
1293
1294void dip_del(int argc, char *argv[])
1295{
1296 unsigned int i, value;
1297
1298 value = 0;
1299 str_to_ip(&value, argv[3]);
1300
1301 reg_write(REG_ATA1_ADDR, value);
1302
1303 value = 0;
1304 reg_write(REG_ATA2_ADDR, value);
1305
developerbe40a9e2024-03-07 21:44:26 +08001306 value = 0; //STATUS=0, delete dip
developerfd40db22021-04-29 10:08:25 +08001307 reg_write(REG_ATWD_ADDR, value);
1308
developerbe40a9e2024-03-07 21:44:26 +08001309 value = 0x8011; //w_dip_cmd
developerfd40db22021-04-29 10:08:25 +08001310 reg_write(REG_ATC_ADDR, value);
1311
1312 for (i = 0; i < 20; i++) {
1313 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001314 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001315 if (argv[1] != NULL)
1316 printf("done.\n");
1317 return;
1318 }
1319 usleep(1000);
1320 }
1321 if (i == 20)
1322 printf("timeout.\n");
1323}
1324
developerbe40a9e2024-03-07 21:44:26 +08001325void dip_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001326{
1327
developerbe40a9e2024-03-07 21:44:26 +08001328 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001329
developerbe40a9e2024-03-07 21:44:26 +08001330 reg_write(REG_ATC_ADDR, 0x8102); //clear all dip
developerfd40db22021-04-29 10:08:25 +08001331 usleep(5000);
1332 reg_read(REG_ATC_ADDR, &value);
1333 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1334}
1335
1336static void sip_dump_internal(int type)
1337{
developerbe40a9e2024-03-07 21:44:26 +08001338 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001339 int table_size = 0;
1340 int hit_value1 = 0;
1341 int hit_value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08001342 char tmpstr[16] = { 0 };
developerfd40db22021-04-29 10:08:25 +08001343
1344 if (type == GENERAL_TABLE) {
1345 table_size = 0x800;
developerbe40a9e2024-03-07 21:44:26 +08001346 reg_write(REG_ATC_ADDR, 0x8204); //sip search command
1347 } else {
developerfd40db22021-04-29 10:08:25 +08001348 table_size = 0x40;
developerbe40a9e2024-03-07 21:44:26 +08001349 reg_write(REG_ATC_ADDR, 0x822c); //sip search command
developerfd40db22021-04-29 10:08:25 +08001350 }
1351 printf("hash port(0:6) dip-address sip-address ATRD\n");
1352 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001353 while (1) {
developerfd40db22021-04-29 10:08:25 +08001354 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001355 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001356 hit_value1 = value & (0x1 << 13);
1357 hit_value2 = 1;
1358 } else {
1359 hit_value1 = value & (0x1 << 13);
1360 hit_value2 = value & (0x1 << 28);
1361 }
1362
developerbe40a9e2024-03-07 21:44:26 +08001363 if (hit_value1 && hit_value2) { //search_rdy
developerfd40db22021-04-29 10:08:25 +08001364 reg_read(REG_ATRD_ADDR, &value2);
1365 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1366
developerbe40a9e2024-03-07 21:44:26 +08001367 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1368 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001369 printf("%c", (j & 0x01) ? '1' : '-');
1370 printf("%c", (j & 0x02) ? '1' : '-');
1371 printf("%c", (j & 0x04) ? '1' : '-');
1372 printf("%c", (j & 0x08) ? '1' : '-');
1373 printf(" %c", (j & 0x10) ? '1' : '-');
1374 printf("%c", (j & 0x20) ? '1' : '-');
1375 printf("%c", (j & 0x40) ? '1' : '-');
1376
1377 reg_read(REG_TSRA2_ADDR, &mac2);
1378
developer546b2792024-06-15 20:31:38 +08001379 ip_to_str(tmpstr, sizeof(tmpstr), mac2);
developerfd40db22021-04-29 10:08:25 +08001380 printf(" %s", tmpstr);
1381
1382 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
1383 reg_read(REG_TSRA1_ADDR, &mac);
developer546b2792024-06-15 20:31:38 +08001384 ip_to_str(tmpstr, sizeof(tmpstr), mac);
developerfd40db22021-04-29 10:08:25 +08001385 printf(" %s", tmpstr);
1386 printf(" 0x%x\n", value2);
1387 //printf("%04x", ((mac2 >> 16) & 0xffff));
1388 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
1389 if (value & 0x4000) {
1390 printf("end of table %d\n", i);
1391 return;
1392 }
1393 break;
developerbe40a9e2024-03-07 21:44:26 +08001394 } else if (value & 0x4000) { //at_table_end
1395 printf("found the last entry %d (not ready)\n",
1396 i);
developerfd40db22021-04-29 10:08:25 +08001397 return;
1398 }
1399 usleep(5000);
1400 }
1401
developerbe40a9e2024-03-07 21:44:26 +08001402 if (type == GENERAL_TABLE)
1403 reg_write(REG_ATC_ADDR, 0x8205); //search for next sip address
1404 else
1405 reg_write(REG_ATC_ADDR, 0x822d); //search for next sip address
1406 usleep(5000);
developerfd40db22021-04-29 10:08:25 +08001407 }
1408}
1409
developerbe40a9e2024-03-07 21:44:26 +08001410void sip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001411{
1412
1413 sip_dump_internal(GENERAL_TABLE);
1414
1415}
1416
developerfd40db22021-04-29 10:08:25 +08001417void sip_add(int argc, char *argv[])
1418{
developerbe40a9e2024-03-07 21:44:26 +08001419 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001420
1421 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08001422 str_to_ip(&value, argv[3]); //SIP
developerfd40db22021-04-29 10:08:25 +08001423
1424 reg_write(REG_ATA2_ADDR, value);
1425 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1426
1427 value = 0;
1428
developerbe40a9e2024-03-07 21:44:26 +08001429 str_to_ip(&value, argv[4]); //DIP
developerfd40db22021-04-29 10:08:25 +08001430 reg_write(REG_ATA1_ADDR, value);
1431 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1432
1433 if (!argv[5] || strlen(argv[5]) != 8) {
1434 printf("portmap format error, should be of length 7\n");
1435 return;
1436 }
1437 j = 0;
1438 for (i = 0; i < 7; i++) {
1439 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001440 printf
1441 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001442 return;
1443 }
1444 j += (argv[5][i] - '0') * (1 << i);
1445 }
developerbe40a9e2024-03-07 21:44:26 +08001446 value = j << 4; //w_port_map
1447 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001448
1449 reg_write(REG_ATWD_ADDR, value);
1450
1451 usleep(5000);
1452 reg_read(REG_ATWD_ADDR, &value);
1453 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1454
developerbe40a9e2024-03-07 21:44:26 +08001455 value = 0x8021; //single w_sip_cmd
developerfd40db22021-04-29 10:08:25 +08001456 reg_write(REG_ATC_ADDR, value);
1457
1458 usleep(1000);
1459
1460 for (i = 0; i < 20; i++) {
1461 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001462 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001463 printf("done.\n");
1464 return;
1465 }
1466 usleep(1000);
1467 }
1468 if (i == 20)
1469 printf("timeout.\n");
1470}
1471
1472void sip_del(int argc, char *argv[])
1473{
developerbe40a9e2024-03-07 21:44:26 +08001474 unsigned int i = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001475
1476 value = 0;
1477 str_to_ip(&value, argv[3]);
1478
developerbe40a9e2024-03-07 21:44:26 +08001479 reg_write(REG_ATA2_ADDR, value); //SIP
developerfd40db22021-04-29 10:08:25 +08001480
1481 str_to_ip(&value, argv[4]);
developerbe40a9e2024-03-07 21:44:26 +08001482 reg_write(REG_ATA1_ADDR, value); //DIP
developerfd40db22021-04-29 10:08:25 +08001483
developerbe40a9e2024-03-07 21:44:26 +08001484 value = 0; //STATUS=0, delete sip
developerfd40db22021-04-29 10:08:25 +08001485 reg_write(REG_ATWD_ADDR, value);
1486
developerbe40a9e2024-03-07 21:44:26 +08001487 value = 0x8021; //w_sip_cmd
developerfd40db22021-04-29 10:08:25 +08001488 reg_write(REG_ATC_ADDR, value);
1489
1490 for (i = 0; i < 20; i++) {
1491 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001492 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001493 if (argv[1] != NULL)
1494 printf("done.\n");
1495 return;
1496 }
1497 usleep(1000);
1498 }
1499 if (i == 20)
1500 printf("timeout.\n");
1501}
1502
developerbe40a9e2024-03-07 21:44:26 +08001503void sip_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001504{
developerbe40a9e2024-03-07 21:44:26 +08001505 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001506
developerbe40a9e2024-03-07 21:44:26 +08001507 reg_write(REG_ATC_ADDR, 0x8202); //clear all sip
developerfd40db22021-04-29 10:08:25 +08001508 usleep(5000);
1509 reg_read(REG_ATC_ADDR, &value);
1510 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1511}
1512
1513static void table_dump_internal(int type)
1514{
developerbe40a9e2024-03-07 21:44:26 +08001515 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001516 int table_size = 0;
1517 int table_end = 0;
1518 int hit_value1 = 0;
1519 int hit_value2 = 0;
1520
developerbe40a9e2024-03-07 21:44:26 +08001521 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001522 table_size = 0x800;
1523 table_end = 0x7FF;
1524 reg_write(REG_ATC_ADDR, 0x8004);
1525 } else {
1526 table_size = 0x40;
1527 table_end = 0x3F;
1528 reg_write(REG_ATC_ADDR, 0x800C);
1529 }
developerbe40a9e2024-03-07 21:44:26 +08001530 printf
1531 ("hash port(0:6) fid vid age(s) mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001532 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001533 while (1) {
developerfd40db22021-04-29 10:08:25 +08001534 reg_read(REG_ATC_ADDR, &value);
1535 //printf("ATC = 0x%x\n", value);
developerbe40a9e2024-03-07 21:44:26 +08001536 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001537 hit_value1 = value & (0x1 << 13);
1538 hit_value2 = 1;
1539 } else {
1540 hit_value1 = value & (0x1 << 13);
1541 hit_value2 = value & (0x1 << 28);
1542 }
1543
developerbe40a9e2024-03-07 21:44:26 +08001544 if (hit_value1 && hit_value2
1545 && (((value >> 15) & 0x1) == 0)) {
developerfd40db22021-04-29 10:08:25 +08001546 printf("%03x: ", (value >> 16) & 0xfff);
1547 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001548 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001549 printf("%c", (j & 0x01) ? '1' : '-');
1550 printf("%c", (j & 0x02) ? '1' : '-');
1551 printf("%c", (j & 0x04) ? '1' : '-');
1552 printf("%c", (j & 0x08) ? '1' : '-');
1553 printf("%c", (j & 0x10) ? '1' : '-');
1554 printf("%c", (j & 0x20) ? '1' : '-');
1555 printf("%c", (j & 0x40) ? '1' : '-');
1556 printf("%c", (j & 0x80) ? '1' : '-');
1557
1558 reg_read(REG_TSRA2_ADDR, &mac2);
1559
developerbe40a9e2024-03-07 21:44:26 +08001560 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001561 printf(" %4d", (mac2 & 0xfff));
1562 if (((value2 >> 24) & 0xff) == 0xFF)
developerbe40a9e2024-03-07 21:44:26 +08001563 printf(" --- "); //r_age_field:static
developerfd40db22021-04-29 10:08:25 +08001564 else
developerbe40a9e2024-03-07 21:44:26 +08001565 printf(" %5d ", (((value2 >> 24) & 0xff) + 1) * 2); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001566 reg_read(REG_TSRA1_ADDR, &mac);
1567 printf(" %08x", mac);
1568 printf("%04x", ((mac2 >> 16) & 0xffff));
developerbe40a9e2024-03-07 21:44:26 +08001569 printf(" %c",
1570 (((value2 >> 20) & 0x03) ==
1571 0x03) ? 'y' : '-');
1572 printf(" %c\n",
1573 (((value2 >> 23) & 0x01) ==
1574 0x01) ? 'y' : '-');
1575 if ((value & 0x4000)
1576 && (((value >> 16) & 0xfff) == table_end)) {
developerfd40db22021-04-29 10:08:25 +08001577 printf("end of table %d\n", i);
1578 return;
1579 }
1580 break;
developerbe40a9e2024-03-07 21:44:26 +08001581 } else if ((value & 0x4000) && (((value >> 15) & 0x1) == 0) && (((value >> 16) & 0xfff) == table_end)) { //at_table_end
1582 printf("found the last entry %d (not ready)\n",
1583 i);
developerfd40db22021-04-29 10:08:25 +08001584 return;
developerbe40a9e2024-03-07 21:44:26 +08001585 } else
developerfd40db22021-04-29 10:08:25 +08001586 usleep(5);
1587 }
1588
developerbe40a9e2024-03-07 21:44:26 +08001589 if (type == GENERAL_TABLE)
1590 reg_write(REG_ATC_ADDR, 0x8005); //search for next address
1591 else
1592 reg_write(REG_ATC_ADDR, 0x800d); //search for next address
developerfd40db22021-04-29 10:08:25 +08001593 usleep(5);
1594 }
1595}
1596
developerbe40a9e2024-03-07 21:44:26 +08001597void table_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001598{
1599 table_dump_internal(GENERAL_TABLE);
1600
1601}
1602
developerfd40db22021-04-29 10:08:25 +08001603void table_add(int argc, char *argv[])
1604{
developerbe40a9e2024-03-07 21:44:26 +08001605 unsigned int i = 0, j = 0, value = 0, is_filter = 0, is_mymac = 0;
developerfd40db22021-04-29 10:08:25 +08001606 char tmpstr[9];
1607
1608 is_filter = (argv[1][0] == 'f') ? 1 : 0;
1609 is_mymac = (argv[1][0] == 'm') ? 1 : 0;
1610 if (!argv[2] || strlen(argv[2]) != 12) {
1611 printf("MAC address format error, should be of length 12\n");
1612 return;
1613 }
1614 strncpy(tmpstr, argv[2], 8);
1615 tmpstr[8] = '\0';
1616 value = strtoul(tmpstr, NULL, 16);
1617 reg_write(REG_ATA1_ADDR, value);
1618 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1619
1620 strncpy(tmpstr, argv[2] + 8, 4);
1621 tmpstr[4] = '\0';
1622
1623 value = strtoul(tmpstr, NULL, 16);
1624 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001625 value |= (1 << 15); //IVL=1
developerfd40db22021-04-29 10:08:25 +08001626
1627 if (argc > 4) {
1628 j = strtoul(argv[4], NULL, 0);
1629 if (4095 < j) {
1630 printf("wrong vid range, should be within 0~4095\n");
1631 return;
1632 }
developerbe40a9e2024-03-07 21:44:26 +08001633 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001634 }
1635
1636 reg_write(REG_ATA2_ADDR, value);
1637 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1638
1639 if (!argv[3] || strlen(argv[3]) != 8) {
1640 if (is_filter)
1641 argv[3] = "11111111";
1642 else {
1643 printf("portmap format error, should be of length 8\n");
1644 return;
1645 }
1646 }
1647 j = 0;
1648 for (i = 0; i < 7; i++) {
1649 if (argv[3][i] != '0' && argv[3][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001650 printf
1651 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001652 return;
1653 }
1654 j += (argv[3][i] - '0') * (1 << i);
1655 }
developerbe40a9e2024-03-07 21:44:26 +08001656 value = j << 4; //w_port_map
developerfd40db22021-04-29 10:08:25 +08001657
1658 if (argc > 5) {
1659 j = strtoul(argv[5], NULL, 0);
1660 if (j < 1 || 255 < j) {
1661 printf("wrong age range, should be within 1~255\n");
1662 return;
1663 }
developerbe40a9e2024-03-07 21:44:26 +08001664 value |= (j << 24); //w_age_field
1665 value |= (0x1 << 2); //dynamic
developerfd40db22021-04-29 10:08:25 +08001666 } else {
developerbe40a9e2024-03-07 21:44:26 +08001667 value |= (0xff << 24); //w_age_field
1668 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001669 }
1670
1671 if (argc > 6) {
1672 j = strtoul(argv[6], NULL, 0);
1673 if (7 < j) {
1674 printf("wrong eg-tag range, should be within 0~7\n");
1675 return;
1676 }
developerbe40a9e2024-03-07 21:44:26 +08001677 value |= (j << 13); //EG_TAG
developerfd40db22021-04-29 10:08:25 +08001678 }
1679
1680 if (is_filter)
developerbe40a9e2024-03-07 21:44:26 +08001681 value |= (7 << 20); //sa_filter
developerfd40db22021-04-29 10:08:25 +08001682
1683 if (is_mymac)
1684 value |= (1 << 23);
1685
1686 reg_write(REG_ATWD_ADDR, value);
1687
1688 usleep(5000);
1689 reg_read(REG_ATWD_ADDR, &value);
1690 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1691
developerbe40a9e2024-03-07 21:44:26 +08001692 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001693 reg_write(REG_ATC_ADDR, value);
1694
1695 usleep(1000);
1696
1697 for (i = 0; i < 20; i++) {
1698 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001699 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001700 printf("done.\n");
1701 return;
1702 }
1703 usleep(1000);
1704 }
1705 if (i == 20)
1706 printf("timeout.\n");
1707}
1708
1709void table_search_mac_vid(int argc, char *argv[])
1710{
developerbe40a9e2024-03-07 21:44:26 +08001711 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001712 char tmpstr[9];
1713
1714 if (!argv[3] || strlen(argv[3]) != 12) {
1715 printf("MAC address format error, should be of length 12\n");
1716 return;
1717 }
1718 strncpy(tmpstr, argv[3], 8);
1719 tmpstr[8] = '\0';
1720 value = strtoul(tmpstr, NULL, 16);
1721 reg_write(REG_ATA1_ADDR, value);
1722 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1723
1724 strncpy(tmpstr, argv[3] + 8, 4);
1725 tmpstr[4] = '\0';
1726
1727 value = strtoul(tmpstr, NULL, 16);
1728 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001729 value |= (1 << 15); //IVL=1
developerfd40db22021-04-29 10:08:25 +08001730
1731 j = strtoul(argv[5], NULL, 0);
1732 if (4095 < j) {
1733 printf("wrong vid range, should be within 0~4095\n");
1734 return;
1735 }
developerbe40a9e2024-03-07 21:44:26 +08001736 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001737
1738 reg_write(REG_ATA2_ADDR, value);
1739 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1740
developerbe40a9e2024-03-07 21:44:26 +08001741 value = 0x8000; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001742 reg_write(REG_ATC_ADDR, value);
1743
1744 usleep(1000);
1745
1746 for (i = 0; i < 20; i++) {
1747 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001748 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001749 break;
1750 }
1751 usleep(1000);
1752 }
1753 if (i == 20) {
1754 printf("search timeout.\n");
1755 return;
1756 }
1757
1758 if (value & 0x1000) {
1759 printf("search no entry.\n");
1760 return;
1761 }
1762
1763 printf("search done.\n");
developerbe40a9e2024-03-07 21:44:26 +08001764 printf
1765 ("hash port(0:6) fid vid age mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001766
developerbe40a9e2024-03-07 21:44:26 +08001767 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
developerfd40db22021-04-29 10:08:25 +08001768 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001769 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001770 printf("%c", (j & 0x01) ? '1' : '-');
1771 printf("%c", (j & 0x02) ? '1' : '-');
1772 printf("%c", (j & 0x04) ? '1' : '-');
1773 printf("%c ", (j & 0x08) ? '1' : '-');
1774 printf("%c", (j & 0x10) ? '1' : '-');
1775 printf("%c", (j & 0x20) ? '1' : '-');
1776 printf("%c", (j & 0x40) ? '1' : '-');
1777 printf("%c", (j & 0x80) ? '1' : '-');
1778
1779 reg_read(REG_TSRA2_ADDR, &mac2);
1780
developerbe40a9e2024-03-07 21:44:26 +08001781 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001782 printf(" %4d", (mac2 & 0xfff));
developerbe40a9e2024-03-07 21:44:26 +08001783 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001784 reg_read(REG_TSRA1_ADDR, &mac);
1785 printf(" %08x", mac);
1786 printf("%04x", ((mac2 >> 16) & 0xffff));
1787 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1788 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1789}
1790
1791void table_search_mac_fid(int argc, char *argv[])
1792{
developerbe40a9e2024-03-07 21:44:26 +08001793 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001794 char tmpstr[9];
1795
1796 if (!argv[3] || strlen(argv[3]) != 12) {
1797 printf("MAC address format error, should be of length 12\n");
1798 return;
1799 }
1800 strncpy(tmpstr, argv[3], 8);
1801 tmpstr[8] = '\0';
1802 value = strtoul(tmpstr, NULL, 16);
1803 reg_write(REG_ATA1_ADDR, value);
1804 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1805
1806 strncpy(tmpstr, argv[3] + 8, 4);
1807 tmpstr[4] = '\0';
1808
1809 value = strtoul(tmpstr, NULL, 16);
1810 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001811 value &= ~(1 << 15); //IVL=0
developerfd40db22021-04-29 10:08:25 +08001812
1813 j = strtoul(argv[5], NULL, 0);
1814 if (7 < j) {
1815 printf("wrong fid range, should be within 0~7\n");
1816 return;
1817 }
developerbe40a9e2024-03-07 21:44:26 +08001818 value |= (j << 12); //vid
developerfd40db22021-04-29 10:08:25 +08001819
1820 reg_write(REG_ATA2_ADDR, value);
1821 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1822
developerbe40a9e2024-03-07 21:44:26 +08001823 value = 0x8000; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001824 reg_write(REG_ATC_ADDR, value);
1825
1826 usleep(1000);
1827
1828 for (i = 0; i < 20; i++) {
1829 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001830 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001831 break;
1832 }
1833 usleep(1000);
1834 }
1835 if (i == 20) {
1836 printf("search timeout.\n");
1837 return;
1838 }
1839
1840 if (value & 0x1000) {
1841 printf("search no entry.\n");
1842 return;
1843 }
1844
1845 printf("search done.\n");
developerbe40a9e2024-03-07 21:44:26 +08001846 printf
1847 ("hash port(0:6) fid vid age mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001848
developerbe40a9e2024-03-07 21:44:26 +08001849 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
developerfd40db22021-04-29 10:08:25 +08001850 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001851 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001852 printf("%c", (j & 0x01) ? '1' : '-');
1853 printf("%c", (j & 0x02) ? '1' : '-');
1854 printf("%c", (j & 0x04) ? '1' : '-');
1855 printf("%c ", (j & 0x08) ? '1' : '-');
1856 printf("%c", (j & 0x10) ? '1' : '-');
1857 printf("%c", (j & 0x20) ? '1' : '-');
1858 printf("%c", (j & 0x40) ? '1' : '-');
1859 printf("%c", (j & 0x80) ? '1' : '-');
1860
1861 reg_read(REG_TSRA2_ADDR, &mac2);
1862
developerbe40a9e2024-03-07 21:44:26 +08001863 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001864 printf(" %4d", (mac2 & 0xfff));
developerbe40a9e2024-03-07 21:44:26 +08001865 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001866 reg_read(REG_TSRA1_ADDR, &mac);
1867 printf(" %08x", mac);
1868 printf("%04x", ((mac2 >> 16) & 0xffff));
1869 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1870 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1871}
1872
1873void table_del_fid(int argc, char *argv[])
1874{
developerbe40a9e2024-03-07 21:44:26 +08001875 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001876 char tmpstr[9];
1877
1878 if (!argv[3] || strlen(argv[3]) != 12) {
1879 printf("MAC address format error, should be of length 12\n");
1880 return;
1881 }
1882 strncpy(tmpstr, argv[3], 8);
1883 tmpstr[8] = '\0';
1884 value = strtoul(tmpstr, NULL, 16);
1885 reg_write(REG_ATA1_ADDR, value);
1886 strncpy(tmpstr, argv[3] + 8, 4);
1887 tmpstr[4] = '\0';
1888 value = strtoul(tmpstr, NULL, 16);
1889 value = (value << 16);
1890
1891 if (argc > 5) {
1892 j = strtoul(argv[5], NULL, 0);
1893 if (j > 7) {
1894 printf("wrong fid range, should be within 0~7\n");
1895 return;
1896 }
developerbe40a9e2024-03-07 21:44:26 +08001897 value |= (j << 12); /* fid */
developerfd40db22021-04-29 10:08:25 +08001898 }
1899
1900 reg_write(REG_ATA2_ADDR, value);
1901
developerbe40a9e2024-03-07 21:44:26 +08001902 value = 0; /* STATUS=0, delete mac */
developerfd40db22021-04-29 10:08:25 +08001903 reg_write(REG_ATWD_ADDR, value);
1904
developerbe40a9e2024-03-07 21:44:26 +08001905 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001906 reg_write(REG_ATC_ADDR, value);
1907
1908 for (i = 0; i < 20; i++) {
1909 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001910 if ((value & 0x8000) == 0) { /* mac address busy */
developerfd40db22021-04-29 10:08:25 +08001911 if (argv[1] != NULL)
1912 printf("done.\n");
1913 return;
1914 }
1915 usleep(1000);
1916 }
1917 if (i == 20)
1918 printf("timeout.\n");
1919}
1920
1921void table_del_vid(int argc, char *argv[])
1922{
developerbe40a9e2024-03-07 21:44:26 +08001923 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001924 char tmpstr[9];
1925
1926 if (!argv[3] || strlen(argv[3]) != 12) {
1927 printf("MAC address format error, should be of length 12\n");
1928 return;
1929 }
1930 strncpy(tmpstr, argv[3], 8);
1931 tmpstr[8] = '\0';
1932 value = strtoul(tmpstr, NULL, 16);
1933 reg_write(REG_ATA1_ADDR, value);
1934
1935 strncpy(tmpstr, argv[3] + 8, 4);
1936 tmpstr[4] = '\0';
1937 value = strtoul(tmpstr, NULL, 16);
1938 value = (value << 16);
1939
1940 j = strtoul(argv[5], NULL, 0);
1941 if (j > 4095) {
1942 printf("wrong fid range, should be within 0~4095\n");
1943 return;
1944 }
developerbe40a9e2024-03-07 21:44:26 +08001945 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001946 value |= 1 << 15;
1947 reg_write(REG_ATA2_ADDR, value);
1948
developerbe40a9e2024-03-07 21:44:26 +08001949 value = 0; //STATUS=0, delete mac
developerfd40db22021-04-29 10:08:25 +08001950 reg_write(REG_ATWD_ADDR, value);
1951
developerbe40a9e2024-03-07 21:44:26 +08001952 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001953 reg_write(REG_ATC_ADDR, value);
1954
1955 for (i = 0; i < 20; i++) {
1956 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001957 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001958 if (argv[1] != NULL)
1959 printf("done.\n");
1960 return;
1961 }
1962 usleep(1000);
1963 }
1964 if (i == 20)
1965 printf("timeout.\n");
1966}
1967
developerbe40a9e2024-03-07 21:44:26 +08001968void table_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001969{
developerbe40a9e2024-03-07 21:44:26 +08001970 unsigned int value = 0;
1971
developerfd40db22021-04-29 10:08:25 +08001972 reg_write(REG_ATC_ADDR, 0x8002);
1973 usleep(5000);
1974 reg_read(REG_ATC_ADDR, &value);
1975
1976 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1977}
1978
1979void set_mirror_to(int argc, char *argv[])
1980{
developerbe40a9e2024-03-07 21:44:26 +08001981 unsigned int value = 0;
1982 int idx = 0;
developerfd40db22021-04-29 10:08:25 +08001983
1984 idx = strtoul(argv[3], NULL, 0);
1985 if (idx < 0 || MAX_PORT < idx) {
1986 printf("wrong port member, should be within 0~%d\n", MAX_PORT);
1987 return;
1988 }
1989 if (chip_name == 0x7530) {
1990
1991 reg_read(REG_MFC_ADDR, &value);
1992 value |= 0x1 << 3;
1993 value &= 0xfffffff8;
1994 value |= idx << 0;
1995
1996 reg_write(REG_MFC_ADDR, value);
1997 } else {
1998
1999 reg_read(REG_CFC_ADDR, &value);
2000 value &= (~REG_CFC_MIRROR_EN_MASK);
2001 value |= (1 << REG_CFC_MIRROR_EN_OFFT);
2002 value &= (~REG_CFC_MIRROR_PORT_MASK);
2003 value |= (idx << REG_CFC_MIRROR_PORT_OFFT);
2004 reg_write(REG_CFC_ADDR, value);
2005 }
2006}
2007
2008void set_mirror_from(int argc, char *argv[])
2009{
developerbe40a9e2024-03-07 21:44:26 +08002010 unsigned int offset = 0, value = 0;
developer546b2792024-06-15 20:31:38 +08002011 unsigned int idx = 0, mirror = 0;
2012 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002013
developer546b2792024-06-15 20:31:38 +08002014 errno = 0;
2015 idx = strtoul(argv[3], &endptr, 0);
2016 if (errno != 0 || *endptr != '\0' || idx > MAX_PORT) {
2017 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
developerfd40db22021-04-29 10:08:25 +08002018 return;
2019 }
2020
developer546b2792024-06-15 20:31:38 +08002021 errno = 0;
2022 mirror = strtoul(argv[4], &endptr, 0);
2023
2024 if (errno != 0 || *endptr != '\0' || mirror > 3) {
developerfd40db22021-04-29 10:08:25 +08002025 printf("wrong mirror setting, should be within 0~3\n");
2026 return;
2027 }
2028
2029 offset = (0x2004 | (idx << 8));
2030 reg_read(offset, &value);
2031
2032 value &= 0xfffffcff;
2033 value |= mirror << 8;
2034
2035 reg_write(offset, value);
2036}
2037
2038void vlan_dump(int argc, char *argv[])
2039{
developerbe40a9e2024-03-07 21:44:26 +08002040 unsigned int i = 0, j = 0, value = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08002041 int eg_tag = 0;
2042
2043 if (argc == 4) {
2044 if (!strncmp(argv[3], "egtag", 6))
2045 eg_tag = 1;
2046 }
2047
2048 if (eg_tag)
developerbe40a9e2024-03-07 21:44:26 +08002049 printf
2050 (" vid fid portmap s-tag\teg_tag(0:untagged 2:tagged)\n");
developerfd40db22021-04-29 10:08:25 +08002051 else
2052 printf(" vid fid portmap s-tag\n");
2053
2054 for (i = 1; i < 4095; i++) {
developerbe40a9e2024-03-07 21:44:26 +08002055 value = (0x80000000 + i); //r_vid_cmd
developerfd40db22021-04-29 10:08:25 +08002056 reg_write(REG_VTCR_ADDR, value);
2057
2058 for (j = 0; j < 20; j++) {
2059 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002060 if ((value & 0x80000000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08002061 break;
2062 }
2063 usleep(1000);
2064 }
2065 if (j == 20)
2066 printf("timeout.\n");
2067
2068 reg_read(REG_VAWD1_ADDR, &value);
2069 reg_read(REG_VAWD2_ADDR, &value2);
2070 //printf("REG_VAWD1_ADDR value%d is 0x%x\n\r", i, value);
2071 //printf("REG_VAWD2_ADDR value%d is 0x%x\n\r", i, value2);
2072
2073 if ((value & 0x01) != 0) {
2074 printf(" %4d ", i);
2075 printf(" %2d ", ((value & 0xe) >> 1));
2076 printf(" %c", (value & 0x00010000) ? '1' : '-');
2077 printf("%c", (value & 0x00020000) ? '1' : '-');
2078 printf("%c", (value & 0x00040000) ? '1' : '-');
2079 printf("%c", (value & 0x00080000) ? '1' : '-');
2080 printf("%c", (value & 0x00100000) ? '1' : '-');
2081 printf("%c", (value & 0x00200000) ? '1' : '-');
2082 printf("%c", (value & 0x00400000) ? '1' : '-');
2083 printf("%c", (value & 0x00800000) ? '1' : '-');
2084 printf(" %4d", ((value & 0xfff0) >> 4));
2085 if (eg_tag) {
2086 printf("\t");
2087 if ((value & (0x3 << 28)) == (0x3 << 28)) {
2088 /* VTAG_EN=1 and EG_CON=1 */
2089 printf("CONSISTENT");
2090 } else if (value & (0x1 << 28)) {
2091 /* VTAG_EN=1 */
2092 printf("%d", (value2 & 0x0003) >> 0);
2093 printf("%d", (value2 & 0x000c) >> 2);
2094 printf("%d", (value2 & 0x0030) >> 4);
2095 printf("%d", (value2 & 0x00c0) >> 6);
2096 printf("%d", (value2 & 0x0300) >> 8);
2097 printf("%d", (value2 & 0x0c00) >> 10);
2098 printf("%d", (value2 & 0x3000) >> 12);
2099 printf("%d", (value2 & 0xc000) >> 14);
2100 } else {
2101 /* VTAG_EN=0 */
2102 printf("DISABLED");
2103 }
2104 }
2105 printf("\n");
2106 } else {
developerbe40a9e2024-03-07 21:44:26 +08002107 /*print 16 vid for reference information */
developerfd40db22021-04-29 10:08:25 +08002108 if (i <= 16) {
2109 printf(" %4d ", i);
2110 printf(" %2d ", ((value & 0xe) >> 1));
2111 printf(" invalid\n");
2112 }
2113 }
2114 }
2115}
2116
developerfd40db22021-04-29 10:08:25 +08002117static long timespec_diff_us(struct timespec start, struct timespec end)
2118{
2119 struct timespec temp;
2120 unsigned long duration = 0;
2121
2122 if ((end.tv_nsec - start.tv_nsec) < 0) {
2123 temp.tv_sec = end.tv_sec - start.tv_sec - 1;
2124 temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
2125 } else {
2126 temp.tv_sec = end.tv_sec - start.tv_sec;
2127 temp.tv_nsec = end.tv_nsec - start.tv_nsec;
2128 }
developerbe40a9e2024-03-07 21:44:26 +08002129 /* calculate second part */
developerfd40db22021-04-29 10:08:25 +08002130 duration += temp.tv_sec * 1000000;
developerbe40a9e2024-03-07 21:44:26 +08002131 /* calculate ns part */
developerfd40db22021-04-29 10:08:25 +08002132 duration += temp.tv_nsec >> 10;
2133
2134 return duration;
2135}
2136
developerfd40db22021-04-29 10:08:25 +08002137void vlan_clear(int argc, char *argv[])
2138{
developerbe40a9e2024-03-07 21:44:26 +08002139 unsigned int value = 0;
2140 int vid = 0;
developerfd40db22021-04-29 10:08:25 +08002141 unsigned long duration_us = 0;
2142 struct timespec start, end;
2143
2144 for (vid = 0; vid < 4096; vid++) {
2145 clock_gettime(CLOCK_REALTIME, &start);
developerbe40a9e2024-03-07 21:44:26 +08002146 value = 0; //invalid
developerfd40db22021-04-29 10:08:25 +08002147 reg_write(REG_VAWD1_ADDR, value);
2148
developerbe40a9e2024-03-07 21:44:26 +08002149 value = (0x80001000 + vid); //w_vid_cmd
developerfd40db22021-04-29 10:08:25 +08002150 reg_write(REG_VTCR_ADDR, value);
2151 while (duration_us <= 1000) {
2152 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002153 if ((value & 0x80000000) == 0) { //table busy
developerfd40db22021-04-29 10:08:25 +08002154 break;
2155 }
2156 clock_gettime(CLOCK_REALTIME, &end);
2157 duration_us = timespec_diff_us(start, end);
2158 }
2159 if (duration_us > 1000)
2160 printf("config vlan timeout: %ld.\n", duration_us);
2161 }
2162}
2163
2164void vlan_set(int argc, char *argv[])
2165{
2166 unsigned int vlan_mem = 0;
2167 unsigned int value = 0;
2168 unsigned int value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08002169 int i = 0, vid = 0, fid = 0;
developerfd40db22021-04-29 10:08:25 +08002170 int stag = 0;
2171 unsigned long eg_con = 0;
2172 unsigned int eg_tag = 0;
2173
2174 if (argc < 5) {
2175 printf("insufficient arguments!\n");
2176 return;
2177 }
2178
2179 fid = strtoul(argv[3], NULL, 0);
2180 if (fid < 0 || fid > 7) {
2181 printf("wrong filtering db id range, should be within 0~7\n");
2182 return;
2183 }
2184 value |= (fid << 1);
2185
2186 vid = strtoul(argv[4], NULL, 0);
2187 if (vid < 0 || 0xfff < vid) {
2188 printf("wrong vlan id range, should be within 0~4095\n");
2189 return;
2190 }
2191
2192 if (strlen(argv[5]) != 8) {
2193 printf("portmap format error, should be of length 7\n");
2194 return;
2195 }
2196
2197 vlan_mem = 0;
2198 for (i = 0; i < 8; i++) {
2199 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08002200 printf
2201 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08002202 return;
2203 }
2204 vlan_mem += (argv[5][i] - '0') * (1 << i);
2205 }
2206
2207 /* VLAN stag */
2208 if (argc > 6) {
2209 stag = strtoul(argv[6], NULL, 16);
2210 if (stag < 0 || 0xfff < stag) {
developerbe40a9e2024-03-07 21:44:26 +08002211 printf
2212 ("wrong stag id range, should be within 0~4095\n");
developerfd40db22021-04-29 10:08:25 +08002213 return;
2214 }
2215 //printf("STAG is 0x%x\n", stag);
2216 }
2217
2218 /* set vlan member */
2219 value |= (vlan_mem << 16);
developerbe40a9e2024-03-07 21:44:26 +08002220 value |= (1 << 30); //IVL=1
2221 value |= ((stag & 0xfff) << 4); //stag
2222 value |= 1; //valid
developerfd40db22021-04-29 10:08:25 +08002223
2224 if (argc > 7) {
2225 eg_con = strtoul(argv[7], NULL, 2);
2226 eg_con = !!eg_con;
developerbe40a9e2024-03-07 21:44:26 +08002227 value |= (eg_con << 29); //eg_con
2228 value |= (1 << 28); //eg tag control enable
developerfd40db22021-04-29 10:08:25 +08002229 }
2230
2231 if (argc > 8 && !eg_con) {
2232 if (strlen(argv[8]) != 8) {
developerbe40a9e2024-03-07 21:44:26 +08002233 printf
2234 ("egtag portmap format error, should be of length 7\n");
developerfd40db22021-04-29 10:08:25 +08002235 return;
2236 }
2237
2238 for (i = 0; i < 8; i++) {
2239 if (argv[8][i] < '0' || argv[8][i] > '3') {
developerbe40a9e2024-03-07 21:44:26 +08002240 printf
2241 ("egtag portmap format error, should be of combination of 0 or 3\n");
developerfd40db22021-04-29 10:08:25 +08002242 return;
2243 }
2244 //eg_tag += (argv[8][i] - '0') * (1 << i * 2);
2245 eg_tag |= (argv[8][i] - '0') << (i * 2);
2246 }
2247
developerbe40a9e2024-03-07 21:44:26 +08002248 value |= (1 << 28); //eg tag control enable
developerfd40db22021-04-29 10:08:25 +08002249 value2 &= ~(0xffff);
2250 value2 |= eg_tag;
2251 }
2252 reg_write(REG_VAWD1_ADDR, value);
2253 reg_write(REG_VAWD2_ADDR, value2);
2254 //printf("VAWD1=0x%08x VAWD2=0x%08x ", value, value2);
2255
developerbe40a9e2024-03-07 21:44:26 +08002256 value = (0x80001000 + vid); //w_vid_cmd
developerfd40db22021-04-29 10:08:25 +08002257 reg_write(REG_VTCR_ADDR, value);
2258 //printf("VTCR=0x%08x\n", value);
2259
2260 for (i = 0; i < 300; i++) {
2261 usleep(1000);
2262 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002263 if ((value & 0x80000000) == 0) //table busy
developerfd40db22021-04-29 10:08:25 +08002264 break;
2265 }
2266
2267 if (i == 300)
2268 printf("config vlan timeout.\n");
2269}
2270
2271void igmp_on(int argc, char *argv[])
2272{
2273 unsigned int leaky_en = 0;
2274 unsigned int wan_num = 4;
developerbe40a9e2024-03-07 21:44:26 +08002275 unsigned int port = 0, offset = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002276 char cmd[80];
2277 int ret;
2278
2279 if (argc > 3)
2280 leaky_en = strtoul(argv[3], NULL, 10);
2281 if (argc > 4)
2282 wan_num = strtoul(argv[4], NULL, 10);
2283
2284 if (leaky_en == 1) {
2285 if (wan_num == 4) {
2286 /* reg_write(0x2410, 0x810000c8); */
2287 reg_read(0x2410, &value);
2288 reg_write(0x2410, value | (1 << 3));
2289 /* reg_write(0x2010, 0x810000c0); */
2290 reg_read(0x2010, &value);
2291 reg_write(0x2010, value & (~(1 << 3)));
2292 reg_write(REG_ISC_ADDR, 0x10027d10);
2293 } else {
2294 /* reg_write(0x2010, 0x810000c8); */
2295 reg_read(0x2010, &value);
2296 reg_write(0x2010, value | (1 << 3));
2297 /* reg_write(0x2410, 0x810000c0); */
2298 reg_read(0x2410, &value);
2299 reg_write(0x2410, value & (~(1 << 3)));
2300 reg_write(REG_ISC_ADDR, 0x01027d01);
2301 }
developerbe40a9e2024-03-07 21:44:26 +08002302 } else
developerfd40db22021-04-29 10:08:25 +08002303 reg_write(REG_ISC_ADDR, 0x10027d60);
2304
2305 reg_write(0x1c, 0x08100810);
2306 reg_write(0x2008, 0xb3ff);
2307 reg_write(0x2108, 0xb3ff);
2308 reg_write(0x2208, 0xb3ff);
2309 reg_write(0x2308, 0xb3ff);
2310 reg_write(0x2408, 0xb3ff);
2311 reg_write(0x2608, 0xb3ff);
2312 /* Enable Port ACL
developerbe40a9e2024-03-07 21:44:26 +08002313 * reg_write(0x2P04, 0xff0403);
2314 */
developerfd40db22021-04-29 10:08:25 +08002315 for (port = 0; port <= 6; port++) {
2316 offset = 0x2004 + port * 0x100;
2317 reg_read(offset, &value);
2318 reg_write(offset, value | (1 << 10));
2319 }
2320
developerbe40a9e2024-03-07 21:44:26 +08002321 /*IGMP query only p4 -> p5 */
developerfd40db22021-04-29 10:08:25 +08002322 reg_write(0x94, 0x00ff0002);
2323 if (wan_num == 4)
2324 reg_write(0x98, 0x000a1008);
2325 else
2326 reg_write(0x98, 0x000a0108);
2327 reg_write(0x90, 0x80005000);
2328 reg_write(0x94, 0xff001100);
2329 if (wan_num == 4)
2330 reg_write(0x98, 0x000B1000);
2331 else
2332 reg_write(0x98, 0x000B0100);
2333 reg_write(0x90, 0x80005001);
2334 reg_write(0x94, 0x3);
2335 reg_write(0x98, 0x0);
2336 reg_write(0x90, 0x80009000);
2337 reg_write(0x94, 0x1a002080);
2338 reg_write(0x98, 0x0);
2339 reg_write(0x90, 0x8000b000);
2340
developerbe40a9e2024-03-07 21:44:26 +08002341 /*IGMP p5 -> p4 */
developerfd40db22021-04-29 10:08:25 +08002342 reg_write(0x94, 0x00ff0002);
2343 reg_write(0x98, 0x000a2008);
2344 reg_write(0x90, 0x80005002);
2345 reg_write(0x94, 0x4);
2346 reg_write(0x98, 0x0);
2347 reg_write(0x90, 0x80009001);
2348 if (wan_num == 4)
2349 reg_write(0x94, 0x1a001080);
2350 else
2351 reg_write(0x94, 0x1a000180);
2352 reg_write(0x98, 0x0);
2353 reg_write(0x90, 0x8000b001);
2354
developerbe40a9e2024-03-07 21:44:26 +08002355 /*IGMP p0~p3 -> p6 */
developerfd40db22021-04-29 10:08:25 +08002356 reg_write(0x94, 0x00ff0002);
2357 if (wan_num == 4)
2358 reg_write(0x98, 0x000a0f08);
2359 else
2360 reg_write(0x98, 0x000a1e08);
2361 reg_write(0x90, 0x80005003);
2362 reg_write(0x94, 0x8);
2363 reg_write(0x98, 0x0);
2364 reg_write(0x90, 0x80009002);
2365 reg_write(0x94, 0x1a004080);
2366 reg_write(0x98, 0x0);
2367 reg_write(0x90, 0x8000b002);
2368
developerbe40a9e2024-03-07 21:44:26 +08002369 /*IGMP query only p6 -> p0~p3 */
developerfd40db22021-04-29 10:08:25 +08002370 reg_write(0x94, 0x00ff0002);
2371 reg_write(0x98, 0x000a4008);
2372 reg_write(0x90, 0x80005004);
2373 reg_write(0x94, 0xff001100);
2374 reg_write(0x98, 0x000B4000);
2375 reg_write(0x90, 0x80005005);
2376 reg_write(0x94, 0x30);
2377 reg_write(0x98, 0x0);
2378 reg_write(0x90, 0x80009003);
2379 if (wan_num == 4)
2380 reg_write(0x94, 0x1a000f80);
2381 else
2382 reg_write(0x94, 0x1a001e80);
2383 reg_write(0x98, 0x0);
2384 reg_write(0x90, 0x8000b003);
2385
developerbe40a9e2024-03-07 21:44:26 +08002386 /*Force eth2 to receive all igmp packets */
2387 snprintf(cmd, sizeof(cmd),
2388 "echo 2 > /sys/devices/virtual/net/%s/brif/%s/multicast_router",
2389 BR_DEVNAME, ETH_DEVNAME);
developerfd40db22021-04-29 10:08:25 +08002390 ret = system(cmd);
2391 if (ret)
developerbe40a9e2024-03-07 21:44:26 +08002392 printf
2393 ("Failed to set /sys/devices/virtual/net/%s/brif/%s/multicast_router\n",
2394 BR_DEVNAME, ETH_DEVNAME);
developerfd40db22021-04-29 10:08:25 +08002395}
2396
2397void igmp_disable(int argc, char *argv[])
2398{
developerbe40a9e2024-03-07 21:44:26 +08002399 unsigned int reg_offset = 0, value = 0;
2400 int port_num = 0;
developerfd40db22021-04-29 10:08:25 +08002401
2402 if (argc < 4) {
2403 printf("insufficient arguments!\n");
2404 return;
2405 }
2406 port_num = strtoul(argv[3], NULL, 0);
2407 if (port_num < 0 || 6 < port_num) {
2408 printf("wrong port range, should be within 0~6\n");
2409 return;
2410 }
developerfd40db22021-04-29 10:08:25 +08002411 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2412 reg_offset = 0x2008;
2413 reg_offset |= (port_num << 8);
2414 value = 0x8000;
2415
2416 reg_write(reg_offset, value);
2417}
2418
2419void igmp_enable(int argc, char *argv[])
2420{
developerbe40a9e2024-03-07 21:44:26 +08002421 unsigned int reg_offset = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002422 int port_num;
2423
2424 if (argc < 4) {
2425 printf("insufficient arguments!\n");
2426 return;
2427 }
2428 port_num = strtoul(argv[3], NULL, 0);
2429 if (port_num < 0 || 6 < port_num) {
2430 printf("wrong port range, should be within 0~6\n");
2431 return;
2432 }
developerfd40db22021-04-29 10:08:25 +08002433 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2434 reg_offset = 0x2008;
2435 reg_offset |= (port_num << 8);
2436 value = 0x9755;
2437 reg_write(reg_offset, value);
2438}
2439
developerbe40a9e2024-03-07 21:44:26 +08002440void igmp_off(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002441{
developerbe40a9e2024-03-07 21:44:26 +08002442 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08002443 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2444 reg_read(REG_ISC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002445 value &= ~(1 << 18); //disable
developerfd40db22021-04-29 10:08:25 +08002446 reg_write(REG_ISC_ADDR, value);
2447
developerbe40a9e2024-03-07 21:44:26 +08002448 /*restore wan port multicast leaky vlan function: default disabled */
developerfd40db22021-04-29 10:08:25 +08002449 reg_read(0x2010, &value);
2450 reg_write(0x2010, value & (~(1 << 3)));
2451 reg_read(0x2410, &value);
2452 reg_write(0x2410, value & (~(1 << 3)));
2453
2454 printf("config igmpsnoop off.\n");
2455}
2456
developerbe40a9e2024-03-07 21:44:26 +08002457void switch_reset(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002458{
developer8c3871b2022-07-01 14:07:53 +08002459 if (chip_name == 0x7988)
developerbe40a9e2024-03-07 21:44:26 +08002460 return;
developer8c3871b2022-07-01 14:07:53 +08002461
developerfd40db22021-04-29 10:08:25 +08002462 unsigned int value = 0;
2463 /*Software Register Reset and Software System Reset */
2464 reg_write(0x7000, 0x3);
2465 reg_read(0x7000, &value);
2466 printf("SYS_CTRL(0x7000) register value =0x%x \n", value);
2467 if (chip_name == 0x7531) {
2468 reg_write(0x7c0c, 0x11111111);
2469 reg_read(0x7c0c, &value);
2470 printf("GPIO Mode (0x7c0c) select value =0x%x \n", value);
2471 }
2472 printf("Switch Software Reset !!! \n");
2473}
2474
developerbe40a9e2024-03-07 21:44:26 +08002475void phy_set_fc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002476{
developerbe40a9e2024-03-07 21:44:26 +08002477 unsigned int port = 0, pause_capable = 0;
2478 unsigned int phy_value = 0;
developerfd40db22021-04-29 10:08:25 +08002479
2480 port = atoi(argv[3]);
2481 pause_capable = atoi(argv[4]);
2482
developerbe40a9e2024-03-07 21:44:26 +08002483 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002484 if (port > MAX_PORT - 2 || pause_capable > 1) {
developerbe40a9e2024-03-07 21:44:26 +08002485 printf
2486 ("Illegal parameter (port:0~4, full_duplex_pause_capable:0|1)\n");
2487 return;
developerfd40db22021-04-29 10:08:25 +08002488 }
2489 printf("port=%d, full_duplex_pause_capable:%d\n", port, pause_capable);
developerbe40a9e2024-03-07 21:44:26 +08002490
developerfd40db22021-04-29 10:08:25 +08002491 mii_mgr_read(port, 4, &phy_value);
2492 printf("read phy_value:0x%x\r\n", phy_value);
2493 phy_value &= (~(0x1 << 10));
2494 phy_value &= (~(0x1 << 11));
2495 if (pause_capable == 1) {
2496 phy_value |= (0x1 << 10);
2497 phy_value |= (0x1 << 11);
2498 }
2499 mii_mgr_write(port, 4, phy_value);
2500 printf("write phy_value:0x%x\r\n", phy_value);
developerbe40a9e2024-03-07 21:44:26 +08002501 return;
2502} /*end phy_set_fc */
developerfd40db22021-04-29 10:08:25 +08002503
developerbe40a9e2024-03-07 21:44:26 +08002504void phy_set_an(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002505{
developerbe40a9e2024-03-07 21:44:26 +08002506 unsigned int port = 0, auto_negotiation_en = 0;
2507 unsigned int phy_value = 0;
developerfd40db22021-04-29 10:08:25 +08002508
2509 port = atoi(argv[3]);
2510 auto_negotiation_en = atoi(argv[4]);
2511
developerbe40a9e2024-03-07 21:44:26 +08002512 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002513 if (port > MAX_PORT - 2 || auto_negotiation_en > 1) {
developerbe40a9e2024-03-07 21:44:26 +08002514 printf
2515 ("Illegal parameter (port:0~4, auto_negotiation_en:0|1)\n");
2516 return;
developerfd40db22021-04-29 10:08:25 +08002517 }
2518 printf("port=%d, auto_negotiation_en:%d\n", port, auto_negotiation_en);
developerbe40a9e2024-03-07 21:44:26 +08002519
developerfd40db22021-04-29 10:08:25 +08002520 mii_mgr_read(port, 0, &phy_value);
2521 printf("read phy_value:0x%x\r\n", phy_value);
2522 phy_value &= (~(1 << 12));
2523 phy_value |= (auto_negotiation_en << 12);
2524 mii_mgr_write(port, 0, phy_value);
2525 printf("write phy_value:0x%x\r\n", phy_value);
developerbe40a9e2024-03-07 21:44:26 +08002526} /*end phy_set_an */
developerfd40db22021-04-29 10:08:25 +08002527
developerbe40a9e2024-03-07 21:44:26 +08002528void set_mac_pfc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002529{
developerbe40a9e2024-03-07 21:44:26 +08002530 unsigned int value = 0;
developer546b2792024-06-15 20:31:38 +08002531 unsigned int port, enable = 0;
2532 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002533
developer546b2792024-06-15 20:31:38 +08002534 errno = 0;
2535 port = strtoul(argv[3], &endptr, 10);
2536 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2537 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2538 return;
2539 }
2540
2541 errno = 0;
2542 enable = strtoul(argv[4], &endptr, 10);
2543 if (errno != 0 || *endptr != '\0' || enable > 1) {
2544 printf("Error: Illegal paramete, enable|diable:0|1\n");
developerbe40a9e2024-03-07 21:44:26 +08002545 return;
developerfd40db22021-04-29 10:08:25 +08002546 }
developer546b2792024-06-15 20:31:38 +08002547 printf("enable: %d\n", enable);
2548
developer8c3871b2022-07-01 14:07:53 +08002549 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002550 reg_read(REG_PFC_CTRL_ADDR, &value);
2551 value &= ~(1 << port);
2552 value |= (enable << port);
2553 printf("write reg: %x, value: %x\n", REG_PFC_CTRL_ADDR, value);
2554 reg_write(REG_PFC_CTRL_ADDR, value);
developerbe40a9e2024-03-07 21:44:26 +08002555 } else
developerfd40db22021-04-29 10:08:25 +08002556 printf("\nCommand not support by this chip.\n");
developerfd40db22021-04-29 10:08:25 +08002557}
2558
developerbe40a9e2024-03-07 21:44:26 +08002559void global_set_mac_fc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002560{
2561 unsigned char enable = 0;
developerbe40a9e2024-03-07 21:44:26 +08002562 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08002563
2564 if (chip_name == 0x7530) {
2565 enable = atoi(argv[3]);
2566 printf("enable: %d\n", enable);
2567
developerbe40a9e2024-03-07 21:44:26 +08002568 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002569 if (enable > 1) {
2570 printf(HELP_MACCTL_FC);
developerbe40a9e2024-03-07 21:44:26 +08002571 return;
developerfd40db22021-04-29 10:08:25 +08002572 }
2573 reg_write(0x7000, 0x3);
2574 reg = REG_GFCCR0_ADDR;
2575 reg_read(REG_GFCCR0_ADDR, &value);
2576 value &= (~REG_FC_EN_MASK);
2577 value |= (enable << REG_FC_EN_OFFT);
2578 printf("write reg: %x, value: %x\n", reg, value);
2579 reg_write(REG_GFCCR0_ADDR, value);
2580 } else
2581 printf("\r\nCommand not support by this chip.\n");
developerbe40a9e2024-03-07 21:44:26 +08002582} /*end mac_set_fc */
developerfd40db22021-04-29 10:08:25 +08002583
developerbe40a9e2024-03-07 21:44:26 +08002584void qos_sch_select(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002585{
developerbe40a9e2024-03-07 21:44:26 +08002586 unsigned char port = 0, queue = 0;
developerfd40db22021-04-29 10:08:25 +08002587 unsigned char type = 0;
developerbe40a9e2024-03-07 21:44:26 +08002588 unsigned int value = 0, reg = 0;
developer546b2792024-06-15 20:31:38 +08002589 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002590
2591 if (argc < 7)
developerbe40a9e2024-03-07 21:44:26 +08002592 return;
developerfd40db22021-04-29 10:08:25 +08002593
developer546b2792024-06-15 20:31:38 +08002594 errno = 0;
2595 port = strtoul(argv[3], &endptr, 10);
2596 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2597 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2598 return;
2599 }
developerfd40db22021-04-29 10:08:25 +08002600
developer546b2792024-06-15 20:31:38 +08002601 errno = 0;
2602 queue = strtoul(argv[4], &endptr, 10);
2603 if (errno != 0 || *endptr != '\0' || queue > 7) {
2604 printf("Error: wrong port queue member\n");
developerbe40a9e2024-03-07 21:44:26 +08002605 return;
developerfd40db22021-04-29 10:08:25 +08002606 }
2607
developer546b2792024-06-15 20:31:38 +08002608 errno = 0;
2609 type = strtoul(argv[6], &endptr, 10);
2610 if (errno != 0 || *endptr != '\0' || type > 2) {
developerfd40db22021-04-29 10:08:25 +08002611 printf(HELP_QOS_TYPE);
developerbe40a9e2024-03-07 21:44:26 +08002612 return;
developerfd40db22021-04-29 10:08:25 +08002613 }
2614
developerbe40a9e2024-03-07 21:44:26 +08002615 printf("\r\nswitch qos type: %d.\n", type);
developerfd40db22021-04-29 10:08:25 +08002616
2617 if (!strncmp(argv[5], "min", 4)) {
2618
2619 if (type == 0) {
developerbe40a9e2024-03-07 21:44:26 +08002620 /*min sharper-->round roubin, disable min sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002621 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2622 reg_read(reg, &value);
2623 value = 0x0;
2624 reg_write(reg, value);
2625 } else if (type == 1) {
developerbe40a9e2024-03-07 21:44:26 +08002626 /*min sharper-->sp, disable min sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002627 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2628 reg_read(reg, &value);
2629 value = 0x0;
2630 value |= (1 << 31);
2631 reg_write(reg, value);
2632 } else {
2633 printf("min sharper only support: rr or sp\n");
developerbe40a9e2024-03-07 21:44:26 +08002634 return;
developerfd40db22021-04-29 10:08:25 +08002635 }
2636 } else if (!strncmp(argv[5], "max", 4)) {
2637 if (type == 1) {
developerbe40a9e2024-03-07 21:44:26 +08002638 /*max sharper-->sp, disable max sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002639 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2640 reg_read(reg, &value);
2641 value = 0x0;
2642 value |= (1 << 31);
2643 reg_write(reg, value);
2644 } else if (type == 2) {
developerbe40a9e2024-03-07 21:44:26 +08002645 /*max sharper-->wfq, disable max sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002646 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2647 reg_read(reg, &value);
2648 value = 0x0;
2649 reg_write(reg, value);
2650 } else {
2651 printf("max sharper only support: wfq or sp\n");
developerbe40a9e2024-03-07 21:44:26 +08002652 return;
developerfd40db22021-04-29 10:08:25 +08002653 }
2654 } else {
developerbe40a9e2024-03-07 21:44:26 +08002655 printf("\r\nIllegal sharper:%s\n", argv[5]);
2656 return;
developerfd40db22021-04-29 10:08:25 +08002657 }
developerbe40a9e2024-03-07 21:44:26 +08002658 printf("reg:0x%x--value:0x%x\n", reg, value);
developerfd40db22021-04-29 10:08:25 +08002659}
2660
2661void get_upw(unsigned int *value, unsigned char base)
2662{
2663 *value &= (~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
2664 (0x7 << 16) | (0x7 << 20)));
developerbe40a9e2024-03-07 21:44:26 +08002665 switch (base) {
2666 case 0: /* port-based 0x2x40[18:16] */
2667 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2668 (0x2 << 12) | (0x7 << 16) | (0x2 << 20));
2669 break;
2670 case 1: /* tagged-based 0x2x40[10:8] */
2671 *value |= ((0x2 << 0) | (0x2 << 4) | (0x7 << 8) |
2672 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2673 break;
2674 case 2: /* DSCP-based 0x2x40[14:12] */
2675 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2676 (0x7 << 12) | (0x2 << 16) | (0x2 << 20));
2677 break;
2678 case 3: /* acl-based 0x2x40[2:0] */
2679 *value |= ((0x7 << 0) | (0x2 << 4) | (0x2 << 8) |
2680 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2681 break;
2682 case 4: /* arl-based 0x2x40[22:20] */
2683 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2684 (0x2 << 12) | (0x2 << 16) | (0x7 << 20));
2685 break;
2686 case 5: /* stag-based 0x2x40[6:4] */
2687 *value |= ((0x2 << 0) | (0x7 << 4) | (0x2 << 8) |
2688 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2689 break;
2690 default:
2691 break;
developerfd40db22021-04-29 10:08:25 +08002692 }
2693}
2694
2695void qos_set_base(int argc, char *argv[])
2696{
2697 unsigned char base = 0;
developerbe40a9e2024-03-07 21:44:26 +08002698 unsigned char port = 0;
2699 unsigned int value = 0;
developer546b2792024-06-15 20:31:38 +08002700 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002701
2702 if (argc < 5)
2703 return;
2704
developer546b2792024-06-15 20:31:38 +08002705 errno = 0;
2706 port = strtoul(argv[3], &endptr, 10);
2707 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2708 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
developerfd40db22021-04-29 10:08:25 +08002709 return;
2710 }
2711
developer546b2792024-06-15 20:31:38 +08002712 errno = 0;
2713 base = strtoul(argv[4], &endptr, 10);
2714 if (errno != 0 || *endptr != '\0' || base > 5) {
2715 printf(HELP_QOS_BASE);
developerfd40db22021-04-29 10:08:25 +08002716 return;
2717 }
2718
2719 printf("\r\nswitch qos base : %d. (port-based:0, tag-based:1,\
developerbe40a9e2024-03-07 21:44:26 +08002720 dscp-based:2, acl-based:3, arl-based:4, stag-based:5)\n", base);
developerfd40db22021-04-29 10:08:25 +08002721 if (chip_name == 0x7530) {
2722
2723 reg_read(0x44, &value);
2724 get_upw(&value, base);
2725 reg_write(0x44, value);
2726 printf("reg: 0x44, value: 0x%x\n", value);
2727
developer8c3871b2022-07-01 14:07:53 +08002728 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002729
2730 reg_read(GSW_UPW(port), &value);
2731 get_upw(&value, base);
2732 reg_write(GSW_UPW(port), value);
developerbe40a9e2024-03-07 21:44:26 +08002733 printf("reg:0x%x, value: 0x%x\n", GSW_UPW(port), value);
developerfd40db22021-04-29 10:08:25 +08002734
2735 } else {
2736 printf("unknown switch device");
2737 return;
2738 }
2739}
2740
2741void qos_wfq_set_weight(int argc, char *argv[])
2742{
developerbe40a9e2024-03-07 21:44:26 +08002743 int port = 0, weight[8], i = 0;
2744 unsigned char queue = 0;
2745 unsigned int reg = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002746
2747 port = atoi(argv[3]);
2748
2749 for (i = 0; i < 8; i++) {
2750 weight[i] = atoi(argv[i + 4]);
2751 }
2752
2753 /* MT7530 total 7 port */
2754 if (port < 0 || port > 6) {
2755 printf(HELP_QOS_PORT_WEIGHT);
2756 return;
2757 }
2758
2759 for (i = 0; i < 8; i++) {
2760 if (weight[i] < 1 || weight[i] > 16) {
2761 printf(HELP_QOS_PORT_WEIGHT);
2762 return;
2763 }
2764 }
2765 printf("port: %x, q0: %x, q1: %x, q2: %x, q3: %x, \
developerbe40a9e2024-03-07 21:44:26 +08002766 q4: %x, q5: %x, q6: %x, q7: %x\n", port, weight[0], weight[1], weight[2], weight[3], weight[4], weight[5], weight[6], weight[7]);
developerfd40db22021-04-29 10:08:25 +08002767
2768 for (queue = 0; queue < 8; queue++) {
2769 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2770 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002771 value &= (~(0xf << 24)); //bit24~27
developerfd40db22021-04-29 10:08:25 +08002772 value |= (((weight[queue] - 1) & 0xf) << 24);
2773 printf("reg: %x, value: %x\n", reg, value);
2774 reg_write(reg, value);
2775 }
2776}
2777
2778void qos_set_portpri(int argc, char *argv[])
2779{
developerbe40a9e2024-03-07 21:44:26 +08002780 unsigned char port = 0, prio = 0;
2781 unsigned int value = 0;
developer546b2792024-06-15 20:31:38 +08002782 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002783
developer546b2792024-06-15 20:31:38 +08002784 errno = 0;
2785 port = strtoul(argv[3], &endptr, 10);
2786 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2787 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2788 return;
2789 }
developerfd40db22021-04-29 10:08:25 +08002790
developer546b2792024-06-15 20:31:38 +08002791 errno = 0;
2792 prio = strtoul(argv[4], &endptr, 10);
2793 if (errno != 0 || *endptr != '\0' || prio > 7) {
2794 printf("Error: wrong priority, should be within 0~7\n");
developerfd40db22021-04-29 10:08:25 +08002795 return;
2796 }
2797
2798 reg_read(GSW_PCR(port), &value);
2799 value &= (~(0x7 << 24));
2800 value |= (prio << 24);
2801 reg_write(GSW_PCR(port), value);
2802 printf("write reg: %x, value: %x\n", GSW_PCR(port), value);
2803}
2804
2805void qos_set_dscppri(int argc, char *argv[])
2806{
developerbe40a9e2024-03-07 21:44:26 +08002807 unsigned char prio = 0, dscp = 0, pim_n = 0, pim_offset = 0;
2808 unsigned int value = 0, reg = 0;
developer546b2792024-06-15 20:31:38 +08002809 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002810
developer546b2792024-06-15 20:31:38 +08002811 errno = 0;
2812 dscp = strtoul(argv[3], &endptr, 10);
2813 if (errno != 0 || *endptr != '\0' || dscp > 63) {
2814 printf(HELP_QOS_DSCP_PRIO);
2815 return;
2816 }
developerfd40db22021-04-29 10:08:25 +08002817
developer546b2792024-06-15 20:31:38 +08002818 errno = 0;
2819 prio = strtoul(argv[4], &endptr, 10);
2820 if (errno != 0 || *endptr != '\0' || prio > 7) {
developerfd40db22021-04-29 10:08:25 +08002821 printf(HELP_QOS_DSCP_PRIO);
2822 return;
2823 }
2824
2825 pim_n = dscp / 10;
2826 pim_offset = (dscp - pim_n * 10) * 3;
2827 reg = 0x0058 + pim_n * 4;
2828 reg_read(reg, &value);
2829 value &= (~(0x7 << pim_offset));
2830 value |= ((prio & 0x7) << pim_offset);
2831 reg_write(reg, value);
2832 printf("write reg: %x, value: %x\n", reg, value);
2833}
2834
2835void qos_pri_mapping_queue(int argc, char *argv[])
2836{
developerbe40a9e2024-03-07 21:44:26 +08002837 unsigned char prio = 0, queue = 0, pem_n = 0, port = 0;
2838 unsigned int value = 0, reg = 0;
developer546b2792024-06-15 20:31:38 +08002839 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002840
2841 if (argc < 6)
2842 return;
2843
developer546b2792024-06-15 20:31:38 +08002844 errno = 0;
2845 port = strtoul(argv[3], &endptr, 10);
2846 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2847 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2848 return;
2849 }
2850
2851 errno = 0;
2852 prio = strtoul(argv[4], &endptr, 10);
2853 if (errno != 0 || *endptr != '\0' || prio > 7) {
2854 printf(HELP_QOS_PRIO_QMAP);
2855 return;
2856 }
developerfd40db22021-04-29 10:08:25 +08002857
developer546b2792024-06-15 20:31:38 +08002858 errno = 0;
2859 queue = strtoul(argv[5], &endptr, 10);
2860 if (errno != 0 || *endptr != '\0' || queue > 7) {
developerfd40db22021-04-29 10:08:25 +08002861 printf(HELP_QOS_PRIO_QMAP);
2862 return;
2863 }
developerbe40a9e2024-03-07 21:44:26 +08002864
developerfd40db22021-04-29 10:08:25 +08002865 if (chip_name == 0x7530) {
2866 pem_n = prio / 2;
2867 reg = pem_n * 0x4 + 0x48;
2868 reg_read(reg, &value);
2869 if (prio % 2) {
2870 value &= (~(0x7 << 24));
2871 value |= ((queue & 0x7) << 24);
2872 } else {
2873 value &= (~(0x7 << 8));
2874 value |= ((queue & 0x7) << 8);
2875 }
2876 reg_write(reg, value);
2877 printf("write reg: %x, value: %x\n", reg, value);
developer8c3871b2022-07-01 14:07:53 +08002878 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002879 pem_n = prio / 2;
2880 reg = GSW_PEM(pem_n) + 0x100 * port;
2881 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002882 if (prio % 2) { // 1 1
developerfd40db22021-04-29 10:08:25 +08002883 value &= (~(0x7 << 25));
2884 value |= ((queue & 0x7) << 25);
developerbe40a9e2024-03-07 21:44:26 +08002885 } else { // 0 0
developerfd40db22021-04-29 10:08:25 +08002886 value &= (~(0x7 << 9));
2887 value |= ((queue & 0x7) << 9);
2888 }
2889 reg_write(reg, value);
2890 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +08002891 } else {
developerfd40db22021-04-29 10:08:25 +08002892 printf("unknown switch device");
2893 return;
2894 }
2895}
2896
2897static int macMT753xVlanSetVid(unsigned char index, unsigned char active,
developerbe40a9e2024-03-07 21:44:26 +08002898 unsigned short vid, unsigned char portMap,
2899 unsigned char tagPortMap, unsigned char ivl_en,
2900 unsigned char fid, unsigned short stag)
developerfd40db22021-04-29 10:08:25 +08002901{
2902 unsigned int value = 0;
2903 unsigned int value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08002904 unsigned int reg = 0;
2905 int i = 0;
developerfd40db22021-04-29 10:08:25 +08002906
2907 printf("index: %x, active: %x, vid: %x, portMap: %x, \
developerbe40a9e2024-03-07 21:44:26 +08002908 tagPortMap: %x, ivl_en: %x, fid: %x, stag: %x\n", index, active, vid, portMap, tagPortMap, ivl_en, fid, stag);
developerfd40db22021-04-29 10:08:25 +08002909
2910 value = (portMap << 16);
2911 value |= (stag << 4);
2912 value |= (ivl_en << 30);
2913 value |= (fid << 1);
2914 value |= (active ? 1 : 0);
2915
2916 // total 7 ports
2917 for (i = 0; i < 7; i++) {
2918 if (tagPortMap & (1 << i))
2919 value2 |= 0x2 << (i * 2);
2920 }
2921
2922 if (value2)
developerbe40a9e2024-03-07 21:44:26 +08002923 value |= (1 << 28); // eg_tag
developerfd40db22021-04-29 10:08:25 +08002924
developerbe40a9e2024-03-07 21:44:26 +08002925 reg = 0x98; // VAWD2
developerfd40db22021-04-29 10:08:25 +08002926 reg_write(reg, value2);
2927
developerbe40a9e2024-03-07 21:44:26 +08002928 reg = 0x94; // VAWD1
developerfd40db22021-04-29 10:08:25 +08002929 reg_write(reg, value);
2930
developerbe40a9e2024-03-07 21:44:26 +08002931 reg = 0x90; // VTCR
developerfd40db22021-04-29 10:08:25 +08002932 value = (0x80001000 + vid);
2933 reg_write(reg, value);
2934
developerbe40a9e2024-03-07 21:44:26 +08002935 reg = 0x90; // VTCR
developerfd40db22021-04-29 10:08:25 +08002936 while (1) {
2937 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002938 if ((value & 0x80000000) == 0) //table busy
developerfd40db22021-04-29 10:08:25 +08002939 break;
2940 }
2941
2942 /* switch clear */
2943 reg = 0x80;
2944 reg_write(reg, 0x8002);
2945 usleep(5000);
2946 reg_read(reg, &value);
2947
2948 printf("SetVid: index:%d active:%d vid:%d portMap:%x tagPortMap:%x\r\n",
2949 index, active, vid, portMap, tagPortMap);
2950 return 0;
2951
developerbe40a9e2024-03-07 21:44:26 +08002952} /*end macMT753xVlanSetVid */
developerfd40db22021-04-29 10:08:25 +08002953
2954static int macMT753xVlanSetPvid(unsigned char port, unsigned short pvid)
2955{
developerbe40a9e2024-03-07 21:44:26 +08002956 unsigned int value = 0;
2957 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08002958
developerbe40a9e2024-03-07 21:44:26 +08002959 /*Parameters is error */
developerfd40db22021-04-29 10:08:25 +08002960 if (port > 6)
2961 return -1;
2962
2963 reg = 0x2014 + (port * 0x100);
2964 reg_read(reg, &value);
2965 value &= ~0xfff;
2966 value |= pvid;
2967 reg_write(reg, value);
2968
2969 /* switch clear */
2970 reg = 0x80;
2971 reg_write(reg, 0x8002);
2972 usleep(5000);
2973 reg_read(reg, &value);
2974
2975 printf("SetPVID: port:%d pvid:%d\r\n", port, pvid);
2976 return 0;
2977}
developerfd40db22021-04-29 10:08:25 +08002978
2979void doVlanSetPvid(int argc, char *argv[])
2980{
2981 unsigned char port = 0;
2982 unsigned short pvid = 0;
2983
2984 port = atoi(argv[3]);
2985 pvid = atoi(argv[4]);
developerbe40a9e2024-03-07 21:44:26 +08002986 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002987 if ((port >= SWITCH_MAX_PORT) || (pvid > MAX_VID_VALUE)) {
2988 printf(HELP_VLAN_PVID);
2989 return;
2990 }
2991
2992 macMT753xVlanSetPvid(port, pvid);
2993
2994 printf("port:%d pvid:%d,vlancap: max_port:%d maxvid:%d\r\n",
2995 port, pvid, SWITCH_MAX_PORT, MAX_VID_VALUE);
developerbe40a9e2024-03-07 21:44:26 +08002996} /*end doVlanSetPvid */
developerfd40db22021-04-29 10:08:25 +08002997
2998void doVlanSetVid(int argc, char *argv[])
2999{
3000 unsigned char index = 0;
3001 unsigned char active = 0;
3002 unsigned char portMap = 0;
3003 unsigned char tagPortMap = 0;
3004 unsigned short vid = 0;
3005
3006 unsigned char ivl_en = 0;
3007 unsigned char fid = 0;
3008 unsigned short stag = 0;
3009
3010 index = atoi(argv[3]);
3011 active = atoi(argv[4]);
3012 vid = atoi(argv[5]);
3013
developerbe40a9e2024-03-07 21:44:26 +08003014 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003015 if ((index >= MAX_VLAN_RULE) || (vid >= 4096) || (active > ACTIVED)) {
3016 printf(HELP_VLAN_VID);
3017 return;
3018 }
3019
developerbe40a9e2024-03-07 21:44:26 +08003020 /*CPU Port is always the membership */
developerfd40db22021-04-29 10:08:25 +08003021 portMap = atoi(argv[6]);
3022 tagPortMap = atoi(argv[7]);
3023
3024 printf("subcmd parameter argc = %d\r\n", argc);
3025 if (argc >= 9) {
3026 ivl_en = atoi(argv[8]);
3027 if (argc >= 10) {
3028 fid = atoi(argv[9]);
3029 if (argc >= 11)
3030 stag = atoi(argv[10]);
3031 }
3032 }
3033 macMT753xVlanSetVid(index, active, vid, portMap, tagPortMap,
3034 ivl_en, fid, stag);
3035 printf("index:%d active:%d vid:%d\r\n", index, active, vid);
developerbe40a9e2024-03-07 21:44:26 +08003036} /*end doVlanSetVid */
developerfd40db22021-04-29 10:08:25 +08003037
3038void doVlanSetAccFrm(int argc, char *argv[])
3039{
3040 unsigned char port = 0;
3041 unsigned char type = 0;
developerbe40a9e2024-03-07 21:44:26 +08003042 unsigned int value = 0;
3043 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08003044
3045 port = atoi(argv[3]);
3046 type = atoi(argv[4]);
3047
3048 printf("port: %d, type: %d\n", port, type);
3049
developerbe40a9e2024-03-07 21:44:26 +08003050 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003051 if ((port > SWITCH_MAX_PORT) || (type > REG_PVC_ACC_FRM_RELMASK)) {
3052 printf(HELP_VLAN_ACC_FRM);
3053 return;
3054 }
3055
3056 reg = REG_PVC_P0_ADDR + port * 0x100;
3057 reg_read(reg, &value);
3058 value &= (~REG_PVC_ACC_FRM_MASK);
3059 value |= ((unsigned int)type << REG_PVC_ACC_FRM_OFFT);
3060
3061 printf("write reg: %x, value: %x\n", reg, value);
3062 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003063} /*end doVlanSetAccFrm */
developerfd40db22021-04-29 10:08:25 +08003064
3065void doVlanSetPortAttr(int argc, char *argv[])
3066{
3067 unsigned char port = 0;
3068 unsigned char attr = 0;
developerbe40a9e2024-03-07 21:44:26 +08003069 unsigned int value = 0;
3070 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08003071
3072 port = atoi(argv[3]);
3073 attr = atoi(argv[4]);
3074
3075 printf("port: %x, attr: %x\n", port, attr);
3076
developerbe40a9e2024-03-07 21:44:26 +08003077 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003078 if (port > SWITCH_MAX_PORT || attr > 3) {
3079 printf(HELP_VLAN_PORT_ATTR);
3080 return;
3081 }
3082
3083 reg = 0x2010 + port * 0x100;
3084 reg_read(reg, &value);
3085 value &= (0xffffff3f);
3086 value |= (attr << 6);
3087
3088 printf("write reg: %x, value: %x\n", reg, value);
3089 reg_write(reg, value);
3090}
3091
3092void doVlanSetPortMode(int argc, char *argv[])
3093{
3094 unsigned char port = 0;
3095 unsigned char mode = 0;
developerbe40a9e2024-03-07 21:44:26 +08003096 unsigned int value = 0;
3097 unsigned int reg = 0;
3098
developerfd40db22021-04-29 10:08:25 +08003099 port = atoi(argv[3]);
3100 mode = atoi(argv[4]);
3101 printf("port: %x, mode: %x\n", port, mode);
3102
developerbe40a9e2024-03-07 21:44:26 +08003103 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003104 if (port > SWITCH_MAX_PORT || mode > 3) {
3105 printf(HELP_VLAN_PORT_MODE);
3106 return;
3107 }
3108
3109 reg = 0x2004 + port * 0x100;
3110 reg_read(reg, &value);
3111 value &= (~((1 << 0) | (1 << 1)));
3112 value |= (mode & 0x3);
3113 printf("write reg: %x, value: %x\n", reg, value);
3114 reg_write(reg, value);
3115}
3116
3117void doVlanSetEgressTagPCR(int argc, char *argv[])
3118{
3119 unsigned char port = 0;
3120 unsigned char eg_tag = 0;
developerbe40a9e2024-03-07 21:44:26 +08003121 unsigned int value = 0;
3122 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08003123
3124 port = atoi(argv[3]);
3125 eg_tag = atoi(argv[4]);
3126
3127 printf("port: %d, eg_tag: %d\n", port, eg_tag);
3128
developerbe40a9e2024-03-07 21:44:26 +08003129 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003130 if ((port > SWITCH_MAX_PORT) || (eg_tag > REG_PCR_EG_TAG_RELMASK)) {
3131 printf(HELP_VLAN_EGRESS_TAG_PCR);
3132 return;
3133 }
3134
3135 reg = REG_PCR_P0_ADDR + port * 0x100;
3136 reg_read(reg, &value);
3137 value &= (~REG_PCR_EG_TAG_MASK);
3138 value |= ((unsigned int)eg_tag << REG_PCR_EG_TAG_OFFT);
3139
3140 printf("write reg: %x, value: %x\n", reg, value);
3141 reg_write(reg, value);
3142
developerbe40a9e2024-03-07 21:44:26 +08003143} /*end doVlanSetEgressTagPCR */
developerfd40db22021-04-29 10:08:25 +08003144
3145void doVlanSetEgressTagPVC(int argc, char *argv[])
3146{
3147 unsigned char port = 0;
3148 unsigned char eg_tag = 0;
developerbe40a9e2024-03-07 21:44:26 +08003149 unsigned int value = 0;
3150 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08003151
3152 port = atoi(argv[3]);
3153 eg_tag = atoi(argv[4]);
3154
3155 printf("port: %d, eg_tag: %d\n", port, eg_tag);
3156
developerbe40a9e2024-03-07 21:44:26 +08003157 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003158 if ((port > SWITCH_MAX_PORT) || (eg_tag > REG_PVC_EG_TAG_RELMASK)) {
3159 printf(HELP_VLAN_EGRESS_TAG_PVC);
3160 return;
3161 }
3162
3163 reg = REG_PVC_P0_ADDR + port * 0x100;
3164 reg_read(reg, &value);
3165 value &= (~REG_PVC_EG_TAG_MASK);
3166 value |= ((unsigned int)eg_tag << REG_PVC_EG_TAG_OFFT);
3167
3168 printf("write reg: %x, value: %x\n", reg, value);
3169 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003170} /*end doVlanSetEgressTagPVC */
developerfd40db22021-04-29 10:08:25 +08003171
3172void doArlAging(int argc, char *argv[])
3173{
3174 unsigned char aging_en = 0;
developerbe40a9e2024-03-07 21:44:26 +08003175 unsigned int time = 0, aging_cnt = 0, aging_unit = 0, value = 0, reg =
3176 0;
developerfd40db22021-04-29 10:08:25 +08003177
3178 aging_en = atoi(argv[3]);
3179 time = atoi(argv[4]);
3180 printf("aging_en: %x, aging time: %x\n", aging_en, time);
3181
developerbe40a9e2024-03-07 21:44:26 +08003182 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003183 if ((aging_en != 0 && aging_en != 1) || (time <= 0 || time > 65536)) {
3184 printf(HELP_ARL_AGING);
3185 return;
3186 }
3187
3188 reg = 0xa0;
3189 reg_read(reg, &value);
3190 value &= (~(1 << 20));
3191 if (!aging_en) {
3192 value |= (1 << 20);
3193 }
3194
3195 aging_unit = (time / 0x100) + 1;
3196 aging_cnt = (time / aging_unit);
3197 aging_unit--;
3198 aging_cnt--;
3199
3200 value &= (0xfff00000);
3201 value |= ((aging_cnt << 12) | aging_unit);
3202
3203 printf("aging_unit: %x, aging_cnt: %x\n", aging_unit, aging_cnt);
3204 printf("write reg: %x, value: %x\n", reg, value);
3205
3206 reg_write(reg, value);
3207}
3208
3209void doMirrorEn(int argc, char *argv[])
3210{
developerbe40a9e2024-03-07 21:44:26 +08003211 unsigned char mirror_en = 0;
3212 unsigned char mirror_port = 0;
3213 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003214
3215 mirror_en = atoi(argv[3]);
3216 mirror_port = atoi(argv[4]);
3217
3218 printf("mirror_en: %d, mirror_port: %d\n", mirror_en, mirror_port);
3219
developerbe40a9e2024-03-07 21:44:26 +08003220 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003221 if ((mirror_en > 1) || (mirror_port > REG_CFC_MIRROR_PORT_RELMASK)) {
3222 printf(HELP_MIRROR_EN);
3223 return;
3224 }
3225
3226 reg = REG_CFC_ADDR;
3227 reg_read(reg, &value);
3228 value &= (~REG_CFC_MIRROR_EN_MASK);
3229 value |= (mirror_en << REG_CFC_MIRROR_EN_OFFT);
3230 value &= (~REG_CFC_MIRROR_PORT_MASK);
3231 value |= (mirror_port << REG_CFC_MIRROR_PORT_OFFT);
3232
3233 printf("write reg: %x, value: %x\n", reg, value);
3234 reg_write(reg, value);
3235
developerbe40a9e2024-03-07 21:44:26 +08003236} /*end doMirrorEn */
developerfd40db22021-04-29 10:08:25 +08003237
3238void doMirrorPortBased(int argc, char *argv[])
3239{
developerbe40a9e2024-03-07 21:44:26 +08003240 unsigned char port = 0, port_tx_mir = 0, port_rx_mir = 0, vlan_mis =
3241 0, acl_mir = 0, igmp_mir = 0;
3242 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003243
3244 port = atoi(argv[3]);
3245 port_tx_mir = atoi(argv[4]);
3246 port_rx_mir = atoi(argv[5]);
3247 acl_mir = atoi(argv[6]);
3248 vlan_mis = atoi(argv[7]);
3249 igmp_mir = atoi(argv[8]);
3250
developerbe40a9e2024-03-07 21:44:26 +08003251 printf
3252 ("port:%d, port_tx_mir:%d, port_rx_mir:%d, acl_mir:%d, vlan_mis:%d, igmp_mir:%d\n",
3253 port, port_tx_mir, port_rx_mir, acl_mir, vlan_mis, igmp_mir);
developerfd40db22021-04-29 10:08:25 +08003254
developerbe40a9e2024-03-07 21:44:26 +08003255 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003256 //if((port >= vlanCap->max_port_no) || (port_tx_mir > 1) || (port_rx_mir > 1) || (acl_mir > 1) || (vlan_mis > 1)){
developerbe40a9e2024-03-07 21:44:26 +08003257 if ((port >= 7) || (port_tx_mir > 1) || (port_rx_mir > 1) || (acl_mir > 1) || (vlan_mis > 1)) { // also allow CPU port (port6)
developerfd40db22021-04-29 10:08:25 +08003258 printf(HELP_MIRROR_PORTBASED);
3259 return;
3260 }
3261
3262 reg = REG_PCR_P0_ADDR + port * 0x100;
3263 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003264 value &=
3265 ~(REG_PORT_TX_MIR_MASK | REG_PORT_RX_MIR_MASK | REG_PCR_ACL_MIR_MASK
3266 | REG_PCR_VLAN_MIS_MASK);
3267 value |=
3268 (port_tx_mir << REG_PORT_TX_MIR_OFFT) +
3269 (port_rx_mir << REG_PORT_RX_MIR_OFFT);
3270 value |=
3271 (acl_mir << REG_PCR_ACL_MIR_OFFT) +
3272 (vlan_mis << REG_PCR_VLAN_MIS_OFFT);
developerfd40db22021-04-29 10:08:25 +08003273
3274 printf("write reg: %x, value: %x\n", reg, value);
3275 reg_write(reg, value);
3276
3277 reg = REG_PIC_P0_ADDR + port * 0x100;
3278 reg_read(reg, &value);
3279 value &= ~(REG_PIC_IGMP_MIR_MASK);
3280 value |= (igmp_mir << REG_PIC_IGMP_MIR_OFFT);
3281
3282 printf("write reg: %x, value: %x\n", reg, value);
3283 reg_write(reg, value);
3284
developerbe40a9e2024-03-07 21:44:26 +08003285} /*end doMirrorPortBased */
developerfd40db22021-04-29 10:08:25 +08003286
3287void doStp(int argc, char *argv[])
3288{
3289 unsigned char port = 0;
3290 unsigned char fid = 0;
3291 unsigned char state = 0;
developerbe40a9e2024-03-07 21:44:26 +08003292 unsigned int value = 0;
3293 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08003294
3295 port = atoi(argv[2]);
3296 fid = atoi(argv[3]);
3297 state = atoi(argv[4]);
3298
3299 printf("port: %d, fid: %d, state: %d\n", port, fid, state);
3300
developerbe40a9e2024-03-07 21:44:26 +08003301 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003302 if ((port > MAX_PORT + 1) || (fid > 7) || (state > 3)) {
3303 printf(HELP_STP);
3304 return;
3305 }
3306
3307 reg = REG_SSC_P0_ADDR + port * 0x100;
3308 reg_read(reg, &value);
3309 value &= (~(3 << (fid << 2)));
3310 value |= ((unsigned int)state << (fid << 2));
3311
3312 printf("write reg: %x, value: %x\n", reg, value);
3313 reg_write(reg, value);
3314}
3315
developerbe40a9e2024-03-07 21:44:26 +08003316void _ingress_rate_set(int on_off, int port, int bw)
developerfd40db22021-04-29 10:08:25 +08003317{
developerbe40a9e2024-03-07 21:44:26 +08003318 unsigned int reg = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08003319
3320 reg = 0x1800 + (0x100 * port);
3321 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08003322 /*token-bucket */
developerfd40db22021-04-29 10:08:25 +08003323 if (on_off == 1) {
3324 if (chip_name == 0x7530) {
3325 if (bw > 1000000) {
developerbe40a9e2024-03-07 21:44:26 +08003326 printf
3327 ("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",
3328 bw);
3329 return;
developerfd40db22021-04-29 10:08:25 +08003330 }
developerbe40a9e2024-03-07 21:44:26 +08003331 value =
3332 ((bw / 32) << 16) + (1 << 15) + (7 << 8) +
3333 (1 << 7) + 0x0f;
developer8c3871b2022-07-01 14:07:53 +08003334 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3335 if ((chip_name == 0x7531) && (bw > 2500000)) {
developerbe40a9e2024-03-07 21:44:26 +08003336 printf
3337 ("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",
3338 bw);
3339 return;
developerfd40db22021-04-29 10:08:25 +08003340 }
developer8c3871b2022-07-01 14:07:53 +08003341
3342 if ((chip_name == 0x7988) && (bw > 4000000)) {
developerbe40a9e2024-03-07 21:44:26 +08003343 printf
3344 ("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",
3345 bw);
3346 return;
developerfd40db22021-04-29 10:08:25 +08003347 }
developer8c3871b2022-07-01 14:07:53 +08003348
developerbe40a9e2024-03-07 21:44:26 +08003349 if (bw / 32 >= 65536) //supoort 2.5G case
3350 value =
3351 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3352 (1 << 12) + (7 << 8) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003353 else
developerbe40a9e2024-03-07 21:44:26 +08003354 value =
3355 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3356 (7 << 8) + 0xf;
3357 } else
developerfd40db22021-04-29 10:08:25 +08003358 printf("unknow chip\n");
3359 }
developerfd40db22021-04-29 10:08:25 +08003360#if leaky_bucket
3361 reg_read(reg, &value);
3362 value &= 0xffff0000;
developerbe40a9e2024-03-07 21:44:26 +08003363 if (on_off == 1) {
developerfd40db22021-04-29 10:08:25 +08003364 value |= on_off << 15;
3365 //7530 same as 7531
3366 if (bw < 100) {
3367 value |= (0x0 << 8);
3368 value |= bw;
3369 } else if (bw < 1000) {
3370 value |= (0x1 << 8);
3371 value |= bw / 10;
3372 } else if (bw < 10000) {
3373 value |= (0x2 << 8);
3374 value |= bw / 100;
3375 } else if (bw < 100000) {
3376 value |= (0x3 << 8);
3377 value |= bw / 1000;
3378 } else {
3379 value |= (0x4 << 8);
3380 value |= bw / 10000;
3381 }
3382 }
3383#endif
3384 reg_write(reg, value);
3385 reg = 0x1FFC;
3386 reg_read(reg, &value);
3387 value = 0x110104;
3388 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003389
3390 if (on_off)
3391 printf("switch port=%d, bw=%d\n", port, bw);
3392 else
3393 printf("switch port=%d ingress rate limit off\n", port);
developerfd40db22021-04-29 10:08:25 +08003394}
3395
developerbe40a9e2024-03-07 21:44:26 +08003396void ingress_rate_set(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003397{
developerbe40a9e2024-03-07 21:44:26 +08003398 int on_off = 0, port = 0, bw = 0;
developer997ed6b2024-03-26 14:03:42 +08003399 char *endptr;
developerbe40a9e2024-03-07 21:44:26 +08003400
developer997ed6b2024-03-26 14:03:42 +08003401 /* clear errno before conversion to detect overflow */
3402 errno = 0;
3403 port = strtoul(argv[3], &endptr, 0);
3404
3405 if (errno == ERANGE) {
3406 printf("Conversion error, value out of range\n");
3407 return;
3408 }
3409 if (*endptr != '\0') {
3410 printf("Conversion error, no digits were found\n");
3411 return;
3412 }
3413
3414 if (port < 0 || port > 6) {
3415 printf("Wrong port range, should be within 0-6\n");
3416 return;
3417 }
3418
developerbe40a9e2024-03-07 21:44:26 +08003419 if (argv[2][1] == 'n') {
developer997ed6b2024-03-26 14:03:42 +08003420 errno = 0;
3421 bw = strtoul(argv[4], &endptr, 0);
3422 if (errno == ERANGE) {
3423 printf("Conversion error, value out of range\n");
3424 return;
3425 }
3426 if (*endptr != '\0') {
3427 printf("Conversion error, no digits were found\n");
3428 return;
3429 }
developerbe40a9e2024-03-07 21:44:26 +08003430 on_off = 1;
3431 } else if (argv[2][1] == 'f') {
3432 if (argc != 4)
3433 return;
3434 on_off = 0;
3435 }
3436
3437 _ingress_rate_set(on_off, port, bw);
3438}
3439
3440void _egress_rate_set(int on_off, int port, int bw)
3441{
3442 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003443
3444 reg = 0x1040 + (0x100 * port);
3445 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08003446 /*token-bucket */
developerfd40db22021-04-29 10:08:25 +08003447 if (on_off == 1) {
3448 if (chip_name == 0x7530) {
3449 if (bw < 0 || bw > 1000000) {
developerbe40a9e2024-03-07 21:44:26 +08003450 printf
3451 ("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",
3452 bw);
3453 return;
developerfd40db22021-04-29 10:08:25 +08003454 }
developerbe40a9e2024-03-07 21:44:26 +08003455 value =
3456 ((bw / 32) << 16) + (1 << 15) + (7 << 8) +
3457 (1 << 7) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003458 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3459 if ((chip_name == 0x7531) && (bw < 0 || bw > 2500000)) {
developerbe40a9e2024-03-07 21:44:26 +08003460 printf
3461 ("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",
3462 bw);
3463 return;
developerfd40db22021-04-29 10:08:25 +08003464 }
developer8c3871b2022-07-01 14:07:53 +08003465 if ((chip_name == 0x7988) && (bw < 0 || bw > 4000000)) {
developerbe40a9e2024-03-07 21:44:26 +08003466 printf
3467 ("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",
3468 bw);
3469 return;
developer8c3871b2022-07-01 14:07:53 +08003470 }
3471
developerbe40a9e2024-03-07 21:44:26 +08003472 if (bw / 32 >= 65536) //support 2.5G cases
3473 value =
3474 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3475 (1 << 12) + (7 << 8) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003476 else
developerbe40a9e2024-03-07 21:44:26 +08003477 value =
3478 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3479 (7 << 8) + 0xf;
3480 } else
developerfd40db22021-04-29 10:08:25 +08003481 printf("unknow chip\n");
3482 }
3483 reg_write(reg, value);
3484 reg = 0x10E0;
3485 reg_read(reg, &value);
3486 value &= 0x18;
3487 reg_write(reg, value);
3488
developerbe40a9e2024-03-07 21:44:26 +08003489 if (on_off)
3490 printf("switch port=%d, bw=%d\n", port, bw);
3491 else
3492 printf("switch port=%d egress rate limit off\n", port);
3493}
3494
3495void egress_rate_set(int argc, char *argv[])
3496{
3497 unsigned int value = 0, reg = 0;
3498 int on_off = 0, port = 0, bw = 0;
developer997ed6b2024-03-26 14:03:42 +08003499 char *endptr;
developerbe40a9e2024-03-07 21:44:26 +08003500
developer997ed6b2024-03-26 14:03:42 +08003501 /* clear errno before conversion to detect overflow */
3502 errno = 0;
3503 port = strtoul(argv[3], &endptr, 0);
3504 if (errno == ERANGE) {
3505 printf("Conversion error, value out of range\n");
3506 return;
3507 }
3508 if (*endptr != '\0') {
3509 printf("Conversion error, no digits were found\n");
3510 return;
3511 }
3512 if (port < 0 || port > 6) {
3513 printf("Wrong port range, should be within 0-6\n");
3514 return;
3515 }
developerbe40a9e2024-03-07 21:44:26 +08003516 if (argv[2][1] == 'n') {
developer997ed6b2024-03-26 14:03:42 +08003517 errno = 0;
3518 bw = strtoul(argv[4], &endptr, 0);
3519 if (errno == ERANGE) {
3520 printf("Conversion error, value out of range\n");
3521 return;
3522 }
3523 if (*endptr != '\0') {
3524 printf("Conversion error, no digits were found\n");
3525 return;
3526 }
developerbe40a9e2024-03-07 21:44:26 +08003527 on_off = 1;
3528 } else if (argv[2][1] == 'f') {
3529 if (argc != 4)
3530 return;
3531 on_off = 0;
3532 }
3533
3534 _egress_rate_set(on_off, port, bw);
developerfd40db22021-04-29 10:08:25 +08003535}
3536
3537void rate_control(int argc, char *argv[])
3538{
3539 unsigned char dir = 0;
3540 unsigned char port = 0;
3541 unsigned int rate = 0;
3542
3543 dir = atoi(argv[2]);
3544 port = atoi(argv[3]);
3545 rate = atoi(argv[4]);
3546
3547 if (port > 6)
3548 return;
3549
developerbe40a9e2024-03-07 21:44:26 +08003550 if (dir == 1) //ingress
3551 _ingress_rate_set(1, port, rate);
3552 else if (dir == 0) //egress
3553 _egress_rate_set(1, port, rate);
developerfd40db22021-04-29 10:08:25 +08003554 else
3555 return;
3556}
3557
developerbe40a9e2024-03-07 21:44:26 +08003558void collision_pool_enable(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003559{
3560
developerbe40a9e2024-03-07 21:44:26 +08003561 unsigned char enable = 0;
3562 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003563
3564 enable = atoi(argv[3]);
3565
developerfd40db22021-04-29 10:08:25 +08003566 printf("collision pool enable: %d \n", enable);
3567
developerbe40a9e2024-03-07 21:44:26 +08003568 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003569 if (enable > 1) {
3570 printf(HELP_COLLISION_POOL_EN);
developerbe40a9e2024-03-07 21:44:26 +08003571 return;
developerfd40db22021-04-29 10:08:25 +08003572 }
3573
developer8c3871b2022-07-01 14:07:53 +08003574 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003575 reg = REG_CPGC_ADDR;
developerbe40a9e2024-03-07 21:44:26 +08003576 if (enable == 1) {
developerfd40db22021-04-29 10:08:25 +08003577 /* active reset */
3578 reg_read(reg, &value);
3579 value &= (~REG_CPCG_COL_RST_N_MASK);
3580 reg_write(reg, value);
3581
3582 /* enanble clock */
3583 reg_read(reg, &value);
3584 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3585 value |= (1 << REG_CPCG_COL_CLK_EN_OFFT);
3586 reg_write(reg, value);
3587
3588 /* inactive reset */
3589 reg_read(reg, &value);
3590 value &= (~REG_CPCG_COL_RST_N_MASK);
3591 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3592 reg_write(reg, value);
3593
3594 /* enable collision pool */
3595 reg_read(reg, &value);
3596 value &= (~REG_CPCG_COL_EN_MASK);
3597 value |= (1 << REG_CPCG_COL_EN_OFFT);
3598 reg_write(reg, value);
3599
3600 reg_read(reg, &value);
3601 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003602 } else {
developerfd40db22021-04-29 10:08:25 +08003603
3604 /* disable collision pool */
3605 reg_read(reg, &value);
3606 value &= (~REG_CPCG_COL_EN_MASK);
3607 reg_write(reg, value);
3608
3609 /* active reset */
3610 reg_read(reg, &value);
3611 value &= (~REG_CPCG_COL_RST_N_MASK);
3612 reg_write(reg, value);
3613
3614 /* inactive reset */
3615 reg_read(reg, &value);
3616 value &= (~REG_CPCG_COL_RST_N_MASK);
3617 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3618 reg_write(reg, value);
3619
3620 /* disable clock */
3621 reg_read(reg, &value);
3622 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3623 reg_write(reg, value);
3624
3625 reg_read(reg, &value);
3626 printf("write reg: %x, value: %x\n", reg, value);
3627
3628 }
developerbe40a9e2024-03-07 21:44:26 +08003629 } else {
developerfd40db22021-04-29 10:08:25 +08003630 printf("\nCommand not support by this chip.\n");
developerbe40a9e2024-03-07 21:44:26 +08003631 }
developerfd40db22021-04-29 10:08:25 +08003632}
3633
developerbe40a9e2024-03-07 21:44:26 +08003634void collision_pool_mac_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003635{
developerbe40a9e2024-03-07 21:44:26 +08003636 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003637
developer8c3871b2022-07-01 14:07:53 +08003638 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003639 reg = REG_CPGC_ADDR;
3640 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003641 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003642 table_dump_internal(COLLISION_TABLE);
3643 else
developerbe40a9e2024-03-07 21:44:26 +08003644 printf
3645 ("\ncollision pool is disabled, please enable it before use this command.\n");
3646 } else {
developerfd40db22021-04-29 10:08:25 +08003647 printf("\nCommand not support by this chip.\n");
3648 }
3649}
3650
developerbe40a9e2024-03-07 21:44:26 +08003651void collision_pool_dip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003652{
developerbe40a9e2024-03-07 21:44:26 +08003653 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003654
developer8c3871b2022-07-01 14:07:53 +08003655 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003656 reg = REG_CPGC_ADDR;
3657 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003658 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003659 dip_dump_internal(COLLISION_TABLE);
3660 else
developerbe40a9e2024-03-07 21:44:26 +08003661 printf
3662 ("\ncollision pool is disabled, please enable it before use this command.\n");
3663 } else {
developerfd40db22021-04-29 10:08:25 +08003664 printf("\nCommand not support by this chip.\n");
3665 }
developerfd40db22021-04-29 10:08:25 +08003666}
3667
developerbe40a9e2024-03-07 21:44:26 +08003668void collision_pool_sip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003669{
developerbe40a9e2024-03-07 21:44:26 +08003670 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003671
developerbe40a9e2024-03-07 21:44:26 +08003672 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003673 reg = REG_CPGC_ADDR;
3674 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003675 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003676 sip_dump_internal(COLLISION_TABLE);
3677 else
developerbe40a9e2024-03-07 21:44:26 +08003678 printf
3679 ("\ncollision pool is disabled, please enable it before use this command.\n");
3680 } else {
developerfd40db22021-04-29 10:08:25 +08003681 printf("\nCommand not support by this chip.\n");
3682 }
developerfd40db22021-04-29 10:08:25 +08003683}
3684
3685void pfc_get_rx_counter(int argc, char *argv[])
3686{
developerbe40a9e2024-03-07 21:44:26 +08003687 int port = 0;
3688 unsigned int value = 0, reg = 0;
3689 unsigned int user_pri = 0;
developerfd40db22021-04-29 10:08:25 +08003690
3691 port = strtoul(argv[3], NULL, 0);
3692 if (port < 0 || 6 < port) {
3693 printf("wrong port range, should be within 0~6\n");
3694 return;
3695 }
3696
developerbe40a9e2024-03-07 21:44:26 +08003697 if (chip_name == 0x7531 || chip_name == 0x7988) {
3698 reg = PFC_RX_COUNTER_L(port);
developerfd40db22021-04-29 10:08:25 +08003699 reg_read(reg, &value);
3700 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003701 printf("\n port %d rx pfc (up=0)pause on counter is %d.\n",
3702 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003703 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003704 printf("\n port %d rx pfc (up=1)pause on counter is %d.\n",
3705 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003706 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003707 printf("\n port %d rx pfc (up=2)pause on counter is %d.\n",
3708 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003709 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003710 printf("\n port %d rx pfc (up=3)pause on counter is %d.\n",
3711 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003712
developerbe40a9e2024-03-07 21:44:26 +08003713 reg = PFC_RX_COUNTER_H(port);
developerfd40db22021-04-29 10:08:25 +08003714 reg_read(reg, &value);
3715 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003716 printf("\n port %d rx pfc (up=4)pause on counter is %d.\n",
3717 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003718 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003719 printf("\n port %d rx pfc (up=5)pause on counter is %d.\n",
3720 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003721 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003722 printf("\n port %d rx pfc (up=6)pause on counter is %d.\n",
3723 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003724 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003725 printf("\n port %d rx pfc (up=7)pause on counter is %d.\n",
3726 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003727
3728 /* for rx counter could be updated successfully */
3729 reg_read(PMSR_P(port), &value);
3730 reg_read(PMSR_P(port), &value);
developerbe40a9e2024-03-07 21:44:26 +08003731 } else {
developerfd40db22021-04-29 10:08:25 +08003732 printf("\nCommand not support by this chip.\n");
3733 }
3734
3735}
3736
3737void pfc_get_tx_counter(int argc, char *argv[])
3738{
developerbe40a9e2024-03-07 21:44:26 +08003739 int port = 0;
3740 unsigned int value = 0, reg = 0;
3741 unsigned int user_pri = 0;
developerfd40db22021-04-29 10:08:25 +08003742
3743 port = strtoul(argv[3], NULL, 0);
3744 if (port < 0 || 6 < port) {
3745 printf("wrong port range, should be within 0~6\n");
3746 return;
3747 }
3748
developer8c3871b2022-07-01 14:07:53 +08003749 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerbe40a9e2024-03-07 21:44:26 +08003750 reg = PFC_TX_COUNTER_L(port);
developerfd40db22021-04-29 10:08:25 +08003751 reg_read(reg, &value);
3752 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003753 printf("\n port %d tx pfc (up=0)pause on counter is %d.\n",
3754 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003755 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003756 printf("\n port %d tx pfc (up=1)pause on counter is %d.\n",
3757 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003758 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003759 printf("\n port %d tx pfc (up=2)pause on counter is %d.\n",
3760 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003761 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003762 printf("\n port %d tx pfc (up=3)pause on counter is %d.\n",
3763 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003764
developerbe40a9e2024-03-07 21:44:26 +08003765 reg = PFC_TX_COUNTER_H(port);
developerfd40db22021-04-29 10:08:25 +08003766 reg_read(reg, &value);
3767 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003768 printf("\n port %d tx pfc (up=4)pause on counter is %d.\n",
3769 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003770 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003771 printf("\n port %d tx pfc (up=5)pause on counter is %d.\n",
3772 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003773 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003774 printf("\n port %d tx pfc (up=6)pause on counter is %d.\n",
3775 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003776 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003777 printf("\n port %d tx pfc (up=7)pause on counter is %d.\n",
3778 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003779
3780 /* for tx counter could be updated successfully */
3781 reg_read(PMSR_P(port), &value);
3782 reg_read(PMSR_P(port), &value);
developerbe40a9e2024-03-07 21:44:26 +08003783 } else {
3784 printf("\nCommand not support by this chip.\n");
developerfd40db22021-04-29 10:08:25 +08003785 }
3786}
3787
developerbe40a9e2024-03-07 21:44:26 +08003788void read_output_queue_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003789{
developerbe40a9e2024-03-07 21:44:26 +08003790 unsigned int port = 0;
3791 unsigned int value = 0, output_queue = 0;
3792 unsigned int base = 0x220;
developerfd40db22021-04-29 10:08:25 +08003793
3794 for (port = 0; port < 7; port++) {
developerbe40a9e2024-03-07 21:44:26 +08003795 reg_write(0x7038, base + (port * 4));
developerfd40db22021-04-29 10:08:25 +08003796 reg_read(0x7034, &value);
3797 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003798 printf("\n port %d output queue 0 counter is %d.\n", port,
3799 output_queue);
developerfd40db22021-04-29 10:08:25 +08003800 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003801 printf("\n port %d output queue 1 counter is %d.\n", port,
3802 output_queue);
developerfd40db22021-04-29 10:08:25 +08003803
developerbe40a9e2024-03-07 21:44:26 +08003804 reg_write(0x7038, base + (port * 4) + 1);
developerfd40db22021-04-29 10:08:25 +08003805 reg_read(0x7034, &value);
3806 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003807 printf("\n port %d output queue 2 counter is %d.\n", port,
3808 output_queue);
developerfd40db22021-04-29 10:08:25 +08003809 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003810 printf("\n port %d output queue 3 counter is %d.\n", port,
3811 output_queue);
developerfd40db22021-04-29 10:08:25 +08003812
developerbe40a9e2024-03-07 21:44:26 +08003813 reg_write(0x7038, base + (port * 4) + 2);
developerfd40db22021-04-29 10:08:25 +08003814 reg_read(0x7034, &value);
3815 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003816 printf("\n port %d output queue 4 counter is %d.\n", port,
3817 output_queue);
developerfd40db22021-04-29 10:08:25 +08003818 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003819 printf("\n port %d output queue 5 counter is %d.\n", port,
3820 output_queue);
developerfd40db22021-04-29 10:08:25 +08003821
developerbe40a9e2024-03-07 21:44:26 +08003822 reg_write(0x7038, base + (port * 4) + 3);
developerfd40db22021-04-29 10:08:25 +08003823 reg_read(0x7034, &value);
3824 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003825 printf("\n port %d output queue 6 counter is %d.\n", port,
3826 output_queue);
developerfd40db22021-04-29 10:08:25 +08003827 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003828 printf("\n port %d output queue 7 counter is %d.\n", port,
3829 output_queue);
developerfd40db22021-04-29 10:08:25 +08003830 }
3831}
3832
developerbe40a9e2024-03-07 21:44:26 +08003833void read_free_page_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003834{
developerbe40a9e2024-03-07 21:44:26 +08003835 unsigned int value = 0;
3836 unsigned int free_page = 0, free_page_last_read = 0;
3837 unsigned int fc_free_blk_lothd = 0, fc_free_blk_hithd = 0;
3838 unsigned int fc_port_blk_thd = 0, fc_port_blk_hi_thd = 0;
3839 unsigned int queue[8] = { 0 };
developerfd40db22021-04-29 10:08:25 +08003840
developer8c3871b2022-07-01 14:07:53 +08003841 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerbe40a9e2024-03-07 21:44:26 +08003842 /* get system free page link counter */
developerfd40db22021-04-29 10:08:25 +08003843 reg_read(0x1fc0, &value);
3844 free_page = value & 0xFFF;
3845 free_page_last_read = (value & 0xFFF0000) >> 16;
3846
3847 /* get system flow control waterwark */
3848 reg_read(0x1fe0, &value);
3849 fc_free_blk_lothd = value & 0x3FF;
3850 fc_free_blk_hithd = (value & 0x3FF0000) >> 16;
3851
3852 /* get port flow control waterwark */
3853 reg_read(0x1fe4, &value);
3854 fc_port_blk_thd = value & 0x3FF;
3855 fc_port_blk_hi_thd = (value & 0x3FF0000) >> 16;
3856
3857 /* get queue flow control waterwark */
3858 reg_read(0x1fe8, &value);
developerbe40a9e2024-03-07 21:44:26 +08003859 queue[0] = value & 0x3F;
3860 queue[1] = (value & 0x3F00) >> 8;
3861 queue[2] = (value & 0x3F0000) >> 16;
3862 queue[3] = (value & 0x3F000000) >> 24;
developerfd40db22021-04-29 10:08:25 +08003863 reg_read(0x1fec, &value);
developerbe40a9e2024-03-07 21:44:26 +08003864 queue[4] = value & 0x3F;
3865 queue[5] = (value & 0x3F00) >> 8;
3866 queue[6] = (value & 0x3F0000) >> 16;
3867 queue[7] = (value & 0x3F000000) >> 24;
developerfd40db22021-04-29 10:08:25 +08003868 } else {
developerbe40a9e2024-03-07 21:44:26 +08003869 /* get system free page link counter */
developerfd40db22021-04-29 10:08:25 +08003870 reg_read(0x1fc0, &value);
3871 free_page = value & 0x3FF;
3872 free_page_last_read = (value & 0x3FF0000) >> 16;
3873
3874 /* get system flow control waterwark */
3875 reg_read(0x1fe0, &value);
3876 fc_free_blk_lothd = value & 0xFF;
3877 fc_free_blk_hithd = (value & 0xFF00) >> 8;
3878
3879 /* get port flow control waterwark */
3880 reg_read(0x1fe0, &value);
3881 fc_port_blk_thd = (value & 0xFF0000) >> 16;
3882 reg_read(0x1ff4, &value);
3883 fc_port_blk_hi_thd = (value & 0xFF00) >> 8;
3884
3885 /* get queue flow control waterwark */
3886 reg_read(0x1fe4, &value);
developerbe40a9e2024-03-07 21:44:26 +08003887 queue[0] = value & 0xF;
3888 queue[1] = (value & 0xF0) >> 4;
3889 queue[2] = (value & 0xF00) >> 8;
3890 queue[3] = (value & 0xF000) >> 12;
3891 queue[4] = (value & 0xF0000) >> 16;
3892 queue[5] = (value & 0xF00000) >> 20;
3893 queue[6] = (value & 0xF000000) >> 24;
3894 queue[7] = (value & 0xF0000000) >> 28;
developerfd40db22021-04-29 10:08:25 +08003895 }
3896
developerbe40a9e2024-03-07 21:44:26 +08003897 printf("<===Free Page=======Current=======Last Read access=====>\n");
3898 printf("\n");
3899 printf(" page counter %u %u\n ",
3900 free_page, free_page_last_read);
3901 printf("\n ");
3902 printf("=========================================================\n");
3903 printf("<===Type=======High threshold======Low threshold=========\n");
3904 printf("\n ");
3905 printf(" system: %u %u\n",
3906 fc_free_blk_hithd * 2, fc_free_blk_lothd * 2);
3907 printf(" port: %u %u\n",
3908 fc_port_blk_hi_thd * 2, fc_port_blk_thd * 2);
3909 printf(" queue 0: %u NA\n",
3910 queue[0]);
3911 printf(" queue 1: %u NA\n",
3912 queue[1]);
3913 printf(" queue 2: %u NA\n",
3914 queue[2]);
3915 printf(" queue 3: %u NA\n",
3916 queue[3]);
3917 printf(" queue 4: %u NA\n",
3918 queue[4]);
3919 printf(" queue 5: %u NA\n",
3920 queue[5]);
3921 printf(" queue 6: %u NA\n",
3922 queue[6]);
3923 printf(" queue 7: %u NA\n",
3924 queue[7]);
3925 printf("=========================================================\n");
developerfd40db22021-04-29 10:08:25 +08003926}
3927
3928void eee_enable(int argc, char *argv[])
3929{
developerbe40a9e2024-03-07 21:44:26 +08003930 unsigned long enable = 0;
3931 unsigned int value = 0;
3932 unsigned int eee_cap = 0;
developerfd40db22021-04-29 10:08:25 +08003933 unsigned int eee_en_bitmap = 0;
developerbe40a9e2024-03-07 21:44:26 +08003934 unsigned long port_map = 0;
developerfd40db22021-04-29 10:08:25 +08003935 long port_num = -1;
developerbe40a9e2024-03-07 21:44:26 +08003936 int p = 0;
developerfd40db22021-04-29 10:08:25 +08003937
3938 if (argc < 3)
3939 goto error;
3940
developerbe40a9e2024-03-07 21:44:26 +08003941 /* Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003942 if (!strncmp(argv[2], "enable", 7))
3943 enable = 1;
3944 else if (!strncmp(argv[2], "disable", 8))
3945 enable = 0;
3946 else
3947 goto error;
3948
3949 if (argc > 3) {
3950 if (strlen(argv[3]) == 1) {
3951 port_num = strtol(argv[3], (char **)NULL, 10);
3952 if (port_num < 0 || port_num > MAX_PHY_PORT - 1) {
3953 printf("Illegal port index and port:0~4\n");
3954 goto error;
3955 }
3956 port_map = 1 << port_num;
3957 } else if (strlen(argv[3]) == 5) {
3958 port_map = 0;
3959 for (p = 0; p < MAX_PHY_PORT; p++) {
3960 if (argv[3][p] != '0' && argv[3][p] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08003961 printf
3962 ("portmap format error, should be combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08003963 goto error;
3964 }
3965 port_map |= ((argv[3][p] - '0') << p);
3966 }
3967 } else {
developerbe40a9e2024-03-07 21:44:26 +08003968 printf
3969 ("port_no or portmap format error, should be length of 1 or 5\n");
developerfd40db22021-04-29 10:08:25 +08003970 goto error;
3971 }
3972 } else {
3973 port_map = 0x1f;
3974 }
3975
developerbe40a9e2024-03-07 21:44:26 +08003976 eee_cap = (enable) ? 6 : 0;
developerfd40db22021-04-29 10:08:25 +08003977 for (p = 0; p < MAX_PHY_PORT; p++) {
3978 /* port_map describe p0p1p2p3p4 from left to rignt */
developerbe40a9e2024-03-07 21:44:26 +08003979 if (!!(port_map & (1 << p)))
developerfd40db22021-04-29 10:08:25 +08003980 mii_mgr_c45_write(p, 0x7, 0x3c, eee_cap);
3981
3982 mii_mgr_c45_read(p, 0x7, 0x3c, &value);
3983 /* mt7531: Always readback eee_cap = 0 when global EEE switch
3984 * is turned off.
3985 */
3986 if (value | eee_cap)
3987 eee_en_bitmap |= (1 << (MAX_PHY_PORT - 1 - p));
3988 }
3989
3990 /* Turn on/off global EEE switch */
developer8c3871b2022-07-01 14:07:53 +08003991 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003992 mii_mgr_c45_read(0, 0x1f, 0x403, &value);
3993 if (eee_en_bitmap)
3994 value |= (1 << 6);
3995 else
3996 value &= ~(1 << 6);
3997 mii_mgr_c45_write(0, 0x1f, 0x403, value);
3998 } else {
3999 printf("\nCommand not support by this chip.\n");
4000 }
4001
developerbe40a9e2024-03-07 21:44:26 +08004002 printf("EEE(802.3az) %s", (enable) ? "enable" : "disable");
developerfd40db22021-04-29 10:08:25 +08004003 if (argc == 4) {
4004 if (port_num >= 0)
4005 printf(" port%ld", port_num);
4006 else
4007 printf(" port_map: %s", argv[3]);
4008 } else {
4009 printf(" all ports");
4010 }
4011 printf("\n");
4012
4013 return;
4014error:
4015 printf(HELP_EEE_EN);
4016 return;
4017}
4018
4019void eee_dump(int argc, char *argv[])
4020{
developerbe40a9e2024-03-07 21:44:26 +08004021 unsigned int cap = 0, lp_cap = 0;
developerfd40db22021-04-29 10:08:25 +08004022 long port = -1;
developerbe40a9e2024-03-07 21:44:26 +08004023 int p = 0;
developerfd40db22021-04-29 10:08:25 +08004024
4025 if (argc > 3) {
4026 if (strlen(argv[3]) > 1) {
4027 printf("port# format error, should be of length 1\n");
4028 return;
4029 }
4030
4031 port = strtol(argv[3], (char **)NULL, 0);
4032 if (port < 0 || port > MAX_PHY_PORT) {
4033 printf("port# format error, should be 0 to %d\n",
developerbe40a9e2024-03-07 21:44:26 +08004034 MAX_PHY_PORT);
developerfd40db22021-04-29 10:08:25 +08004035 return;
4036 }
4037 }
4038
4039 for (p = 0; p < MAX_PHY_PORT; p++) {
4040 if (port >= 0 && p != port)
4041 continue;
4042
4043 mii_mgr_c45_read(p, 0x7, 0x3c, &cap);
4044 mii_mgr_c45_read(p, 0x7, 0x3d, &lp_cap);
4045 printf("port%d EEE cap=0x%02x, link partner EEE cap=0x%02x",
4046 p, cap, lp_cap);
4047
4048 if (port >= 0 && p == port) {
4049 mii_mgr_c45_read(p, 0x3, 0x1, &cap);
4050 printf(", st=0x%03x", cap);
4051 }
4052 printf("\n");
4053 }
4054}
4055
4056void dump_each_port(unsigned int base)
4057{
4058 unsigned int pkt_cnt = 0;
4059 int i = 0;
4060
4061 for (i = 0; i < 7; i++) {
developer0dea3402022-10-14 13:41:11 +08004062 if (chip_name == 0x7988) {
4063 if ((base == 0x402C) && (i == 6))
4064 base = 0x408C;
4065 else if ((base == 0x408C) && (i == 6))
4066 base = 0x402C;
4067 else
4068 ;
4069 }
developerfd40db22021-04-29 10:08:25 +08004070 reg_read((base) + (i * 0x100), &pkt_cnt);
4071 printf("%8u ", pkt_cnt);
4072 }
4073 printf("\n");
4074}
4075
developerbe40a9e2024-03-07 21:44:26 +08004076void read_mib_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08004077{
4078 printf("===================== %8s %8s %8s %8s %8s %8s %8s\n",
4079 "Port0", "Port1", "Port2", "Port3", "Port4", "Port5", "Port6");
4080 printf("Tx Drop Packet :");
4081 dump_each_port(0x4000);
4082 printf("Tx CRC Error :");
4083 dump_each_port(0x4004);
4084 printf("Tx Unicast Packet :");
4085 dump_each_port(0x4008);
4086 printf("Tx Multicast Packet :");
4087 dump_each_port(0x400C);
4088 printf("Tx Broadcast Packet :");
4089 dump_each_port(0x4010);
4090 printf("Tx Collision Event :");
4091 dump_each_port(0x4014);
4092 printf("Tx Pause Packet :");
4093 dump_each_port(0x402C);
4094 printf("Rx Drop Packet :");
4095 dump_each_port(0x4060);
4096 printf("Rx Filtering Packet :");
4097 dump_each_port(0x4064);
4098 printf("Rx Unicast Packet :");
4099 dump_each_port(0x4068);
4100 printf("Rx Multicast Packet :");
4101 dump_each_port(0x406C);
4102 printf("Rx Broadcast Packet :");
4103 dump_each_port(0x4070);
4104 printf("Rx Alignment Error :");
4105 dump_each_port(0x4074);
4106 printf("Rx CRC Error :");
4107 dump_each_port(0x4078);
4108 printf("Rx Undersize Error :");
4109 dump_each_port(0x407C);
4110 printf("Rx Fragment Error :");
4111 dump_each_port(0x4080);
4112 printf("Rx Oversize Error :");
4113 dump_each_port(0x4084);
4114 printf("Rx Jabber Error :");
4115 dump_each_port(0x4088);
4116 printf("Rx Pause Packet :");
4117 dump_each_port(0x408C);
4118}
4119
developerbe40a9e2024-03-07 21:44:26 +08004120void clear_mib_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08004121{
4122 reg_write(0x4fe0, 0xf0);
developerbe40a9e2024-03-07 21:44:26 +08004123 read_mib_counters(argc, argv);
developerfd40db22021-04-29 10:08:25 +08004124 reg_write(0x4fe0, 0x800000f0);
4125}
4126
developerfd40db22021-04-29 10:08:25 +08004127void exit_free()
4128{
4129 free(attres);
4130 attres = NULL;
4131 switch_ioctl_fini();
4132 mt753x_netlink_free();
4133}