blob: 9e9f4fe6970ced1316f784e9813ddade1269e9db [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001/*
2* switch_fun.c: switch function sets
3*/
4#include <stdio.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <string.h>
8#include <stdbool.h>
9#include <sys/ioctl.h>
10#include <sys/socket.h>
11#include <linux/if.h>
12#include <stdbool.h>
13#include <time.h>
14
15#include "switch_extend.h"
16#include "switch_netlink.h"
17#include "switch_ioctl.h"
18#include "switch_fun.h"
19
20#define leaky_bucket 0
21
developerbe40a9e2024-03-07 21:44:26 +080022struct switch_func_s mt753x_switch_func = {
23 .pf_table_dump = table_dump,
24 .pf_table_clear = table_clear,
25 .pf_switch_reset = switch_reset,
26 .pf_doArlAging = doArlAging,
27 .pf_read_mib_counters = read_mib_counters,
28 .pf_clear_mib_counters = clear_mib_counters,
29 .pf_read_output_queue_counters = read_output_queue_counters,
30 .pf_read_free_page_counters = read_free_page_counters,
31 .pf_rate_control = rate_control,
32 .pf_igress_rate_set = ingress_rate_set,
33 .pf_egress_rate_set = egress_rate_set,
34 .pf_table_add = table_add,
35 .pf_table_del_fid = table_del_fid,
36 .pf_table_del_vid = table_del_vid,
37 .pf_table_search_mac_fid = table_search_mac_fid,
38 .pf_table_search_mac_vid = table_search_mac_vid,
39 .pf_global_set_mac_fc = global_set_mac_fc,
40 .pf_set_mac_pfc = set_mac_pfc,
41 .pf_qos_sch_select = qos_sch_select,
42 .pf_qos_set_base = qos_set_base,
43 .pf_qos_wfq_set_weight = qos_wfq_set_weight,
44 .pf_qos_set_portpri = qos_set_portpri,
45 .pf_qos_set_dscppri = qos_set_dscppri,
46 .pf_qos_pri_mapping_queue = qos_pri_mapping_queue,
47 .pf_doStp = doStp,
48 .pf_sip_dump = sip_dump,
49 .pf_sip_add = sip_add,
50 .pf_sip_del = sip_del,
51 .pf_sip_clear = sip_clear,
52 .pf_dip_dump = dip_dump,
53 .pf_dip_add = dip_add,
54 .pf_dip_del = dip_del,
55 .pf_dip_clear = dip_clear,
56 .pf_set_mirror_to = set_mirror_to,
57 .pf_set_mirror_from = set_mirror_from,
58 .pf_doMirrorEn = doMirrorEn,
59 .pf_doMirrorPortBased = doMirrorPortBased,
60 .pf_acl_dip_add = acl_dip_add,
61 .pf_acl_dip_modify = acl_dip_modify,
62 .pf_acl_dip_pppoe = acl_dip_pppoe,
63 .pf_acl_dip_trtcm = acl_dip_trtcm,
64 .pf_acl_dip_meter = acl_dip_meter,
65 .pf_acl_mac_add = acl_mac_add,
66 .pf_acl_ethertype = acl_ethertype,
67 .pf_acl_sp_add = acl_sp_add,
68 .pf_acl_l4_add = acl_l4_add,
69 .pf_acl_port_enable = acl_port_enable,
70 .pf_acl_table_add = acl_table_add,
71 .pf_acl_mask_table_add = acl_mask_table_add,
72 .pf_acl_rule_table_add = acl_rule_table_add,
73 .pf_acl_rate_table_add = acl_rate_table_add,
74 .pf_vlan_dump = vlan_dump,
75 .pf_vlan_set = vlan_set,
76 .pf_vlan_clear = vlan_clear,
77 .pf_doVlanSetVid = doVlanSetVid,
78 .pf_doVlanSetPvid = doVlanSetPvid,
79 .pf_doVlanSetAccFrm = doVlanSetAccFrm,
80 .pf_doVlanSetPortAttr = doVlanSetPortAttr,
81 .pf_doVlanSetPortMode = doVlanSetPortMode,
82 .pf_doVlanSetEgressTagPCR = doVlanSetEgressTagPCR,
83 .pf_doVlanSetEgressTagPVC = doVlanSetEgressTagPVC,
84 .pf_igmp_on = igmp_on,
85 .pf_igmp_off = igmp_off,
86 .pf_igmp_enable = igmp_enable,
87 .pf_igmp_disable = igmp_disable,
88 .pf_collision_pool_enable = collision_pool_enable,
89 .pf_collision_pool_mac_dump = collision_pool_mac_dump,
90 .pf_collision_pool_dip_dump = collision_pool_dip_dump,
91 .pf_collision_pool_sip_dump = collision_pool_sip_dump,
92 .pf_pfc_get_rx_counter = pfc_get_rx_counter,
93 .pf_pfc_get_tx_counter = pfc_get_tx_counter,
94 .pf_eee_enable = eee_enable,
95 .pf_eee_dump = eee_dump,
96};
97
developerfd40db22021-04-29 10:08:25 +080098static int getnext(char *src, int separator, char *dest)
99{
100 char *c;
101 int len;
102
103 if ((src == NULL) || (dest == NULL))
104 return -1;
105
106 c = strchr(src, separator);
107 if (c == NULL)
108 return -1;
109
110 len = c - src;
111 strncpy(dest, src, len);
112 dest[len] = '\0';
113 return len + 1;
114}
115
116static int str_to_ip(unsigned int *ip, char *str)
117{
118 int i;
119 int len;
120 char *ptr = str;
121 char buf[128];
122 unsigned char c[4];
123
124 for (i = 0; i < 3; ++i) {
125 if ((len = getnext(ptr, '.', buf)) == -1)
126 return 1;
127 c[i] = atoi(buf);
128 ptr += len;
129 }
130 c[3] = atoi(ptr);
131 *ip = (c[0] << 24) + (c[1] << 16) + (c[2] << 8) + c[3];
132 return 0;
133}
134
135/*convert IP address from number to string */
136static void ip_to_str(char *str, unsigned int ip)
137{
138 unsigned char *ptr = (unsigned char *)&ip;
139 unsigned char c[4];
140
141 c[0] = *(ptr);
142 c[1] = *(ptr + 1);
143 c[2] = *(ptr + 2);
144 c[3] = *(ptr + 3);
developerbe40a9e2024-03-07 21:44:26 +0800145 /*sprintf(str, "%d.%d.%d.%d", c[0], c[1], c[2], c[3]); */
developerfd40db22021-04-29 10:08:25 +0800146 sprintf(str, "%d.%d.%d.%d", c[3], c[2], c[1], c[0]);
147}
148
149int reg_read(unsigned int offset, unsigned int *value)
150{
151 int ret = -1;
152
153 if (nl_init_flag == true) {
154 ret = reg_read_netlink(attres, offset, value);
155 } else {
156 if (attres->dev_id == -1)
157 ret = reg_read_ioctl(offset, value);
158 }
159 if (ret < 0) {
160 printf("Read fail\n");
161 *value = 0;
162 return ret;
163 }
164
165 return 0;
166}
167
168int reg_write(unsigned int offset, unsigned int value)
169{
170 int ret = -1;
171
172 if (nl_init_flag == true) {
173 ret = reg_write_netlink(attres, offset, value);
174 } else {
175 if (attres->dev_id == -1)
176 ret = reg_write_ioctl(offset, value);
177 }
178 if (ret < 0) {
179 printf("Write fail\n");
180 exit_free();
181 exit(0);
182 }
183 return 0;
184}
185
186int mii_mgr_read(unsigned int port_num, unsigned int reg, unsigned int *value)
187{
188 int ret;
189
190 if (port_num > 31) {
191 printf("Invalid Port or PHY addr \n");
192 return -1;
193 }
194
195 if (nl_init_flag == true)
196 ret = phy_cl22_read_netlink(attres, port_num, reg, value);
197 else
198 ret = mii_mgr_cl22_read_ioctl(port_num, reg, value);
199
200 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800201 printf("Phy cl22 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800202 exit_free();
203 exit(0);
204 }
205
206 return 0;
207}
208
209int mii_mgr_write(unsigned int port_num, unsigned int reg, unsigned int value)
210{
211 int ret;
212
213 if (port_num > 31) {
214 printf("Invalid Port or PHY addr \n");
215 return -1;
216 }
217
218 if (nl_init_flag == true)
219 ret = phy_cl22_write_netlink(attres, port_num, reg, value);
220 else
221 ret = mii_mgr_cl22_write_ioctl(port_num, reg, value);
222
223 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800224 printf("Phy cl22 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800225 exit_free();
226 exit(0);
227 }
228
229 return 0;
230}
231
developerbe40a9e2024-03-07 21:44:26 +0800232int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg,
233 unsigned int *value)
developerfd40db22021-04-29 10:08:25 +0800234{
235 int ret;
236
237 if (port_num > 31) {
238 printf("Invalid Port or PHY addr \n");
239 return -1;
240 }
241
242 if (nl_init_flag == true)
243 ret = phy_cl45_read_netlink(attres, port_num, dev, reg, value);
244 else
245 ret = mii_mgr_cl45_read_ioctl(port_num, dev, reg, value);
246
247 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800248 printf("Phy cl45 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800249 exit_free();
250 exit(0);
251 }
252
253 return 0;
254}
255
developerbe40a9e2024-03-07 21:44:26 +0800256int mii_mgr_c45_write(unsigned int port_num, unsigned int dev, unsigned int reg,
257 unsigned int value)
developerfd40db22021-04-29 10:08:25 +0800258{
259 int ret;
260
261 if (port_num > 31) {
262 printf("Invalid Port or PHY addr \n");
263 return -1;
264 }
265
266 if (nl_init_flag == true)
267 ret = phy_cl45_write_netlink(attres, port_num, dev, reg, value);
268 else
269 ret = mii_mgr_cl45_write_ioctl(port_num, dev, reg, value);
270
271 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800272 printf("Phy cl45 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800273 exit_free();
274 exit(0);
275 }
276
277 return 0;
278}
279
developerfd40db22021-04-29 10:08:25 +0800280int phy_dump(int phy_addr)
281{
282 int ret;
283
284 if (nl_init_flag == true)
285 ret = phy_dump_netlink(attres, phy_addr);
286 else
287 ret = phy_dump_ioctl(phy_addr);
288
289 if (ret < 0) {
290 printf("Phy dump fail\n");
291 exit_free();
292 exit(0);
293 }
294
295 return 0;
296}
297
298void phy_crossover(int argc, char *argv[])
299{
300 unsigned int port_num = strtoul(argv[2], NULL, 10);
developerbe40a9e2024-03-07 21:44:26 +0800301 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +0800302 int ret;
303
304 if (port_num > 4) {
305 printf("invaild value, port_name:0~4\n");
306 return;
307 }
308
309 if (nl_init_flag == true)
developerbe40a9e2024-03-07 21:44:26 +0800310 ret =
311 phy_cl45_read_netlink(attres, port_num, 0x1E,
312 MT7530_T10_TEST_CONTROL, &value);
developerfd40db22021-04-29 10:08:25 +0800313 else
developerbe40a9e2024-03-07 21:44:26 +0800314 ret =
315 mii_mgr_cl45_read_ioctl(port_num, 0x1E,
316 MT7530_T10_TEST_CONTROL, &value);
developerfd40db22021-04-29 10:08:25 +0800317 if (ret < 0) {
318 printf("phy_cl45 read fail\n");
319 exit_free();
320 exit(0);
321 }
322
323 printf("mii_mgr_cl45:");
developerbe40a9e2024-03-07 21:44:26 +0800324 printf("Read: port#=%d, device=0x%x, reg=0x%x, value=0x%x\n", port_num,
325 0x1E, MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800326
developerbe40a9e2024-03-07 21:44:26 +0800327 if (!strncmp(argv[3], "auto", 5)) {
developerfd40db22021-04-29 10:08:25 +0800328 value &= (~(0x3 << 3));
329 } else if (!strncmp(argv[3], "mdi", 4)) {
330 value &= (~(0x3 << 3));
331 value |= (0x2 << 3);
332 } else if (!strncmp(argv[3], "mdix", 5)) {
333 value |= (0x3 << 3);
334 } else {
335 printf("invaild parameter\n");
336 return;
337 }
developerbe40a9e2024-03-07 21:44:26 +0800338 printf("Write: 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
341 if (nl_init_flag == true)
developerbe40a9e2024-03-07 21:44:26 +0800342 ret =
343 phy_cl45_write_netlink(attres, port_num, 0x1E,
344 MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800345 else
developerbe40a9e2024-03-07 21:44:26 +0800346 ret =
347 mii_mgr_cl45_write_ioctl(port_num, 0x1E,
348 MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800349
350 if (ret < 0) {
351 printf("phy_cl45 write fail\n");
352 exit_free();
353 exit(0);
354 }
355}
356
357int rw_phy_token_ring(int argc, char *argv[])
358{
359 int ch_addr, node_addr, data_addr;
360 unsigned int tr_reg_control;
361 unsigned int val_l = 0;
362 unsigned int val_h = 0;
363 unsigned int port_num;
364
365 if (argc < 4)
366 return -1;
367
368 if (argv[2][0] == 'r') {
369 if (argc != 7)
370 return -1;
developerbe40a9e2024-03-07 21:44:26 +0800371 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
developerfd40db22021-04-29 10:08:25 +0800372 port_num = strtoul(argv[3], NULL, 0);
373 if (port_num > MAX_PORT) {
374 printf("Illegal port index and port:0~6\n");
375 return -1;
376 }
377 ch_addr = strtoul(argv[4], NULL, 0);
378 node_addr = strtoul(argv[5], NULL, 0);
379 data_addr = strtoul(argv[6], NULL, 0);
developerbe40a9e2024-03-07 21:44:26 +0800380 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n",
381 port_num, ch_addr, node_addr, data_addr);
382 tr_reg_control =
383 (1 << 15) | (1 << 13) | (ch_addr << 11) | (node_addr << 7) |
384 (data_addr << 1);
385 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
developerfd40db22021-04-29 10:08:25 +0800386 mii_mgr_read(port_num, 17, &val_l);
387 mii_mgr_read(port_num, 18, &val_h);
developerbe40a9e2024-03-07 21:44:26 +0800388 printf
389 ("switch trreg read tr_reg_control=%x, value_H=%x, value_L=%x\n",
390 tr_reg_control, val_h, val_l);
developerfd40db22021-04-29 10:08:25 +0800391 } else if (argv[2][0] == 'w') {
392 if (argc != 9)
393 return -1;
developerbe40a9e2024-03-07 21:44:26 +0800394 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
developerfd40db22021-04-29 10:08:25 +0800395 port_num = strtoul(argv[3], NULL, 0);
396 if (port_num > MAX_PORT) {
397 printf("\n**Illegal port index and port:0~6\n");
398 return -1;
399 }
400 ch_addr = strtoul(argv[4], NULL, 0);
401 node_addr = strtoul(argv[5], NULL, 0);
402 data_addr = strtoul(argv[6], NULL, 0);
403 val_h = strtoul(argv[7], NULL, 0);
404 val_l = strtoul(argv[8], NULL, 0);
developerbe40a9e2024-03-07 21:44:26 +0800405 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n",
406 port_num, ch_addr, node_addr, data_addr);
407 tr_reg_control =
408 (1 << 15) | (0 << 13) | (ch_addr << 11) | (node_addr << 7) |
409 (data_addr << 1);
developerfd40db22021-04-29 10:08:25 +0800410 mii_mgr_write(port_num, 17, val_l);
411 mii_mgr_write(port_num, 18, val_h);
developerbe40a9e2024-03-07 21:44:26 +0800412 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
413 printf
414 ("switch trreg Write tr_reg_control=%x, value_H=%x, value_L=%x\n",
415 tr_reg_control, val_h, val_l);
developerfd40db22021-04-29 10:08:25 +0800416 } else
417 return -1;
418 return 0;
419}
420
developerbe40a9e2024-03-07 21:44:26 +0800421void write_acl_table(unsigned char tbl_idx, unsigned int vawd1,
422 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800423{
developerbe40a9e2024-03-07 21:44:26 +0800424 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800425 unsigned int max_index;
426
developer8c3871b2022-07-01 14:07:53 +0800427 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800428 max_index = 256;
429 else
430 max_index = 64;
431
432 printf("Pattern_acl_tbl_idx:%d\n", tbl_idx);
433
434 if (tbl_idx >= max_index) {
435 printf(HELP_ACL_ACL_TBL_ADD);
436 return;
437 }
438
439 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800440 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800441 reg_read(reg, &value);
442 if ((value & REG_VTCR_BUSY_MASK) == 0) {
443 break;
444 }
445 }
446 reg_write(REG_VAWD1_ADDR, vawd1);
447 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
448 reg_write(REG_VAWD2_ADDR, vawd2);
449 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
450 reg = REG_VTCR_ADDR;
451 value = REG_VTCR_BUSY_MASK | (0x05 << REG_VTCR_FUNC_OFFT) | tbl_idx;
452 reg_write(reg, value);
453 printf("write reg: %x, value: %x\n", reg, value);
454
developerbe40a9e2024-03-07 21:44:26 +0800455 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800456 reg_read(reg, &value);
457 if ((value & REG_VTCR_BUSY_MASK) == 0)
458 break;
459 }
460}
461
462void acl_table_add(int argc, char *argv[])
463{
developerbe40a9e2024-03-07 21:44:26 +0800464 unsigned int vawd1 = 0, vawd2 = 0;
465 unsigned char tbl_idx = 0;
developerfd40db22021-04-29 10:08:25 +0800466
467 tbl_idx = atoi(argv[3]);
468 vawd1 = strtoul(argv[4], (char **)NULL, 16);
469 vawd2 = strtoul(argv[5], (char **)NULL, 16);
470 write_acl_table(tbl_idx, vawd1, vawd2);
471}
472
developerbe40a9e2024-03-07 21:44:26 +0800473void write_acl_mask_table(unsigned char tbl_idx, unsigned int vawd1,
474 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800475{
developerbe40a9e2024-03-07 21:44:26 +0800476 unsigned int value = 0, reg = 0;
477 unsigned int max_index = 0;
developerfd40db22021-04-29 10:08:25 +0800478
developer8c3871b2022-07-01 14:07:53 +0800479 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800480 max_index = 128;
481 else
482 max_index = 32;
483
484 printf("Rule_mask_tbl_idx:%d\n", tbl_idx);
485
486 if (tbl_idx >= max_index) {
487 printf(HELP_ACL_MASK_TBL_ADD);
488 return;
489 }
490 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800491 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800492 reg_read(reg, &value);
493 if ((value & REG_VTCR_BUSY_MASK) == 0)
494 break;
495 }
496 reg_write(REG_VAWD1_ADDR, vawd1);
497 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
498 reg_write(REG_VAWD2_ADDR, vawd2);
499 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
500 reg = REG_VTCR_ADDR;
501 value = REG_VTCR_BUSY_MASK | (0x09 << REG_VTCR_FUNC_OFFT) | tbl_idx;
502 reg_write(reg, value);
503 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +0800504 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800505 reg_read(reg, &value);
506 if ((value & REG_VTCR_BUSY_MASK) == 0)
507 break;
508 }
509}
510
511void acl_mask_table_add(int argc, char *argv[])
512{
developerbe40a9e2024-03-07 21:44:26 +0800513 unsigned int vawd1 = 0, vawd2 = 0;
514 unsigned char tbl_idx = 0;
developerfd40db22021-04-29 10:08:25 +0800515
516 tbl_idx = atoi(argv[3]);
517 vawd1 = strtoul(argv[4], (char **)NULL, 16);
518 vawd2 = strtoul(argv[5], (char **)NULL, 16);
519 write_acl_mask_table(tbl_idx, vawd1, vawd2);
520}
521
developerbe40a9e2024-03-07 21:44:26 +0800522void write_acl_rule_table(unsigned char tbl_idx, unsigned int vawd1,
523 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800524{
developerbe40a9e2024-03-07 21:44:26 +0800525 unsigned int value = 0, reg = 0;
526 unsigned int max_index = 0;
developerfd40db22021-04-29 10:08:25 +0800527
developer8c3871b2022-07-01 14:07:53 +0800528 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800529 max_index = 128;
530 else
531 max_index = 32;
532
533 printf("Rule_control_tbl_idx:%d\n", tbl_idx);
534
developerbe40a9e2024-03-07 21:44:26 +0800535 if (tbl_idx >= max_index) { /* Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +0800536 printf(HELP_ACL_RULE_TBL_ADD);
537 return;
538 }
539 reg = REG_VTCR_ADDR;
540
developerbe40a9e2024-03-07 21:44:26 +0800541 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800542 reg_read(reg, &value);
543 if ((value & REG_VTCR_BUSY_MASK) == 0) {
544 break;
545 }
546 }
547 reg_write(REG_VAWD1_ADDR, vawd1);
548 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
549 reg_write(REG_VAWD2_ADDR, vawd2);
550 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
551 reg = REG_VTCR_ADDR;
552 value = REG_VTCR_BUSY_MASK | (0x0B << REG_VTCR_FUNC_OFFT) | tbl_idx;
553 reg_write(reg, value);
554 printf("write reg: %x, value: %x\n", reg, value);
555
developerbe40a9e2024-03-07 21:44:26 +0800556 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800557 reg_read(reg, &value);
558 if ((value & REG_VTCR_BUSY_MASK) == 0) {
559 break;
560 }
561 }
562}
563
564void acl_rule_table_add(int argc, char *argv[])
565{
developerbe40a9e2024-03-07 21:44:26 +0800566 unsigned int vawd1 = 0, vawd2 = 0;
567 unsigned char tbl_idx = 0;
developerfd40db22021-04-29 10:08:25 +0800568
569 tbl_idx = atoi(argv[3]);
570 vawd1 = strtoul(argv[4], (char **)NULL, 16);
571 vawd2 = strtoul(argv[5], (char **)NULL, 16);
572 write_acl_rule_table(tbl_idx, vawd1, vawd2);
573}
574
developerbe40a9e2024-03-07 21:44:26 +0800575void write_rate_table(unsigned char tbl_idx, unsigned int vawd1,
576 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800577{
developerbe40a9e2024-03-07 21:44:26 +0800578 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800579 unsigned int max_index = 32;
580
581 printf("Rule_action_tbl_idx:%d\n", tbl_idx);
582
583 if (tbl_idx >= max_index) {
584 printf(HELP_ACL_RATE_TBL_ADD);
585 return;
586 }
587
588 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800589 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800590 reg_read(reg, &value);
591 if ((value & REG_VTCR_BUSY_MASK) == 0)
592 break;
593 }
594
595 reg_write(REG_VAWD1_ADDR, vawd1);
596 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
597 reg_write(REG_VAWD2_ADDR, vawd2);
598 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
599 reg = REG_VTCR_ADDR;
600 value = REG_VTCR_BUSY_MASK | (0x0D << REG_VTCR_FUNC_OFFT) | tbl_idx;
601 reg_write(reg, value);
602 printf("write reg: %x, value: %x\n", reg, value);
603
developerbe40a9e2024-03-07 21:44:26 +0800604 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800605 reg_read(reg, &value);
606 if ((value & REG_VTCR_BUSY_MASK) == 0)
607 break;
608 }
609}
610
611void acl_rate_table_add(int argc, char *argv[])
612{
developerbe40a9e2024-03-07 21:44:26 +0800613 unsigned int vawd1 = 0, vawd2 = 0;
614 unsigned char tbl_idx = 0;
developerfd40db22021-04-29 10:08:25 +0800615
616 tbl_idx = atoi(argv[3]);
617 vawd1 = strtoul(argv[4], (char **)NULL, 16);
618 vawd2 = strtoul(argv[5], (char **)NULL, 16);
619
620 write_rate_table(tbl_idx, vawd1, vawd2);
621}
622
developerbe40a9e2024-03-07 21:44:26 +0800623void write_trTCM_table(unsigned char tbl_idx, unsigned int vawd1,
624 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800625{
developerbe40a9e2024-03-07 21:44:26 +0800626 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800627 unsigned int max_index = 32;
628
629 printf("trTCM_tbl_idx:%d\n", tbl_idx);
630
631 if (tbl_idx >= max_index) {
632 printf(HELP_ACL_TRTCM_TBL_ADD);
633 return;
634 }
635
636 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800637 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800638 reg_read(reg, &value);
639 if ((value & REG_VTCR_BUSY_MASK) == 0)
640 break;
641 }
642
643 reg_write(REG_VAWD1_ADDR, vawd1);
644 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
645 reg_write(REG_VAWD2_ADDR, vawd2);
646 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
647 reg = REG_VTCR_ADDR;
648 value = REG_VTCR_BUSY_MASK | (0x07 << REG_VTCR_FUNC_OFFT) | tbl_idx;
649 reg_write(reg, value);
650 printf("write reg: %x, value: %x\n", reg, value);
651
developerbe40a9e2024-03-07 21:44:26 +0800652 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800653 reg_read(reg, &value);
654 if ((value & REG_VTCR_BUSY_MASK) == 0)
655 break;
656 }
657}
658
developerbe40a9e2024-03-07 21:44:26 +0800659int acl_parameters_pre_del(int len1, int len2, int argc, char *argv[],
660 int *port)
developerfd40db22021-04-29 10:08:25 +0800661{
developerbe40a9e2024-03-07 21:44:26 +0800662 int i = 0;
developerfd40db22021-04-29 10:08:25 +0800663
664 *port = 0;
665 if (argc < len1) {
666 printf("insufficient arguments!\n");
667 return -1;
668 }
669
developerbe40a9e2024-03-07 21:44:26 +0800670 if (len2 == 12) {
developerfd40db22021-04-29 10:08:25 +0800671 if (!argv[4] || strlen(argv[4]) != len2) {
developerbe40a9e2024-03-07 21:44:26 +0800672 printf
673 ("The [%s] format error, should be of length %d\n",
674 argv[4], len2);
developerfd40db22021-04-29 10:08:25 +0800675 return -1;
676 }
677 }
678
679 if (!argv[5] || strlen(argv[5]) != 8) {
680 printf("portsmap format error, should be of length 7\n");
681 return -1;
682 }
683
684 for (i = 0; i < 7; i++) {
685 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +0800686 printf
687 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +0800688 return -1;
689 }
690 *port += (argv[5][i] - '0') * (1 << i);
691 }
692 return 0;
693}
694
developerbe40a9e2024-03-07 21:44:26 +0800695void acl_compare_pattern(int ports, int comparion, int base, int word,
696 unsigned char table_index)
developerfd40db22021-04-29 10:08:25 +0800697{
developerbe40a9e2024-03-07 21:44:26 +0800698 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +0800699
developerbe40a9e2024-03-07 21:44:26 +0800700 comparion |= 0xffff0000; //compare mask
developerfd40db22021-04-29 10:08:25 +0800701
developerbe40a9e2024-03-07 21:44:26 +0800702 value = ports << 8; //w_port_map
703 value |= 0x1 << 19; //enable
704 value |= base << 16; //mac header
705 value |= word << 1; //word offset
developerfd40db22021-04-29 10:08:25 +0800706
707 write_acl_table(table_index, comparion, value);
708}
709
710void acl_mac_add(int argc, char *argv[])
711{
developerbe40a9e2024-03-07 21:44:26 +0800712 unsigned int value = 0;
713 int ports = 0;
developerfd40db22021-04-29 10:08:25 +0800714 char tmpstr[5];
715 int ret;
716
717 ret = acl_parameters_pre_del(6, 12, argc, argv, &ports);
718 if (ret < 0)
719 return;
developerbe40a9e2024-03-07 21:44:26 +0800720 /* Set pattern */
developerfd40db22021-04-29 10:08:25 +0800721 strncpy(tmpstr, argv[4], 4);
722 tmpstr[4] = '\0';
723 value = strtoul(tmpstr, NULL, 16);
724 acl_compare_pattern(ports, value, 0x0, 0, 0);
725
726 strncpy(tmpstr, argv[4] + 4, 4);
727 tmpstr[4] = '\0';
728 value = strtoul(tmpstr, NULL, 16);
729 acl_compare_pattern(ports, value, 0x0, 1, 1);
730
731 strncpy(tmpstr, argv[4] + 8, 4);
732 tmpstr[4] = '\0';
733 value = strtoul(tmpstr, NULL, 16);
734 acl_compare_pattern(ports, value, 0x0, 2, 2);
735
736 //set mask
developerbe40a9e2024-03-07 21:44:26 +0800737 write_acl_mask_table(0, 0x7, 0);
developerfd40db22021-04-29 10:08:25 +0800738
739 //set action
developerbe40a9e2024-03-07 21:44:26 +0800740 value = 0x7; //drop
741 value |= 1 << 28; //acl intterupt enable
742 value |= 1 << 27; //acl hit count
743 value |= 2 << 24; //acl hit count group index (0~3)
744 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +0800745}
746
747void acl_dip_meter(int argc, char *argv[])
748{
developerbe40a9e2024-03-07 21:44:26 +0800749 unsigned int value = 0, ip_value = 0, meter = 0;
750 int ports = 0;
developerfd40db22021-04-29 10:08:25 +0800751 int ret;
752
753 ip_value = 0;
754 ret = acl_parameters_pre_del(7, -1, argc, argv, &ports);
755 if (ret < 0)
756 return;
757
758 str_to_ip(&ip_value, argv[4]);
759 //set pattern
760 value = (ip_value >> 16);
761 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
762
763 //set pattern
764 value = (ip_value & 0xffff);
765 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
766
767 //set mask
developerbe40a9e2024-03-07 21:44:26 +0800768 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800769
770 //set action
771 meter = strtoul(argv[6], NULL, 0);
772 if (((chip_name == 0x7530) && (meter > 1000000)) ||
developerbe40a9e2024-03-07 21:44:26 +0800773 ((chip_name == 0x7531) && (meter > 2500000)) ||
774 ((chip_name == 0x7988) && (meter > 4000000))) {
developer8c3871b2022-07-01 14:07:53 +0800775 printf("\n**Illegal meter input, and 7530: 0~1000000Kpbs, 7531: 0~2500000Kpbs, 7988: 0~4000000Kpbs**\n");
developerfd40db22021-04-29 10:08:25 +0800776 return;
777 }
developer8c3871b2022-07-01 14:07:53 +0800778 if (((chip_name == 0x7531 || chip_name == 0x7988) && (meter > 1000000))) {
developerbe40a9e2024-03-07 21:44:26 +0800779 reg_read(0xc, &value);
developerfd40db22021-04-29 10:08:25 +0800780 value |= 0x1 << 30;
developerbe40a9e2024-03-07 21:44:26 +0800781 reg_write(0xC, value);
782 printf("AGC: 0x%x\n", value);
783 value = meter / 1000; //uint is 1Mbps
developerfd40db22021-04-29 10:08:25 +0800784 } else {
developerbe40a9e2024-03-07 21:44:26 +0800785 reg_read(0xc, &value);
developerfd40db22021-04-29 10:08:25 +0800786 value &= ~(0x1 << 30);
developerbe40a9e2024-03-07 21:44:26 +0800787 reg_write(0xC, value);
788 printf("AGC: 0x%x\n", value);
789 value = meter >> 6; //uint is 64Kbps
developerfd40db22021-04-29 10:08:25 +0800790 }
developerbe40a9e2024-03-07 21:44:26 +0800791 value |= 0x1 << 15; //enable rate control
792 printf("Acl rate control:0x%x\n", value);
developerfd40db22021-04-29 10:08:25 +0800793 write_rate_table(0, value, 0);
794}
795
796void acl_dip_trtcm(int argc, char *argv[])
797{
798 unsigned int value, value2, ip_value;
799 unsigned int CIR, CBS, PIR, PBS;
800 int ports;
801 int ret;
802
803 ip_value = 0;
804 ret = acl_parameters_pre_del(10, -1, argc, argv, &ports);
805 if (ret < 0)
806 return;
807
808 str_to_ip(&ip_value, argv[4]);
809 //set pattern
810 value = (ip_value >> 16);
811 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
812
813 //set pattern
814 value = (ip_value & 0xffff);
815 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
816
817 //set CBS PBS
818 CIR = strtoul(argv[6], NULL, 0);
819 CBS = strtoul(argv[7], NULL, 0);
820 PIR = strtoul(argv[8], NULL, 0);
821 PBS = strtoul(argv[9], NULL, 0);
822
developerbe40a9e2024-03-07 21:44:26 +0800823 if (CIR > 65535 * 64 || CBS > 65535 || PIR > 65535 * 64 || PBS > 65535) {
developerfd40db22021-04-29 10:08:25 +0800824 printf("\n**Illegal input parameters**\n");
825 return;
826 }
827
developerbe40a9e2024-03-07 21:44:26 +0800828 value = CBS << 16; //bit16~31
829 value |= PBS; //bit0~15
830 //value |= 1;//valid
developerfd40db22021-04-29 10:08:25 +0800831 CIR = CIR >> 6;
832 PIR = PIR >> 6;
833
developerbe40a9e2024-03-07 21:44:26 +0800834 value2 = CIR << 16; //bit16~31
835 value2 |= PIR; //bit0~15
836 write_trTCM_table(0, value, value2);
developerfd40db22021-04-29 10:08:25 +0800837
838 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800839 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800840
841 //set action
developerbe40a9e2024-03-07 21:44:26 +0800842 value = 0x1 << (11 + 1); //TrTCM green meter#0 Low drop
843 value |= 0x2 << (8 + 1); //TrTCM yellow meter#0 Med drop
844 value |= 0x3 << (5 + 1); //TrTCM red meter#0 Hig drop
845 value |= 0x1 << 0; //TrTCM drop pcd select
846 write_acl_rule_table(0, 0, value);
developerfd40db22021-04-29 10:08:25 +0800847}
848
849void acl_ethertype(int argc, char *argv[])
850{
851 unsigned int value, ethertype;
852 int ports;
853 int ret;
854
855 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
856 if (ret < 0)
857 return;
developerbe40a9e2024-03-07 21:44:26 +0800858 printf("ports:0x%x\n", ports);
developerfd40db22021-04-29 10:08:25 +0800859 ethertype = strtoul(argv[4], NULL, 16);
860 //set pattern
861 value = ethertype;
862 acl_compare_pattern(ports, value, 0x0, 0x6, 0);
863
864 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800865 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +0800866
867 //set action(drop)
developerbe40a9e2024-03-07 21:44:26 +0800868 value = 0x7; //default. Nodrop
869 value |= 1 << 28; //acl intterupt enable
870 value |= 1 << 27; //acl hit count
developerfd40db22021-04-29 10:08:25 +0800871
developerbe40a9e2024-03-07 21:44:26 +0800872 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +0800873}
874
875void acl_dip_modify(int argc, char *argv[])
876{
877 unsigned int value, ip_value;
878 int ports;
879 int priority;
880 int ret;
881
882 ip_value = 0;
883 priority = strtoul(argv[6], NULL, 16);
884 if (priority < 0 || priority > 7) {
885 printf("\n**Illegal priority value!**\n");
886 return;
887 }
888
889 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
890 if (ret < 0)
891 return;
892
893 str_to_ip(&ip_value, argv[4]);
894 //set pattern
895 value = (ip_value >> 16);
896 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
897
898 //set pattern
899 value = (ip_value & 0xffff);
900 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
901
902 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800903 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800904
905 //set action
developerbe40a9e2024-03-07 21:44:26 +0800906 value = 0x0; //default. Nodrop
907 value |= 1 << 28; //acl intterupt enable
908 value |= 1 << 27; //acl hit count
909 value |= priority << 4; //acl UP
910 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +0800911}
912
913void acl_dip_pppoe(int argc, char *argv[])
914{
915 unsigned int value, ip_value;
916 int ports;
917 int ret;
918
919 ip_value = 0;
920 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
921 if (ret < 0)
922 return;
923
924 str_to_ip(&ip_value, argv[4]);
925 //set pattern
926 value = (ip_value >> 16);
927 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
928
929 //set pattern
930 value = (ip_value & 0xffff);
931 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
932
933 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800934 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800935
936 //set action
developerbe40a9e2024-03-07 21:44:26 +0800937 value = 0x0; //default. Nodrop
938 value |= 1 << 28; //acl intterupt enable
939 value |= 1 << 27; //acl hit count
940 value |= 1 << 20; //pppoe header remove
941 value |= 1 << 21; //SA MAC SWAP
942 value |= 1 << 22; //DA MAC SWAP
943 write_acl_rule_table(0, value, 7);
developerfd40db22021-04-29 10:08:25 +0800944}
945
946void acl_dip_add(int argc, char *argv[])
947{
948 unsigned int value, ip_value;
949 int ports;
950 int ret;
951
952 ip_value = 0;
953 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
954 if (ret < 0)
955 return;
956
957 str_to_ip(&ip_value, argv[4]);
958 //set pattern
959 value = (ip_value >> 16);
960 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
961
962 //set pattern
963 value = (ip_value & 0xffff);
964 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
965
966 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800967 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800968
969 //set action
970 //value = 0x0; //default
developerbe40a9e2024-03-07 21:44:26 +0800971 value = 0x7; //drop
972 value |= 1 << 28; //acl intterupt enable
973 value |= 1 << 27; //acl hit count
974 value |= 2 << 24; //acl hit count group index (0~3)
975 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +0800976}
977
978void acl_l4_add(int argc, char *argv[])
979{
developerbe40a9e2024-03-07 21:44:26 +0800980 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +0800981 int ports;
982 int ret;
983
984 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
985 if (ret < 0)
986 return;
987
988 //set pattern
989 value = strtoul(argv[4], NULL, 16);
990 acl_compare_pattern(ports, value, 0x5, 0x0, 0);
991
992 //set rue mask
developerbe40a9e2024-03-07 21:44:26 +0800993 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +0800994 //set action
developerbe40a9e2024-03-07 21:44:26 +0800995 value = 0x7; //drop
996 //value |= 1;//valid
997 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +0800998}
999
1000void acl_sp_add(int argc, char *argv[])
1001{
developerbe40a9e2024-03-07 21:44:26 +08001002 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001003 int ports;
1004 int ret;
1005
1006 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1007 if (ret < 0)
1008 return;
1009 //set pattern
1010 value = strtoul(argv[4], NULL, 0);
1011 acl_compare_pattern(ports, value, 0x4, 0x0, 0);
1012
1013 //set rue mask
developerbe40a9e2024-03-07 21:44:26 +08001014 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +08001015
1016 //set action
developerbe40a9e2024-03-07 21:44:26 +08001017 value = 0x7; //drop
1018 //value |= 1;//valid
1019 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001020}
1021
1022void acl_port_enable(int argc, char *argv[])
1023{
developerbe40a9e2024-03-07 21:44:26 +08001024 unsigned int value = 0, reg = 0;
1025 unsigned char acl_port = 0, acl_en = 0;
developerfd40db22021-04-29 10:08:25 +08001026
1027 acl_port = atoi(argv[3]);
1028 acl_en = atoi(argv[4]);
1029
1030 printf("acl_port:%d, acl_en:%d\n", acl_port, acl_en);
1031
developerbe40a9e2024-03-07 21:44:26 +08001032 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08001033 if ((acl_port > SWITCH_MAX_PORT) || (acl_en > 1)) {
1034 printf(HELP_ACL_SETPORTEN);
1035 return;
1036 }
1037
developerbe40a9e2024-03-07 21:44:26 +08001038 reg = REG_PCR_P0_ADDR + (0x100 * acl_port); // 0x2004[10]
developerfd40db22021-04-29 10:08:25 +08001039 reg_read(reg, &value);
1040 value &= (~REG_PORT_ACL_EN_MASK);
1041 value |= (acl_en << REG_PORT_ACL_EN_OFFT);
1042
1043 printf("write reg: %x, value: %x\n", reg, value);
1044 reg_write(reg, value);
1045}
1046
1047static void dip_dump_internal(int type)
1048{
1049 unsigned int i, j, value, mac, mac2, value2;
developerbe40a9e2024-03-07 21:44:26 +08001050 char tmpstr[16] = { 0 };
developerfd40db22021-04-29 10:08:25 +08001051 int table_size = 0;
1052 int hit_value1 = 0;
1053 int hit_value2 = 0;
1054
developerbe40a9e2024-03-07 21:44:26 +08001055 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001056 table_size = 0x800;
developerbe40a9e2024-03-07 21:44:26 +08001057 reg_write(REG_ATC_ADDR, 0x8104); //dip search command
1058 } else {
developerfd40db22021-04-29 10:08:25 +08001059 table_size = 0x40;
developerbe40a9e2024-03-07 21:44:26 +08001060 reg_write(REG_ATC_ADDR, 0x811c); //dip search command
developerfd40db22021-04-29 10:08:25 +08001061 }
developerbe40a9e2024-03-07 21:44:26 +08001062 printf
1063 ("hash port(0:6) rsp_cnt flag timer dip-address ATRD\n");
developerfd40db22021-04-29 10:08:25 +08001064 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001065 while (1) {
developerfd40db22021-04-29 10:08:25 +08001066 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001067 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001068 hit_value1 = value & (0x1 << 13);
1069 hit_value2 = 1;
developerbe40a9e2024-03-07 21:44:26 +08001070 } else {
developerfd40db22021-04-29 10:08:25 +08001071 hit_value1 = value & (0x1 << 13);
1072 hit_value2 = value & (0x1 << 28);
1073 }
1074
developerbe40a9e2024-03-07 21:44:26 +08001075 if (hit_value1 && hit_value2) { //search_rdy
developerfd40db22021-04-29 10:08:25 +08001076 reg_read(REG_ATRD_ADDR, &value2);
1077 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1078
developerbe40a9e2024-03-07 21:44:26 +08001079 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1080 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001081 printf("%c", (j & 0x01) ? '1' : '-');
1082 printf("%c", (j & 0x02) ? '1' : '-');
1083 printf("%c", (j & 0x04) ? '1' : '-');
1084 printf("%c ", (j & 0x08) ? '1' : '-');
1085 printf("%c", (j & 0x10) ? '1' : '-');
1086 printf("%c", (j & 0x20) ? '1' : '-');
1087 printf("%c", (j & 0x40) ? '1' : '-');
1088
1089 reg_read(REG_TSRA2_ADDR, &mac2);
1090
developerbe40a9e2024-03-07 21:44:26 +08001091 printf(" 0x%4x", (mac2 & 0xffff)); //RESP_CNT
1092 printf(" 0x%2x", ((mac2 >> 16) & 0xff)); //RESP_FLAG
1093 printf(" %3d", ((mac2 >> 24) & 0xff)); //RESP_TIMER
1094 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001095 reg_read(REG_TSRA1_ADDR, &mac);
1096 ip_to_str(tmpstr, mac);
1097 printf(" %s", tmpstr);
developerbe40a9e2024-03-07 21:44:26 +08001098 printf(" 0x%8x\n", value2); //ATRD
1099 //printf("%04x", ((mac2 >> 16) & 0xffff));
1100 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
developerfd40db22021-04-29 10:08:25 +08001101 if (value & 0x4000) {
1102 printf("end of table %d\n", i);
1103 return;
1104 }
1105 break;
developerbe40a9e2024-03-07 21:44:26 +08001106 } else if (value & 0x4000) { //at_table_end
1107 printf("found the last entry %d (not ready)\n",
1108 i);
developerfd40db22021-04-29 10:08:25 +08001109 return;
1110 }
1111 usleep(5000);
1112 }
1113
developerbe40a9e2024-03-07 21:44:26 +08001114 if (type == GENERAL_TABLE)
1115 reg_write(REG_ATC_ADDR, 0x8105); //search for next dip address
developerfd40db22021-04-29 10:08:25 +08001116 else
developerbe40a9e2024-03-07 21:44:26 +08001117 reg_write(REG_ATC_ADDR, 0x811d); //search for next dip address
developerfd40db22021-04-29 10:08:25 +08001118 usleep(5000);
1119 }
1120}
1121
developerbe40a9e2024-03-07 21:44:26 +08001122void dip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001123{
1124 dip_dump_internal(GENERAL_TABLE);
1125
1126}
1127
1128void dip_add(int argc, char *argv[])
1129{
1130 unsigned int value = 0;
developerbe40a9e2024-03-07 21:44:26 +08001131 unsigned int i = 0, j = 0;
developerfd40db22021-04-29 10:08:25 +08001132
1133 value = 0;
1134
1135 str_to_ip(&value, argv[3]);
1136
1137 reg_write(REG_ATA1_ADDR, value);
1138 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1139
1140#if 0
1141 reg_write(REG_ATA2_ADDR, value);
1142 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1143#endif
1144 if (!argv[4] || strlen(argv[4]) != 8) {
1145 printf("portmap format error, should be of length 7\n");
1146 return;
1147 }
1148 j = 0;
1149 for (i = 0; i < 7; i++) {
1150 if (argv[4][i] != '0' && argv[4][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001151 printf
1152 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001153 return;
1154 }
1155 j += (argv[4][i] - '0') * (1 << i);
1156 }
developerbe40a9e2024-03-07 21:44:26 +08001157 value = j << 4; //w_port_map
1158 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001159
1160 reg_write(REG_ATWD_ADDR, value);
1161
1162 usleep(5000);
1163 reg_read(REG_ATWD_ADDR, &value);
1164 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1165
developerbe40a9e2024-03-07 21:44:26 +08001166 value = 0x8011; //single w_dip_cmd
developerfd40db22021-04-29 10:08:25 +08001167 reg_write(REG_ATC_ADDR, value);
1168
1169 usleep(1000);
1170
1171 for (i = 0; i < 20; i++) {
1172 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001173 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001174 printf("done.\n");
1175 return;
1176 }
1177 usleep(1000);
1178 }
1179 if (i == 20)
1180 printf("timeout.\n");
1181}
1182
1183void dip_del(int argc, char *argv[])
1184{
1185 unsigned int i, value;
1186
1187 value = 0;
1188 str_to_ip(&value, argv[3]);
1189
1190 reg_write(REG_ATA1_ADDR, value);
1191
1192 value = 0;
1193 reg_write(REG_ATA2_ADDR, value);
1194
developerbe40a9e2024-03-07 21:44:26 +08001195 value = 0; //STATUS=0, delete dip
developerfd40db22021-04-29 10:08:25 +08001196 reg_write(REG_ATWD_ADDR, value);
1197
developerbe40a9e2024-03-07 21:44:26 +08001198 value = 0x8011; //w_dip_cmd
developerfd40db22021-04-29 10:08:25 +08001199 reg_write(REG_ATC_ADDR, value);
1200
1201 for (i = 0; i < 20; i++) {
1202 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001203 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001204 if (argv[1] != NULL)
1205 printf("done.\n");
1206 return;
1207 }
1208 usleep(1000);
1209 }
1210 if (i == 20)
1211 printf("timeout.\n");
1212}
1213
developerbe40a9e2024-03-07 21:44:26 +08001214void dip_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001215{
1216
developerbe40a9e2024-03-07 21:44:26 +08001217 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001218
developerbe40a9e2024-03-07 21:44:26 +08001219 reg_write(REG_ATC_ADDR, 0x8102); //clear all dip
developerfd40db22021-04-29 10:08:25 +08001220 usleep(5000);
1221 reg_read(REG_ATC_ADDR, &value);
1222 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1223}
1224
1225static void sip_dump_internal(int type)
1226{
developerbe40a9e2024-03-07 21:44:26 +08001227 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001228 int table_size = 0;
1229 int hit_value1 = 0;
1230 int hit_value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08001231 char tmpstr[16] = { 0 };
developerfd40db22021-04-29 10:08:25 +08001232
1233 if (type == GENERAL_TABLE) {
1234 table_size = 0x800;
developerbe40a9e2024-03-07 21:44:26 +08001235 reg_write(REG_ATC_ADDR, 0x8204); //sip search command
1236 } else {
developerfd40db22021-04-29 10:08:25 +08001237 table_size = 0x40;
developerbe40a9e2024-03-07 21:44:26 +08001238 reg_write(REG_ATC_ADDR, 0x822c); //sip search command
developerfd40db22021-04-29 10:08:25 +08001239 }
1240 printf("hash port(0:6) dip-address sip-address ATRD\n");
1241 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001242 while (1) {
developerfd40db22021-04-29 10:08:25 +08001243 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001244 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001245 hit_value1 = value & (0x1 << 13);
1246 hit_value2 = 1;
1247 } else {
1248 hit_value1 = value & (0x1 << 13);
1249 hit_value2 = value & (0x1 << 28);
1250 }
1251
developerbe40a9e2024-03-07 21:44:26 +08001252 if (hit_value1 && hit_value2) { //search_rdy
developerfd40db22021-04-29 10:08:25 +08001253 reg_read(REG_ATRD_ADDR, &value2);
1254 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1255
developerbe40a9e2024-03-07 21:44:26 +08001256 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1257 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001258 printf("%c", (j & 0x01) ? '1' : '-');
1259 printf("%c", (j & 0x02) ? '1' : '-');
1260 printf("%c", (j & 0x04) ? '1' : '-');
1261 printf("%c", (j & 0x08) ? '1' : '-');
1262 printf(" %c", (j & 0x10) ? '1' : '-');
1263 printf("%c", (j & 0x20) ? '1' : '-');
1264 printf("%c", (j & 0x40) ? '1' : '-');
1265
1266 reg_read(REG_TSRA2_ADDR, &mac2);
1267
1268 ip_to_str(tmpstr, mac2);
1269 printf(" %s", tmpstr);
1270
1271 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
1272 reg_read(REG_TSRA1_ADDR, &mac);
1273 ip_to_str(tmpstr, mac);
1274 printf(" %s", tmpstr);
1275 printf(" 0x%x\n", value2);
1276 //printf("%04x", ((mac2 >> 16) & 0xffff));
1277 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
1278 if (value & 0x4000) {
1279 printf("end of table %d\n", i);
1280 return;
1281 }
1282 break;
developerbe40a9e2024-03-07 21:44:26 +08001283 } else if (value & 0x4000) { //at_table_end
1284 printf("found the last entry %d (not ready)\n",
1285 i);
developerfd40db22021-04-29 10:08:25 +08001286 return;
1287 }
1288 usleep(5000);
1289 }
1290
developerbe40a9e2024-03-07 21:44:26 +08001291 if (type == GENERAL_TABLE)
1292 reg_write(REG_ATC_ADDR, 0x8205); //search for next sip address
1293 else
1294 reg_write(REG_ATC_ADDR, 0x822d); //search for next sip address
1295 usleep(5000);
developerfd40db22021-04-29 10:08:25 +08001296 }
1297}
1298
developerbe40a9e2024-03-07 21:44:26 +08001299void sip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001300{
1301
1302 sip_dump_internal(GENERAL_TABLE);
1303
1304}
1305
developerfd40db22021-04-29 10:08:25 +08001306void sip_add(int argc, char *argv[])
1307{
developerbe40a9e2024-03-07 21:44:26 +08001308 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001309
1310 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08001311 str_to_ip(&value, argv[3]); //SIP
developerfd40db22021-04-29 10:08:25 +08001312
1313 reg_write(REG_ATA2_ADDR, value);
1314 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1315
1316 value = 0;
1317
developerbe40a9e2024-03-07 21:44:26 +08001318 str_to_ip(&value, argv[4]); //DIP
developerfd40db22021-04-29 10:08:25 +08001319 reg_write(REG_ATA1_ADDR, value);
1320 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1321
1322 if (!argv[5] || strlen(argv[5]) != 8) {
1323 printf("portmap format error, should be of length 7\n");
1324 return;
1325 }
1326 j = 0;
1327 for (i = 0; i < 7; i++) {
1328 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001329 printf
1330 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001331 return;
1332 }
1333 j += (argv[5][i] - '0') * (1 << i);
1334 }
developerbe40a9e2024-03-07 21:44:26 +08001335 value = j << 4; //w_port_map
1336 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001337
1338 reg_write(REG_ATWD_ADDR, value);
1339
1340 usleep(5000);
1341 reg_read(REG_ATWD_ADDR, &value);
1342 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1343
developerbe40a9e2024-03-07 21:44:26 +08001344 value = 0x8021; //single w_sip_cmd
developerfd40db22021-04-29 10:08:25 +08001345 reg_write(REG_ATC_ADDR, value);
1346
1347 usleep(1000);
1348
1349 for (i = 0; i < 20; i++) {
1350 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001351 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001352 printf("done.\n");
1353 return;
1354 }
1355 usleep(1000);
1356 }
1357 if (i == 20)
1358 printf("timeout.\n");
1359}
1360
1361void sip_del(int argc, char *argv[])
1362{
developerbe40a9e2024-03-07 21:44:26 +08001363 unsigned int i = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001364
1365 value = 0;
1366 str_to_ip(&value, argv[3]);
1367
developerbe40a9e2024-03-07 21:44:26 +08001368 reg_write(REG_ATA2_ADDR, value); //SIP
developerfd40db22021-04-29 10:08:25 +08001369
1370 str_to_ip(&value, argv[4]);
developerbe40a9e2024-03-07 21:44:26 +08001371 reg_write(REG_ATA1_ADDR, value); //DIP
developerfd40db22021-04-29 10:08:25 +08001372
developerbe40a9e2024-03-07 21:44:26 +08001373 value = 0; //STATUS=0, delete sip
developerfd40db22021-04-29 10:08:25 +08001374 reg_write(REG_ATWD_ADDR, value);
1375
developerbe40a9e2024-03-07 21:44:26 +08001376 value = 0x8021; //w_sip_cmd
developerfd40db22021-04-29 10:08:25 +08001377 reg_write(REG_ATC_ADDR, value);
1378
1379 for (i = 0; i < 20; i++) {
1380 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001381 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001382 if (argv[1] != NULL)
1383 printf("done.\n");
1384 return;
1385 }
1386 usleep(1000);
1387 }
1388 if (i == 20)
1389 printf("timeout.\n");
1390}
1391
developerbe40a9e2024-03-07 21:44:26 +08001392void sip_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001393{
developerbe40a9e2024-03-07 21:44:26 +08001394 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001395
developerbe40a9e2024-03-07 21:44:26 +08001396 reg_write(REG_ATC_ADDR, 0x8202); //clear all sip
developerfd40db22021-04-29 10:08:25 +08001397 usleep(5000);
1398 reg_read(REG_ATC_ADDR, &value);
1399 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1400}
1401
1402static void table_dump_internal(int type)
1403{
developerbe40a9e2024-03-07 21:44:26 +08001404 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001405 int table_size = 0;
1406 int table_end = 0;
1407 int hit_value1 = 0;
1408 int hit_value2 = 0;
1409
developerbe40a9e2024-03-07 21:44:26 +08001410 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001411 table_size = 0x800;
1412 table_end = 0x7FF;
1413 reg_write(REG_ATC_ADDR, 0x8004);
1414 } else {
1415 table_size = 0x40;
1416 table_end = 0x3F;
1417 reg_write(REG_ATC_ADDR, 0x800C);
1418 }
developerbe40a9e2024-03-07 21:44:26 +08001419 printf
1420 ("hash port(0:6) fid vid age(s) mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001421 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001422 while (1) {
developerfd40db22021-04-29 10:08:25 +08001423 reg_read(REG_ATC_ADDR, &value);
1424 //printf("ATC = 0x%x\n", value);
developerbe40a9e2024-03-07 21:44:26 +08001425 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001426 hit_value1 = value & (0x1 << 13);
1427 hit_value2 = 1;
1428 } else {
1429 hit_value1 = value & (0x1 << 13);
1430 hit_value2 = value & (0x1 << 28);
1431 }
1432
developerbe40a9e2024-03-07 21:44:26 +08001433 if (hit_value1 && hit_value2
1434 && (((value >> 15) & 0x1) == 0)) {
developerfd40db22021-04-29 10:08:25 +08001435 printf("%03x: ", (value >> 16) & 0xfff);
1436 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001437 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001438 printf("%c", (j & 0x01) ? '1' : '-');
1439 printf("%c", (j & 0x02) ? '1' : '-');
1440 printf("%c", (j & 0x04) ? '1' : '-');
1441 printf("%c", (j & 0x08) ? '1' : '-');
1442 printf("%c", (j & 0x10) ? '1' : '-');
1443 printf("%c", (j & 0x20) ? '1' : '-');
1444 printf("%c", (j & 0x40) ? '1' : '-');
1445 printf("%c", (j & 0x80) ? '1' : '-');
1446
1447 reg_read(REG_TSRA2_ADDR, &mac2);
1448
developerbe40a9e2024-03-07 21:44:26 +08001449 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001450 printf(" %4d", (mac2 & 0xfff));
1451 if (((value2 >> 24) & 0xff) == 0xFF)
developerbe40a9e2024-03-07 21:44:26 +08001452 printf(" --- "); //r_age_field:static
developerfd40db22021-04-29 10:08:25 +08001453 else
developerbe40a9e2024-03-07 21:44:26 +08001454 printf(" %5d ", (((value2 >> 24) & 0xff) + 1) * 2); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001455 reg_read(REG_TSRA1_ADDR, &mac);
1456 printf(" %08x", mac);
1457 printf("%04x", ((mac2 >> 16) & 0xffff));
developerbe40a9e2024-03-07 21:44:26 +08001458 printf(" %c",
1459 (((value2 >> 20) & 0x03) ==
1460 0x03) ? 'y' : '-');
1461 printf(" %c\n",
1462 (((value2 >> 23) & 0x01) ==
1463 0x01) ? 'y' : '-');
1464 if ((value & 0x4000)
1465 && (((value >> 16) & 0xfff) == table_end)) {
developerfd40db22021-04-29 10:08:25 +08001466 printf("end of table %d\n", i);
1467 return;
1468 }
1469 break;
developerbe40a9e2024-03-07 21:44:26 +08001470 } else if ((value & 0x4000) && (((value >> 15) & 0x1) == 0) && (((value >> 16) & 0xfff) == table_end)) { //at_table_end
1471 printf("found the last entry %d (not ready)\n",
1472 i);
developerfd40db22021-04-29 10:08:25 +08001473 return;
developerbe40a9e2024-03-07 21:44:26 +08001474 } else
developerfd40db22021-04-29 10:08:25 +08001475 usleep(5);
1476 }
1477
developerbe40a9e2024-03-07 21:44:26 +08001478 if (type == GENERAL_TABLE)
1479 reg_write(REG_ATC_ADDR, 0x8005); //search for next address
1480 else
1481 reg_write(REG_ATC_ADDR, 0x800d); //search for next address
developerfd40db22021-04-29 10:08:25 +08001482 usleep(5);
1483 }
1484}
1485
developerbe40a9e2024-03-07 21:44:26 +08001486void table_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001487{
1488 table_dump_internal(GENERAL_TABLE);
1489
1490}
1491
developerfd40db22021-04-29 10:08:25 +08001492void table_add(int argc, char *argv[])
1493{
developerbe40a9e2024-03-07 21:44:26 +08001494 unsigned int i = 0, j = 0, value = 0, is_filter = 0, is_mymac = 0;
developerfd40db22021-04-29 10:08:25 +08001495 char tmpstr[9];
1496
1497 is_filter = (argv[1][0] == 'f') ? 1 : 0;
1498 is_mymac = (argv[1][0] == 'm') ? 1 : 0;
1499 if (!argv[2] || strlen(argv[2]) != 12) {
1500 printf("MAC address format error, should be of length 12\n");
1501 return;
1502 }
1503 strncpy(tmpstr, argv[2], 8);
1504 tmpstr[8] = '\0';
1505 value = strtoul(tmpstr, NULL, 16);
1506 reg_write(REG_ATA1_ADDR, value);
1507 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1508
1509 strncpy(tmpstr, argv[2] + 8, 4);
1510 tmpstr[4] = '\0';
1511
1512 value = strtoul(tmpstr, NULL, 16);
1513 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001514 value |= (1 << 15); //IVL=1
developerfd40db22021-04-29 10:08:25 +08001515
1516 if (argc > 4) {
1517 j = strtoul(argv[4], NULL, 0);
1518 if (4095 < j) {
1519 printf("wrong vid range, should be within 0~4095\n");
1520 return;
1521 }
developerbe40a9e2024-03-07 21:44:26 +08001522 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001523 }
1524
1525 reg_write(REG_ATA2_ADDR, value);
1526 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1527
1528 if (!argv[3] || strlen(argv[3]) != 8) {
1529 if (is_filter)
1530 argv[3] = "11111111";
1531 else {
1532 printf("portmap format error, should be of length 8\n");
1533 return;
1534 }
1535 }
1536 j = 0;
1537 for (i = 0; i < 7; i++) {
1538 if (argv[3][i] != '0' && argv[3][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001539 printf
1540 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001541 return;
1542 }
1543 j += (argv[3][i] - '0') * (1 << i);
1544 }
developerbe40a9e2024-03-07 21:44:26 +08001545 value = j << 4; //w_port_map
developerfd40db22021-04-29 10:08:25 +08001546
1547 if (argc > 5) {
1548 j = strtoul(argv[5], NULL, 0);
1549 if (j < 1 || 255 < j) {
1550 printf("wrong age range, should be within 1~255\n");
1551 return;
1552 }
developerbe40a9e2024-03-07 21:44:26 +08001553 value |= (j << 24); //w_age_field
1554 value |= (0x1 << 2); //dynamic
developerfd40db22021-04-29 10:08:25 +08001555 } else {
developerbe40a9e2024-03-07 21:44:26 +08001556 value |= (0xff << 24); //w_age_field
1557 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001558 }
1559
1560 if (argc > 6) {
1561 j = strtoul(argv[6], NULL, 0);
1562 if (7 < j) {
1563 printf("wrong eg-tag range, should be within 0~7\n");
1564 return;
1565 }
developerbe40a9e2024-03-07 21:44:26 +08001566 value |= (j << 13); //EG_TAG
developerfd40db22021-04-29 10:08:25 +08001567 }
1568
1569 if (is_filter)
developerbe40a9e2024-03-07 21:44:26 +08001570 value |= (7 << 20); //sa_filter
developerfd40db22021-04-29 10:08:25 +08001571
1572 if (is_mymac)
1573 value |= (1 << 23);
1574
1575 reg_write(REG_ATWD_ADDR, value);
1576
1577 usleep(5000);
1578 reg_read(REG_ATWD_ADDR, &value);
1579 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1580
developerbe40a9e2024-03-07 21:44:26 +08001581 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001582 reg_write(REG_ATC_ADDR, value);
1583
1584 usleep(1000);
1585
1586 for (i = 0; i < 20; i++) {
1587 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001588 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001589 printf("done.\n");
1590 return;
1591 }
1592 usleep(1000);
1593 }
1594 if (i == 20)
1595 printf("timeout.\n");
1596}
1597
1598void table_search_mac_vid(int argc, char *argv[])
1599{
developerbe40a9e2024-03-07 21:44:26 +08001600 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001601 char tmpstr[9];
1602
1603 if (!argv[3] || strlen(argv[3]) != 12) {
1604 printf("MAC address format error, should be of length 12\n");
1605 return;
1606 }
1607 strncpy(tmpstr, argv[3], 8);
1608 tmpstr[8] = '\0';
1609 value = strtoul(tmpstr, NULL, 16);
1610 reg_write(REG_ATA1_ADDR, value);
1611 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1612
1613 strncpy(tmpstr, argv[3] + 8, 4);
1614 tmpstr[4] = '\0';
1615
1616 value = strtoul(tmpstr, NULL, 16);
1617 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001618 value |= (1 << 15); //IVL=1
developerfd40db22021-04-29 10:08:25 +08001619
1620 j = strtoul(argv[5], NULL, 0);
1621 if (4095 < j) {
1622 printf("wrong vid range, should be within 0~4095\n");
1623 return;
1624 }
developerbe40a9e2024-03-07 21:44:26 +08001625 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001626
1627 reg_write(REG_ATA2_ADDR, value);
1628 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1629
developerbe40a9e2024-03-07 21:44:26 +08001630 value = 0x8000; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001631 reg_write(REG_ATC_ADDR, value);
1632
1633 usleep(1000);
1634
1635 for (i = 0; i < 20; i++) {
1636 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001637 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001638 break;
1639 }
1640 usleep(1000);
1641 }
1642 if (i == 20) {
1643 printf("search timeout.\n");
1644 return;
1645 }
1646
1647 if (value & 0x1000) {
1648 printf("search no entry.\n");
1649 return;
1650 }
1651
1652 printf("search done.\n");
developerbe40a9e2024-03-07 21:44:26 +08001653 printf
1654 ("hash port(0:6) fid vid age mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001655
developerbe40a9e2024-03-07 21:44:26 +08001656 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
developerfd40db22021-04-29 10:08:25 +08001657 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001658 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001659 printf("%c", (j & 0x01) ? '1' : '-');
1660 printf("%c", (j & 0x02) ? '1' : '-');
1661 printf("%c", (j & 0x04) ? '1' : '-');
1662 printf("%c ", (j & 0x08) ? '1' : '-');
1663 printf("%c", (j & 0x10) ? '1' : '-');
1664 printf("%c", (j & 0x20) ? '1' : '-');
1665 printf("%c", (j & 0x40) ? '1' : '-');
1666 printf("%c", (j & 0x80) ? '1' : '-');
1667
1668 reg_read(REG_TSRA2_ADDR, &mac2);
1669
developerbe40a9e2024-03-07 21:44:26 +08001670 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001671 printf(" %4d", (mac2 & 0xfff));
developerbe40a9e2024-03-07 21:44:26 +08001672 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001673 reg_read(REG_TSRA1_ADDR, &mac);
1674 printf(" %08x", mac);
1675 printf("%04x", ((mac2 >> 16) & 0xffff));
1676 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1677 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1678}
1679
1680void table_search_mac_fid(int argc, char *argv[])
1681{
developerbe40a9e2024-03-07 21:44:26 +08001682 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001683 char tmpstr[9];
1684
1685 if (!argv[3] || strlen(argv[3]) != 12) {
1686 printf("MAC address format error, should be of length 12\n");
1687 return;
1688 }
1689 strncpy(tmpstr, argv[3], 8);
1690 tmpstr[8] = '\0';
1691 value = strtoul(tmpstr, NULL, 16);
1692 reg_write(REG_ATA1_ADDR, value);
1693 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1694
1695 strncpy(tmpstr, argv[3] + 8, 4);
1696 tmpstr[4] = '\0';
1697
1698 value = strtoul(tmpstr, NULL, 16);
1699 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001700 value &= ~(1 << 15); //IVL=0
developerfd40db22021-04-29 10:08:25 +08001701
1702 j = strtoul(argv[5], NULL, 0);
1703 if (7 < j) {
1704 printf("wrong fid range, should be within 0~7\n");
1705 return;
1706 }
developerbe40a9e2024-03-07 21:44:26 +08001707 value |= (j << 12); //vid
developerfd40db22021-04-29 10:08:25 +08001708
1709 reg_write(REG_ATA2_ADDR, value);
1710 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1711
developerbe40a9e2024-03-07 21:44:26 +08001712 value = 0x8000; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001713 reg_write(REG_ATC_ADDR, value);
1714
1715 usleep(1000);
1716
1717 for (i = 0; i < 20; i++) {
1718 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001719 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001720 break;
1721 }
1722 usleep(1000);
1723 }
1724 if (i == 20) {
1725 printf("search timeout.\n");
1726 return;
1727 }
1728
1729 if (value & 0x1000) {
1730 printf("search no entry.\n");
1731 return;
1732 }
1733
1734 printf("search done.\n");
developerbe40a9e2024-03-07 21:44:26 +08001735 printf
1736 ("hash port(0:6) fid vid age mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001737
developerbe40a9e2024-03-07 21:44:26 +08001738 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
developerfd40db22021-04-29 10:08:25 +08001739 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001740 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001741 printf("%c", (j & 0x01) ? '1' : '-');
1742 printf("%c", (j & 0x02) ? '1' : '-');
1743 printf("%c", (j & 0x04) ? '1' : '-');
1744 printf("%c ", (j & 0x08) ? '1' : '-');
1745 printf("%c", (j & 0x10) ? '1' : '-');
1746 printf("%c", (j & 0x20) ? '1' : '-');
1747 printf("%c", (j & 0x40) ? '1' : '-');
1748 printf("%c", (j & 0x80) ? '1' : '-');
1749
1750 reg_read(REG_TSRA2_ADDR, &mac2);
1751
developerbe40a9e2024-03-07 21:44:26 +08001752 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001753 printf(" %4d", (mac2 & 0xfff));
developerbe40a9e2024-03-07 21:44:26 +08001754 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001755 reg_read(REG_TSRA1_ADDR, &mac);
1756 printf(" %08x", mac);
1757 printf("%04x", ((mac2 >> 16) & 0xffff));
1758 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1759 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1760}
1761
1762void table_del_fid(int argc, char *argv[])
1763{
developerbe40a9e2024-03-07 21:44:26 +08001764 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001765 char tmpstr[9];
1766
1767 if (!argv[3] || strlen(argv[3]) != 12) {
1768 printf("MAC address format error, should be of length 12\n");
1769 return;
1770 }
1771 strncpy(tmpstr, argv[3], 8);
1772 tmpstr[8] = '\0';
1773 value = strtoul(tmpstr, NULL, 16);
1774 reg_write(REG_ATA1_ADDR, value);
1775 strncpy(tmpstr, argv[3] + 8, 4);
1776 tmpstr[4] = '\0';
1777 value = strtoul(tmpstr, NULL, 16);
1778 value = (value << 16);
1779
1780 if (argc > 5) {
1781 j = strtoul(argv[5], NULL, 0);
1782 if (j > 7) {
1783 printf("wrong fid range, should be within 0~7\n");
1784 return;
1785 }
developerbe40a9e2024-03-07 21:44:26 +08001786 value |= (j << 12); /* fid */
developerfd40db22021-04-29 10:08:25 +08001787 }
1788
1789 reg_write(REG_ATA2_ADDR, value);
1790
developerbe40a9e2024-03-07 21:44:26 +08001791 value = 0; /* STATUS=0, delete mac */
developerfd40db22021-04-29 10:08:25 +08001792 reg_write(REG_ATWD_ADDR, value);
1793
developerbe40a9e2024-03-07 21:44:26 +08001794 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001795 reg_write(REG_ATC_ADDR, value);
1796
1797 for (i = 0; i < 20; i++) {
1798 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001799 if ((value & 0x8000) == 0) { /* mac address busy */
developerfd40db22021-04-29 10:08:25 +08001800 if (argv[1] != NULL)
1801 printf("done.\n");
1802 return;
1803 }
1804 usleep(1000);
1805 }
1806 if (i == 20)
1807 printf("timeout.\n");
1808}
1809
1810void table_del_vid(int argc, char *argv[])
1811{
developerbe40a9e2024-03-07 21:44:26 +08001812 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001813 char tmpstr[9];
1814
1815 if (!argv[3] || strlen(argv[3]) != 12) {
1816 printf("MAC address format error, should be of length 12\n");
1817 return;
1818 }
1819 strncpy(tmpstr, argv[3], 8);
1820 tmpstr[8] = '\0';
1821 value = strtoul(tmpstr, NULL, 16);
1822 reg_write(REG_ATA1_ADDR, value);
1823
1824 strncpy(tmpstr, argv[3] + 8, 4);
1825 tmpstr[4] = '\0';
1826 value = strtoul(tmpstr, NULL, 16);
1827 value = (value << 16);
1828
1829 j = strtoul(argv[5], NULL, 0);
1830 if (j > 4095) {
1831 printf("wrong fid range, should be within 0~4095\n");
1832 return;
1833 }
developerbe40a9e2024-03-07 21:44:26 +08001834 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001835 value |= 1 << 15;
1836 reg_write(REG_ATA2_ADDR, value);
1837
developerbe40a9e2024-03-07 21:44:26 +08001838 value = 0; //STATUS=0, delete mac
developerfd40db22021-04-29 10:08:25 +08001839 reg_write(REG_ATWD_ADDR, value);
1840
developerbe40a9e2024-03-07 21:44:26 +08001841 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001842 reg_write(REG_ATC_ADDR, value);
1843
1844 for (i = 0; i < 20; i++) {
1845 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001846 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001847 if (argv[1] != NULL)
1848 printf("done.\n");
1849 return;
1850 }
1851 usleep(1000);
1852 }
1853 if (i == 20)
1854 printf("timeout.\n");
1855}
1856
developerbe40a9e2024-03-07 21:44:26 +08001857void table_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001858{
developerbe40a9e2024-03-07 21:44:26 +08001859 unsigned int value = 0;
1860
developerfd40db22021-04-29 10:08:25 +08001861 reg_write(REG_ATC_ADDR, 0x8002);
1862 usleep(5000);
1863 reg_read(REG_ATC_ADDR, &value);
1864
1865 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1866}
1867
1868void set_mirror_to(int argc, char *argv[])
1869{
developerbe40a9e2024-03-07 21:44:26 +08001870 unsigned int value = 0;
1871 int idx = 0;
developerfd40db22021-04-29 10:08:25 +08001872
1873 idx = strtoul(argv[3], NULL, 0);
1874 if (idx < 0 || MAX_PORT < idx) {
1875 printf("wrong port member, should be within 0~%d\n", MAX_PORT);
1876 return;
1877 }
1878 if (chip_name == 0x7530) {
1879
1880 reg_read(REG_MFC_ADDR, &value);
1881 value |= 0x1 << 3;
1882 value &= 0xfffffff8;
1883 value |= idx << 0;
1884
1885 reg_write(REG_MFC_ADDR, value);
1886 } else {
1887
1888 reg_read(REG_CFC_ADDR, &value);
1889 value &= (~REG_CFC_MIRROR_EN_MASK);
1890 value |= (1 << REG_CFC_MIRROR_EN_OFFT);
1891 value &= (~REG_CFC_MIRROR_PORT_MASK);
1892 value |= (idx << REG_CFC_MIRROR_PORT_OFFT);
1893 reg_write(REG_CFC_ADDR, value);
1894 }
1895}
1896
1897void set_mirror_from(int argc, char *argv[])
1898{
developerbe40a9e2024-03-07 21:44:26 +08001899 unsigned int offset = 0, value = 0;
1900 int idx = 0, mirror = 0;
developerfd40db22021-04-29 10:08:25 +08001901
1902 idx = strtoul(argv[3], NULL, 0);
1903 mirror = strtoul(argv[4], NULL, 0);
1904
1905 if (idx < 0 || MAX_PORT < idx) {
1906 printf("wrong port member, should be within 0~%d\n", MAX_PORT);
1907 return;
1908 }
1909
1910 if (mirror < 0 || 3 < mirror) {
1911 printf("wrong mirror setting, should be within 0~3\n");
1912 return;
1913 }
1914
1915 offset = (0x2004 | (idx << 8));
1916 reg_read(offset, &value);
1917
1918 value &= 0xfffffcff;
1919 value |= mirror << 8;
1920
1921 reg_write(offset, value);
1922}
1923
1924void vlan_dump(int argc, char *argv[])
1925{
developerbe40a9e2024-03-07 21:44:26 +08001926 unsigned int i = 0, j = 0, value = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001927 int eg_tag = 0;
1928
1929 if (argc == 4) {
1930 if (!strncmp(argv[3], "egtag", 6))
1931 eg_tag = 1;
1932 }
1933
1934 if (eg_tag)
developerbe40a9e2024-03-07 21:44:26 +08001935 printf
1936 (" vid fid portmap s-tag\teg_tag(0:untagged 2:tagged)\n");
developerfd40db22021-04-29 10:08:25 +08001937 else
1938 printf(" vid fid portmap s-tag\n");
1939
1940 for (i = 1; i < 4095; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001941 value = (0x80000000 + i); //r_vid_cmd
developerfd40db22021-04-29 10:08:25 +08001942 reg_write(REG_VTCR_ADDR, value);
1943
1944 for (j = 0; j < 20; j++) {
1945 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001946 if ((value & 0x80000000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001947 break;
1948 }
1949 usleep(1000);
1950 }
1951 if (j == 20)
1952 printf("timeout.\n");
1953
1954 reg_read(REG_VAWD1_ADDR, &value);
1955 reg_read(REG_VAWD2_ADDR, &value2);
1956 //printf("REG_VAWD1_ADDR value%d is 0x%x\n\r", i, value);
1957 //printf("REG_VAWD2_ADDR value%d is 0x%x\n\r", i, value2);
1958
1959 if ((value & 0x01) != 0) {
1960 printf(" %4d ", i);
1961 printf(" %2d ", ((value & 0xe) >> 1));
1962 printf(" %c", (value & 0x00010000) ? '1' : '-');
1963 printf("%c", (value & 0x00020000) ? '1' : '-');
1964 printf("%c", (value & 0x00040000) ? '1' : '-');
1965 printf("%c", (value & 0x00080000) ? '1' : '-');
1966 printf("%c", (value & 0x00100000) ? '1' : '-');
1967 printf("%c", (value & 0x00200000) ? '1' : '-');
1968 printf("%c", (value & 0x00400000) ? '1' : '-');
1969 printf("%c", (value & 0x00800000) ? '1' : '-');
1970 printf(" %4d", ((value & 0xfff0) >> 4));
1971 if (eg_tag) {
1972 printf("\t");
1973 if ((value & (0x3 << 28)) == (0x3 << 28)) {
1974 /* VTAG_EN=1 and EG_CON=1 */
1975 printf("CONSISTENT");
1976 } else if (value & (0x1 << 28)) {
1977 /* VTAG_EN=1 */
1978 printf("%d", (value2 & 0x0003) >> 0);
1979 printf("%d", (value2 & 0x000c) >> 2);
1980 printf("%d", (value2 & 0x0030) >> 4);
1981 printf("%d", (value2 & 0x00c0) >> 6);
1982 printf("%d", (value2 & 0x0300) >> 8);
1983 printf("%d", (value2 & 0x0c00) >> 10);
1984 printf("%d", (value2 & 0x3000) >> 12);
1985 printf("%d", (value2 & 0xc000) >> 14);
1986 } else {
1987 /* VTAG_EN=0 */
1988 printf("DISABLED");
1989 }
1990 }
1991 printf("\n");
1992 } else {
developerbe40a9e2024-03-07 21:44:26 +08001993 /*print 16 vid for reference information */
developerfd40db22021-04-29 10:08:25 +08001994 if (i <= 16) {
1995 printf(" %4d ", i);
1996 printf(" %2d ", ((value & 0xe) >> 1));
1997 printf(" invalid\n");
1998 }
1999 }
2000 }
2001}
2002
developerfd40db22021-04-29 10:08:25 +08002003static long timespec_diff_us(struct timespec start, struct timespec end)
2004{
2005 struct timespec temp;
2006 unsigned long duration = 0;
2007
2008 if ((end.tv_nsec - start.tv_nsec) < 0) {
2009 temp.tv_sec = end.tv_sec - start.tv_sec - 1;
2010 temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
2011 } else {
2012 temp.tv_sec = end.tv_sec - start.tv_sec;
2013 temp.tv_nsec = end.tv_nsec - start.tv_nsec;
2014 }
developerbe40a9e2024-03-07 21:44:26 +08002015 /* calculate second part */
developerfd40db22021-04-29 10:08:25 +08002016 duration += temp.tv_sec * 1000000;
developerbe40a9e2024-03-07 21:44:26 +08002017 /* calculate ns part */
developerfd40db22021-04-29 10:08:25 +08002018 duration += temp.tv_nsec >> 10;
2019
2020 return duration;
2021}
2022
developerfd40db22021-04-29 10:08:25 +08002023void vlan_clear(int argc, char *argv[])
2024{
developerbe40a9e2024-03-07 21:44:26 +08002025 unsigned int value = 0;
2026 int vid = 0;
developerfd40db22021-04-29 10:08:25 +08002027 unsigned long duration_us = 0;
2028 struct timespec start, end;
2029
2030 for (vid = 0; vid < 4096; vid++) {
2031 clock_gettime(CLOCK_REALTIME, &start);
developerbe40a9e2024-03-07 21:44:26 +08002032 value = 0; //invalid
developerfd40db22021-04-29 10:08:25 +08002033 reg_write(REG_VAWD1_ADDR, value);
2034
developerbe40a9e2024-03-07 21:44:26 +08002035 value = (0x80001000 + vid); //w_vid_cmd
developerfd40db22021-04-29 10:08:25 +08002036 reg_write(REG_VTCR_ADDR, value);
2037 while (duration_us <= 1000) {
2038 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002039 if ((value & 0x80000000) == 0) { //table busy
developerfd40db22021-04-29 10:08:25 +08002040 break;
2041 }
2042 clock_gettime(CLOCK_REALTIME, &end);
2043 duration_us = timespec_diff_us(start, end);
2044 }
2045 if (duration_us > 1000)
2046 printf("config vlan timeout: %ld.\n", duration_us);
2047 }
2048}
2049
2050void vlan_set(int argc, char *argv[])
2051{
2052 unsigned int vlan_mem = 0;
2053 unsigned int value = 0;
2054 unsigned int value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08002055 int i = 0, vid = 0, fid = 0;
developerfd40db22021-04-29 10:08:25 +08002056 int stag = 0;
2057 unsigned long eg_con = 0;
2058 unsigned int eg_tag = 0;
2059
2060 if (argc < 5) {
2061 printf("insufficient arguments!\n");
2062 return;
2063 }
2064
2065 fid = strtoul(argv[3], NULL, 0);
2066 if (fid < 0 || fid > 7) {
2067 printf("wrong filtering db id range, should be within 0~7\n");
2068 return;
2069 }
2070 value |= (fid << 1);
2071
2072 vid = strtoul(argv[4], NULL, 0);
2073 if (vid < 0 || 0xfff < vid) {
2074 printf("wrong vlan id range, should be within 0~4095\n");
2075 return;
2076 }
2077
2078 if (strlen(argv[5]) != 8) {
2079 printf("portmap format error, should be of length 7\n");
2080 return;
2081 }
2082
2083 vlan_mem = 0;
2084 for (i = 0; i < 8; i++) {
2085 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08002086 printf
2087 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08002088 return;
2089 }
2090 vlan_mem += (argv[5][i] - '0') * (1 << i);
2091 }
2092
2093 /* VLAN stag */
2094 if (argc > 6) {
2095 stag = strtoul(argv[6], NULL, 16);
2096 if (stag < 0 || 0xfff < stag) {
developerbe40a9e2024-03-07 21:44:26 +08002097 printf
2098 ("wrong stag id range, should be within 0~4095\n");
developerfd40db22021-04-29 10:08:25 +08002099 return;
2100 }
2101 //printf("STAG is 0x%x\n", stag);
2102 }
2103
2104 /* set vlan member */
2105 value |= (vlan_mem << 16);
developerbe40a9e2024-03-07 21:44:26 +08002106 value |= (1 << 30); //IVL=1
2107 value |= ((stag & 0xfff) << 4); //stag
2108 value |= 1; //valid
developerfd40db22021-04-29 10:08:25 +08002109
2110 if (argc > 7) {
2111 eg_con = strtoul(argv[7], NULL, 2);
2112 eg_con = !!eg_con;
developerbe40a9e2024-03-07 21:44:26 +08002113 value |= (eg_con << 29); //eg_con
2114 value |= (1 << 28); //eg tag control enable
developerfd40db22021-04-29 10:08:25 +08002115 }
2116
2117 if (argc > 8 && !eg_con) {
2118 if (strlen(argv[8]) != 8) {
developerbe40a9e2024-03-07 21:44:26 +08002119 printf
2120 ("egtag portmap format error, should be of length 7\n");
developerfd40db22021-04-29 10:08:25 +08002121 return;
2122 }
2123
2124 for (i = 0; i < 8; i++) {
2125 if (argv[8][i] < '0' || argv[8][i] > '3') {
developerbe40a9e2024-03-07 21:44:26 +08002126 printf
2127 ("egtag portmap format error, should be of combination of 0 or 3\n");
developerfd40db22021-04-29 10:08:25 +08002128 return;
2129 }
2130 //eg_tag += (argv[8][i] - '0') * (1 << i * 2);
2131 eg_tag |= (argv[8][i] - '0') << (i * 2);
2132 }
2133
developerbe40a9e2024-03-07 21:44:26 +08002134 value |= (1 << 28); //eg tag control enable
developerfd40db22021-04-29 10:08:25 +08002135 value2 &= ~(0xffff);
2136 value2 |= eg_tag;
2137 }
2138 reg_write(REG_VAWD1_ADDR, value);
2139 reg_write(REG_VAWD2_ADDR, value2);
2140 //printf("VAWD1=0x%08x VAWD2=0x%08x ", value, value2);
2141
developerbe40a9e2024-03-07 21:44:26 +08002142 value = (0x80001000 + vid); //w_vid_cmd
developerfd40db22021-04-29 10:08:25 +08002143 reg_write(REG_VTCR_ADDR, value);
2144 //printf("VTCR=0x%08x\n", value);
2145
2146 for (i = 0; i < 300; i++) {
2147 usleep(1000);
2148 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002149 if ((value & 0x80000000) == 0) //table busy
developerfd40db22021-04-29 10:08:25 +08002150 break;
2151 }
2152
2153 if (i == 300)
2154 printf("config vlan timeout.\n");
2155}
2156
2157void igmp_on(int argc, char *argv[])
2158{
2159 unsigned int leaky_en = 0;
2160 unsigned int wan_num = 4;
developerbe40a9e2024-03-07 21:44:26 +08002161 unsigned int port = 0, offset = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002162 char cmd[80];
2163 int ret;
2164
2165 if (argc > 3)
2166 leaky_en = strtoul(argv[3], NULL, 10);
2167 if (argc > 4)
2168 wan_num = strtoul(argv[4], NULL, 10);
2169
2170 if (leaky_en == 1) {
2171 if (wan_num == 4) {
2172 /* reg_write(0x2410, 0x810000c8); */
2173 reg_read(0x2410, &value);
2174 reg_write(0x2410, value | (1 << 3));
2175 /* reg_write(0x2010, 0x810000c0); */
2176 reg_read(0x2010, &value);
2177 reg_write(0x2010, value & (~(1 << 3)));
2178 reg_write(REG_ISC_ADDR, 0x10027d10);
2179 } else {
2180 /* reg_write(0x2010, 0x810000c8); */
2181 reg_read(0x2010, &value);
2182 reg_write(0x2010, value | (1 << 3));
2183 /* reg_write(0x2410, 0x810000c0); */
2184 reg_read(0x2410, &value);
2185 reg_write(0x2410, value & (~(1 << 3)));
2186 reg_write(REG_ISC_ADDR, 0x01027d01);
2187 }
developerbe40a9e2024-03-07 21:44:26 +08002188 } else
developerfd40db22021-04-29 10:08:25 +08002189 reg_write(REG_ISC_ADDR, 0x10027d60);
2190
2191 reg_write(0x1c, 0x08100810);
2192 reg_write(0x2008, 0xb3ff);
2193 reg_write(0x2108, 0xb3ff);
2194 reg_write(0x2208, 0xb3ff);
2195 reg_write(0x2308, 0xb3ff);
2196 reg_write(0x2408, 0xb3ff);
2197 reg_write(0x2608, 0xb3ff);
2198 /* Enable Port ACL
developerbe40a9e2024-03-07 21:44:26 +08002199 * reg_write(0x2P04, 0xff0403);
2200 */
developerfd40db22021-04-29 10:08:25 +08002201 for (port = 0; port <= 6; port++) {
2202 offset = 0x2004 + port * 0x100;
2203 reg_read(offset, &value);
2204 reg_write(offset, value | (1 << 10));
2205 }
2206
developerbe40a9e2024-03-07 21:44:26 +08002207 /*IGMP query only p4 -> p5 */
developerfd40db22021-04-29 10:08:25 +08002208 reg_write(0x94, 0x00ff0002);
2209 if (wan_num == 4)
2210 reg_write(0x98, 0x000a1008);
2211 else
2212 reg_write(0x98, 0x000a0108);
2213 reg_write(0x90, 0x80005000);
2214 reg_write(0x94, 0xff001100);
2215 if (wan_num == 4)
2216 reg_write(0x98, 0x000B1000);
2217 else
2218 reg_write(0x98, 0x000B0100);
2219 reg_write(0x90, 0x80005001);
2220 reg_write(0x94, 0x3);
2221 reg_write(0x98, 0x0);
2222 reg_write(0x90, 0x80009000);
2223 reg_write(0x94, 0x1a002080);
2224 reg_write(0x98, 0x0);
2225 reg_write(0x90, 0x8000b000);
2226
developerbe40a9e2024-03-07 21:44:26 +08002227 /*IGMP p5 -> p4 */
developerfd40db22021-04-29 10:08:25 +08002228 reg_write(0x94, 0x00ff0002);
2229 reg_write(0x98, 0x000a2008);
2230 reg_write(0x90, 0x80005002);
2231 reg_write(0x94, 0x4);
2232 reg_write(0x98, 0x0);
2233 reg_write(0x90, 0x80009001);
2234 if (wan_num == 4)
2235 reg_write(0x94, 0x1a001080);
2236 else
2237 reg_write(0x94, 0x1a000180);
2238 reg_write(0x98, 0x0);
2239 reg_write(0x90, 0x8000b001);
2240
developerbe40a9e2024-03-07 21:44:26 +08002241 /*IGMP p0~p3 -> p6 */
developerfd40db22021-04-29 10:08:25 +08002242 reg_write(0x94, 0x00ff0002);
2243 if (wan_num == 4)
2244 reg_write(0x98, 0x000a0f08);
2245 else
2246 reg_write(0x98, 0x000a1e08);
2247 reg_write(0x90, 0x80005003);
2248 reg_write(0x94, 0x8);
2249 reg_write(0x98, 0x0);
2250 reg_write(0x90, 0x80009002);
2251 reg_write(0x94, 0x1a004080);
2252 reg_write(0x98, 0x0);
2253 reg_write(0x90, 0x8000b002);
2254
developerbe40a9e2024-03-07 21:44:26 +08002255 /*IGMP query only p6 -> p0~p3 */
developerfd40db22021-04-29 10:08:25 +08002256 reg_write(0x94, 0x00ff0002);
2257 reg_write(0x98, 0x000a4008);
2258 reg_write(0x90, 0x80005004);
2259 reg_write(0x94, 0xff001100);
2260 reg_write(0x98, 0x000B4000);
2261 reg_write(0x90, 0x80005005);
2262 reg_write(0x94, 0x30);
2263 reg_write(0x98, 0x0);
2264 reg_write(0x90, 0x80009003);
2265 if (wan_num == 4)
2266 reg_write(0x94, 0x1a000f80);
2267 else
2268 reg_write(0x94, 0x1a001e80);
2269 reg_write(0x98, 0x0);
2270 reg_write(0x90, 0x8000b003);
2271
developerbe40a9e2024-03-07 21:44:26 +08002272 /*Force eth2 to receive all igmp packets */
2273 snprintf(cmd, sizeof(cmd),
2274 "echo 2 > /sys/devices/virtual/net/%s/brif/%s/multicast_router",
2275 BR_DEVNAME, ETH_DEVNAME);
developerfd40db22021-04-29 10:08:25 +08002276 ret = system(cmd);
2277 if (ret)
developerbe40a9e2024-03-07 21:44:26 +08002278 printf
2279 ("Failed to set /sys/devices/virtual/net/%s/brif/%s/multicast_router\n",
2280 BR_DEVNAME, ETH_DEVNAME);
developerfd40db22021-04-29 10:08:25 +08002281}
2282
2283void igmp_disable(int argc, char *argv[])
2284{
developerbe40a9e2024-03-07 21:44:26 +08002285 unsigned int reg_offset = 0, value = 0;
2286 int port_num = 0;
developerfd40db22021-04-29 10:08:25 +08002287
2288 if (argc < 4) {
2289 printf("insufficient arguments!\n");
2290 return;
2291 }
2292 port_num = strtoul(argv[3], NULL, 0);
2293 if (port_num < 0 || 6 < port_num) {
2294 printf("wrong port range, should be within 0~6\n");
2295 return;
2296 }
developerfd40db22021-04-29 10:08:25 +08002297 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2298 reg_offset = 0x2008;
2299 reg_offset |= (port_num << 8);
2300 value = 0x8000;
2301
2302 reg_write(reg_offset, value);
2303}
2304
2305void igmp_enable(int argc, char *argv[])
2306{
developerbe40a9e2024-03-07 21:44:26 +08002307 unsigned int reg_offset = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002308 int port_num;
2309
2310 if (argc < 4) {
2311 printf("insufficient arguments!\n");
2312 return;
2313 }
2314 port_num = strtoul(argv[3], NULL, 0);
2315 if (port_num < 0 || 6 < port_num) {
2316 printf("wrong port range, should be within 0~6\n");
2317 return;
2318 }
developerfd40db22021-04-29 10:08:25 +08002319 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2320 reg_offset = 0x2008;
2321 reg_offset |= (port_num << 8);
2322 value = 0x9755;
2323 reg_write(reg_offset, value);
2324}
2325
developerbe40a9e2024-03-07 21:44:26 +08002326void igmp_off(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002327{
developerbe40a9e2024-03-07 21:44:26 +08002328 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08002329 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2330 reg_read(REG_ISC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002331 value &= ~(1 << 18); //disable
developerfd40db22021-04-29 10:08:25 +08002332 reg_write(REG_ISC_ADDR, value);
2333
developerbe40a9e2024-03-07 21:44:26 +08002334 /*restore wan port multicast leaky vlan function: default disabled */
developerfd40db22021-04-29 10:08:25 +08002335 reg_read(0x2010, &value);
2336 reg_write(0x2010, value & (~(1 << 3)));
2337 reg_read(0x2410, &value);
2338 reg_write(0x2410, value & (~(1 << 3)));
2339
2340 printf("config igmpsnoop off.\n");
2341}
2342
developerbe40a9e2024-03-07 21:44:26 +08002343void switch_reset(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002344{
developer8c3871b2022-07-01 14:07:53 +08002345 if (chip_name == 0x7988)
developerbe40a9e2024-03-07 21:44:26 +08002346 return;
developer8c3871b2022-07-01 14:07:53 +08002347
developerfd40db22021-04-29 10:08:25 +08002348 unsigned int value = 0;
2349 /*Software Register Reset and Software System Reset */
2350 reg_write(0x7000, 0x3);
2351 reg_read(0x7000, &value);
2352 printf("SYS_CTRL(0x7000) register value =0x%x \n", value);
2353 if (chip_name == 0x7531) {
2354 reg_write(0x7c0c, 0x11111111);
2355 reg_read(0x7c0c, &value);
2356 printf("GPIO Mode (0x7c0c) select value =0x%x \n", value);
2357 }
2358 printf("Switch Software Reset !!! \n");
2359}
2360
developerbe40a9e2024-03-07 21:44:26 +08002361void phy_set_fc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002362{
developerbe40a9e2024-03-07 21:44:26 +08002363 unsigned int port = 0, pause_capable = 0;
2364 unsigned int phy_value = 0;
developerfd40db22021-04-29 10:08:25 +08002365
2366 port = atoi(argv[3]);
2367 pause_capable = atoi(argv[4]);
2368
developerbe40a9e2024-03-07 21:44:26 +08002369 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002370 if (port > MAX_PORT - 2 || pause_capable > 1) {
developerbe40a9e2024-03-07 21:44:26 +08002371 printf
2372 ("Illegal parameter (port:0~4, full_duplex_pause_capable:0|1)\n");
2373 return;
developerfd40db22021-04-29 10:08:25 +08002374 }
2375 printf("port=%d, full_duplex_pause_capable:%d\n", port, pause_capable);
developerbe40a9e2024-03-07 21:44:26 +08002376
developerfd40db22021-04-29 10:08:25 +08002377 mii_mgr_read(port, 4, &phy_value);
2378 printf("read phy_value:0x%x\r\n", phy_value);
2379 phy_value &= (~(0x1 << 10));
2380 phy_value &= (~(0x1 << 11));
2381 if (pause_capable == 1) {
2382 phy_value |= (0x1 << 10);
2383 phy_value |= (0x1 << 11);
2384 }
2385 mii_mgr_write(port, 4, phy_value);
2386 printf("write phy_value:0x%x\r\n", phy_value);
developerbe40a9e2024-03-07 21:44:26 +08002387 return;
2388} /*end phy_set_fc */
developerfd40db22021-04-29 10:08:25 +08002389
developerbe40a9e2024-03-07 21:44:26 +08002390void phy_set_an(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002391{
developerbe40a9e2024-03-07 21:44:26 +08002392 unsigned int port = 0, auto_negotiation_en = 0;
2393 unsigned int phy_value = 0;
developerfd40db22021-04-29 10:08:25 +08002394
2395 port = atoi(argv[3]);
2396 auto_negotiation_en = atoi(argv[4]);
2397
developerbe40a9e2024-03-07 21:44:26 +08002398 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002399 if (port > MAX_PORT - 2 || auto_negotiation_en > 1) {
developerbe40a9e2024-03-07 21:44:26 +08002400 printf
2401 ("Illegal parameter (port:0~4, auto_negotiation_en:0|1)\n");
2402 return;
developerfd40db22021-04-29 10:08:25 +08002403 }
2404 printf("port=%d, auto_negotiation_en:%d\n", port, auto_negotiation_en);
developerbe40a9e2024-03-07 21:44:26 +08002405
developerfd40db22021-04-29 10:08:25 +08002406 mii_mgr_read(port, 0, &phy_value);
2407 printf("read phy_value:0x%x\r\n", phy_value);
2408 phy_value &= (~(1 << 12));
2409 phy_value |= (auto_negotiation_en << 12);
2410 mii_mgr_write(port, 0, phy_value);
2411 printf("write phy_value:0x%x\r\n", phy_value);
developerbe40a9e2024-03-07 21:44:26 +08002412} /*end phy_set_an */
developerfd40db22021-04-29 10:08:25 +08002413
developerbe40a9e2024-03-07 21:44:26 +08002414void set_mac_pfc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002415{
developerbe40a9e2024-03-07 21:44:26 +08002416 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08002417 int port, enable = 0;
2418
2419 port = atoi(argv[3]);
2420 enable = atoi(argv[4]);
2421 printf("enable: %d\n", enable);
2422 if (port < 0 || port > 6 || enable < 0 || enable > 1) {
2423 printf("Illegal parameter (port:0~6, enable|diable:0|1) \n");
developerbe40a9e2024-03-07 21:44:26 +08002424 return;
developerfd40db22021-04-29 10:08:25 +08002425 }
developer8c3871b2022-07-01 14:07:53 +08002426 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002427 reg_read(REG_PFC_CTRL_ADDR, &value);
2428 value &= ~(1 << port);
2429 value |= (enable << port);
2430 printf("write reg: %x, value: %x\n", REG_PFC_CTRL_ADDR, value);
2431 reg_write(REG_PFC_CTRL_ADDR, value);
developerbe40a9e2024-03-07 21:44:26 +08002432 } else
developerfd40db22021-04-29 10:08:25 +08002433 printf("\nCommand not support by this chip.\n");
developerfd40db22021-04-29 10:08:25 +08002434}
2435
developerbe40a9e2024-03-07 21:44:26 +08002436void global_set_mac_fc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002437{
2438 unsigned char enable = 0;
developerbe40a9e2024-03-07 21:44:26 +08002439 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08002440
2441 if (chip_name == 0x7530) {
2442 enable = atoi(argv[3]);
2443 printf("enable: %d\n", enable);
2444
developerbe40a9e2024-03-07 21:44:26 +08002445 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002446 if (enable > 1) {
2447 printf(HELP_MACCTL_FC);
developerbe40a9e2024-03-07 21:44:26 +08002448 return;
developerfd40db22021-04-29 10:08:25 +08002449 }
2450 reg_write(0x7000, 0x3);
2451 reg = REG_GFCCR0_ADDR;
2452 reg_read(REG_GFCCR0_ADDR, &value);
2453 value &= (~REG_FC_EN_MASK);
2454 value |= (enable << REG_FC_EN_OFFT);
2455 printf("write reg: %x, value: %x\n", reg, value);
2456 reg_write(REG_GFCCR0_ADDR, value);
2457 } else
2458 printf("\r\nCommand not support by this chip.\n");
developerbe40a9e2024-03-07 21:44:26 +08002459} /*end mac_set_fc */
developerfd40db22021-04-29 10:08:25 +08002460
developerbe40a9e2024-03-07 21:44:26 +08002461void qos_sch_select(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002462{
developerbe40a9e2024-03-07 21:44:26 +08002463 unsigned char port = 0, queue = 0;
developerfd40db22021-04-29 10:08:25 +08002464 unsigned char type = 0;
developerbe40a9e2024-03-07 21:44:26 +08002465 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08002466
2467 if (argc < 7)
developerbe40a9e2024-03-07 21:44:26 +08002468 return;
developerfd40db22021-04-29 10:08:25 +08002469
2470 port = atoi(argv[3]);
2471 queue = atoi(argv[4]);
2472 type = atoi(argv[6]);
2473
2474 if (port > 6 || queue > 7) {
2475 printf("\n Illegal input parameters\n");
developerbe40a9e2024-03-07 21:44:26 +08002476 return;
developerfd40db22021-04-29 10:08:25 +08002477 }
2478
2479 if ((type != 0 && type != 1 && type != 2)) {
2480 printf(HELP_QOS_TYPE);
developerbe40a9e2024-03-07 21:44:26 +08002481 return;
developerfd40db22021-04-29 10:08:25 +08002482 }
2483
developerbe40a9e2024-03-07 21:44:26 +08002484 printf("\r\nswitch qos type: %d.\n", type);
developerfd40db22021-04-29 10:08:25 +08002485
2486 if (!strncmp(argv[5], "min", 4)) {
2487
2488 if (type == 0) {
developerbe40a9e2024-03-07 21:44:26 +08002489 /*min sharper-->round roubin, disable min sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002490 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2491 reg_read(reg, &value);
2492 value = 0x0;
2493 reg_write(reg, value);
2494 } else if (type == 1) {
developerbe40a9e2024-03-07 21:44:26 +08002495 /*min sharper-->sp, disable min sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002496 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2497 reg_read(reg, &value);
2498 value = 0x0;
2499 value |= (1 << 31);
2500 reg_write(reg, value);
2501 } else {
2502 printf("min sharper only support: rr or sp\n");
developerbe40a9e2024-03-07 21:44:26 +08002503 return;
developerfd40db22021-04-29 10:08:25 +08002504 }
2505 } else if (!strncmp(argv[5], "max", 4)) {
2506 if (type == 1) {
developerbe40a9e2024-03-07 21:44:26 +08002507 /*max sharper-->sp, disable max sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002508 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2509 reg_read(reg, &value);
2510 value = 0x0;
2511 value |= (1 << 31);
2512 reg_write(reg, value);
2513 } else if (type == 2) {
developerbe40a9e2024-03-07 21:44:26 +08002514 /*max sharper-->wfq, disable max sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002515 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2516 reg_read(reg, &value);
2517 value = 0x0;
2518 reg_write(reg, value);
2519 } else {
2520 printf("max sharper only support: wfq or sp\n");
developerbe40a9e2024-03-07 21:44:26 +08002521 return;
developerfd40db22021-04-29 10:08:25 +08002522 }
2523 } else {
developerbe40a9e2024-03-07 21:44:26 +08002524 printf("\r\nIllegal sharper:%s\n", argv[5]);
2525 return;
developerfd40db22021-04-29 10:08:25 +08002526 }
developerbe40a9e2024-03-07 21:44:26 +08002527 printf("reg:0x%x--value:0x%x\n", reg, value);
developerfd40db22021-04-29 10:08:25 +08002528}
2529
2530void get_upw(unsigned int *value, unsigned char base)
2531{
2532 *value &= (~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
2533 (0x7 << 16) | (0x7 << 20)));
developerbe40a9e2024-03-07 21:44:26 +08002534 switch (base) {
2535 case 0: /* port-based 0x2x40[18:16] */
2536 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2537 (0x2 << 12) | (0x7 << 16) | (0x2 << 20));
2538 break;
2539 case 1: /* tagged-based 0x2x40[10:8] */
2540 *value |= ((0x2 << 0) | (0x2 << 4) | (0x7 << 8) |
2541 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2542 break;
2543 case 2: /* DSCP-based 0x2x40[14:12] */
2544 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2545 (0x7 << 12) | (0x2 << 16) | (0x2 << 20));
2546 break;
2547 case 3: /* acl-based 0x2x40[2:0] */
2548 *value |= ((0x7 << 0) | (0x2 << 4) | (0x2 << 8) |
2549 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2550 break;
2551 case 4: /* arl-based 0x2x40[22:20] */
2552 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2553 (0x2 << 12) | (0x2 << 16) | (0x7 << 20));
2554 break;
2555 case 5: /* stag-based 0x2x40[6:4] */
2556 *value |= ((0x2 << 0) | (0x7 << 4) | (0x2 << 8) |
2557 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2558 break;
2559 default:
2560 break;
developerfd40db22021-04-29 10:08:25 +08002561 }
2562}
2563
2564void qos_set_base(int argc, char *argv[])
2565{
2566 unsigned char base = 0;
developerbe40a9e2024-03-07 21:44:26 +08002567 unsigned char port = 0;
2568 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08002569
2570 if (argc < 5)
2571 return;
2572
2573 port = atoi(argv[3]);
2574 base = atoi(argv[4]);
2575
2576 if (base > 6) {
2577 printf(HELP_QOS_BASE);
2578 return;
2579 }
2580
2581 if (port > 6) {
developerbe40a9e2024-03-07 21:44:26 +08002582 printf("Illegal port index:%d\n", port);
developerfd40db22021-04-29 10:08:25 +08002583 return;
2584 }
2585
2586 printf("\r\nswitch qos base : %d. (port-based:0, tag-based:1,\
developerbe40a9e2024-03-07 21:44:26 +08002587 dscp-based:2, acl-based:3, arl-based:4, stag-based:5)\n", base);
developerfd40db22021-04-29 10:08:25 +08002588 if (chip_name == 0x7530) {
2589
2590 reg_read(0x44, &value);
2591 get_upw(&value, base);
2592 reg_write(0x44, value);
2593 printf("reg: 0x44, value: 0x%x\n", value);
2594
developer8c3871b2022-07-01 14:07:53 +08002595 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002596
2597 reg_read(GSW_UPW(port), &value);
2598 get_upw(&value, base);
2599 reg_write(GSW_UPW(port), value);
developerbe40a9e2024-03-07 21:44:26 +08002600 printf("reg:0x%x, value: 0x%x\n", GSW_UPW(port), value);
developerfd40db22021-04-29 10:08:25 +08002601
2602 } else {
2603 printf("unknown switch device");
2604 return;
2605 }
2606}
2607
2608void qos_wfq_set_weight(int argc, char *argv[])
2609{
developerbe40a9e2024-03-07 21:44:26 +08002610 int port = 0, weight[8], i = 0;
2611 unsigned char queue = 0;
2612 unsigned int reg = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002613
2614 port = atoi(argv[3]);
2615
2616 for (i = 0; i < 8; i++) {
2617 weight[i] = atoi(argv[i + 4]);
2618 }
2619
2620 /* MT7530 total 7 port */
2621 if (port < 0 || port > 6) {
2622 printf(HELP_QOS_PORT_WEIGHT);
2623 return;
2624 }
2625
2626 for (i = 0; i < 8; i++) {
2627 if (weight[i] < 1 || weight[i] > 16) {
2628 printf(HELP_QOS_PORT_WEIGHT);
2629 return;
2630 }
2631 }
2632 printf("port: %x, q0: %x, q1: %x, q2: %x, q3: %x, \
developerbe40a9e2024-03-07 21:44:26 +08002633 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 +08002634
2635 for (queue = 0; queue < 8; queue++) {
2636 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2637 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002638 value &= (~(0xf << 24)); //bit24~27
developerfd40db22021-04-29 10:08:25 +08002639 value |= (((weight[queue] - 1) & 0xf) << 24);
2640 printf("reg: %x, value: %x\n", reg, value);
2641 reg_write(reg, value);
2642 }
2643}
2644
2645void qos_set_portpri(int argc, char *argv[])
2646{
developerbe40a9e2024-03-07 21:44:26 +08002647 unsigned char port = 0, prio = 0;
2648 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08002649
2650 port = atoi(argv[3]);
2651 prio = atoi(argv[4]);
2652
2653 if (port >= 7 || prio > 7) {
2654 printf(HELP_QOS_PORT_PRIO);
2655 return;
2656 }
2657
2658 reg_read(GSW_PCR(port), &value);
2659 value &= (~(0x7 << 24));
2660 value |= (prio << 24);
2661 reg_write(GSW_PCR(port), value);
2662 printf("write reg: %x, value: %x\n", GSW_PCR(port), value);
2663}
2664
2665void qos_set_dscppri(int argc, char *argv[])
2666{
developerbe40a9e2024-03-07 21:44:26 +08002667 unsigned char prio = 0, dscp = 0, pim_n = 0, pim_offset = 0;
2668 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08002669
2670 dscp = atoi(argv[3]);
2671 prio = atoi(argv[4]);
2672
2673 if (dscp > 63 || prio > 7) {
2674 printf(HELP_QOS_DSCP_PRIO);
2675 return;
2676 }
2677
2678 pim_n = dscp / 10;
2679 pim_offset = (dscp - pim_n * 10) * 3;
2680 reg = 0x0058 + pim_n * 4;
2681 reg_read(reg, &value);
2682 value &= (~(0x7 << pim_offset));
2683 value |= ((prio & 0x7) << pim_offset);
2684 reg_write(reg, value);
2685 printf("write reg: %x, value: %x\n", reg, value);
2686}
2687
2688void qos_pri_mapping_queue(int argc, char *argv[])
2689{
developerbe40a9e2024-03-07 21:44:26 +08002690 unsigned char prio = 0, queue = 0, pem_n = 0, port = 0;
2691 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08002692
2693 if (argc < 6)
2694 return;
2695
2696 port = atoi(argv[3]);
2697 prio = atoi(argv[4]);
2698 queue = atoi(argv[5]);
2699
2700 if (prio > 7 || queue > 7) {
2701 printf(HELP_QOS_PRIO_QMAP);
2702 return;
2703 }
developerbe40a9e2024-03-07 21:44:26 +08002704
developerfd40db22021-04-29 10:08:25 +08002705 if (chip_name == 0x7530) {
2706 pem_n = prio / 2;
2707 reg = pem_n * 0x4 + 0x48;
2708 reg_read(reg, &value);
2709 if (prio % 2) {
2710 value &= (~(0x7 << 24));
2711 value |= ((queue & 0x7) << 24);
2712 } else {
2713 value &= (~(0x7 << 8));
2714 value |= ((queue & 0x7) << 8);
2715 }
2716 reg_write(reg, value);
2717 printf("write reg: %x, value: %x\n", reg, value);
developer8c3871b2022-07-01 14:07:53 +08002718 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002719 pem_n = prio / 2;
2720 reg = GSW_PEM(pem_n) + 0x100 * port;
2721 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002722 if (prio % 2) { // 1 1
developerfd40db22021-04-29 10:08:25 +08002723 value &= (~(0x7 << 25));
2724 value |= ((queue & 0x7) << 25);
developerbe40a9e2024-03-07 21:44:26 +08002725 } else { // 0 0
developerfd40db22021-04-29 10:08:25 +08002726 value &= (~(0x7 << 9));
2727 value |= ((queue & 0x7) << 9);
2728 }
2729 reg_write(reg, value);
2730 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +08002731 } else {
developerfd40db22021-04-29 10:08:25 +08002732 printf("unknown switch device");
2733 return;
2734 }
2735}
2736
2737static int macMT753xVlanSetVid(unsigned char index, unsigned char active,
developerbe40a9e2024-03-07 21:44:26 +08002738 unsigned short vid, unsigned char portMap,
2739 unsigned char tagPortMap, unsigned char ivl_en,
2740 unsigned char fid, unsigned short stag)
developerfd40db22021-04-29 10:08:25 +08002741{
2742 unsigned int value = 0;
2743 unsigned int value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08002744 unsigned int reg = 0;
2745 int i = 0;
developerfd40db22021-04-29 10:08:25 +08002746
2747 printf("index: %x, active: %x, vid: %x, portMap: %x, \
developerbe40a9e2024-03-07 21:44:26 +08002748 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 +08002749
2750 value = (portMap << 16);
2751 value |= (stag << 4);
2752 value |= (ivl_en << 30);
2753 value |= (fid << 1);
2754 value |= (active ? 1 : 0);
2755
2756 // total 7 ports
2757 for (i = 0; i < 7; i++) {
2758 if (tagPortMap & (1 << i))
2759 value2 |= 0x2 << (i * 2);
2760 }
2761
2762 if (value2)
developerbe40a9e2024-03-07 21:44:26 +08002763 value |= (1 << 28); // eg_tag
developerfd40db22021-04-29 10:08:25 +08002764
developerbe40a9e2024-03-07 21:44:26 +08002765 reg = 0x98; // VAWD2
developerfd40db22021-04-29 10:08:25 +08002766 reg_write(reg, value2);
2767
developerbe40a9e2024-03-07 21:44:26 +08002768 reg = 0x94; // VAWD1
developerfd40db22021-04-29 10:08:25 +08002769 reg_write(reg, value);
2770
developerbe40a9e2024-03-07 21:44:26 +08002771 reg = 0x90; // VTCR
developerfd40db22021-04-29 10:08:25 +08002772 value = (0x80001000 + vid);
2773 reg_write(reg, value);
2774
developerbe40a9e2024-03-07 21:44:26 +08002775 reg = 0x90; // VTCR
developerfd40db22021-04-29 10:08:25 +08002776 while (1) {
2777 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002778 if ((value & 0x80000000) == 0) //table busy
developerfd40db22021-04-29 10:08:25 +08002779 break;
2780 }
2781
2782 /* switch clear */
2783 reg = 0x80;
2784 reg_write(reg, 0x8002);
2785 usleep(5000);
2786 reg_read(reg, &value);
2787
2788 printf("SetVid: index:%d active:%d vid:%d portMap:%x tagPortMap:%x\r\n",
2789 index, active, vid, portMap, tagPortMap);
2790 return 0;
2791
developerbe40a9e2024-03-07 21:44:26 +08002792} /*end macMT753xVlanSetVid */
developerfd40db22021-04-29 10:08:25 +08002793
2794static int macMT753xVlanSetPvid(unsigned char port, unsigned short pvid)
2795{
developerbe40a9e2024-03-07 21:44:26 +08002796 unsigned int value = 0;
2797 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08002798
developerbe40a9e2024-03-07 21:44:26 +08002799 /*Parameters is error */
developerfd40db22021-04-29 10:08:25 +08002800 if (port > 6)
2801 return -1;
2802
2803 reg = 0x2014 + (port * 0x100);
2804 reg_read(reg, &value);
2805 value &= ~0xfff;
2806 value |= pvid;
2807 reg_write(reg, value);
2808
2809 /* switch clear */
2810 reg = 0x80;
2811 reg_write(reg, 0x8002);
2812 usleep(5000);
2813 reg_read(reg, &value);
2814
2815 printf("SetPVID: port:%d pvid:%d\r\n", port, pvid);
2816 return 0;
2817}
developerfd40db22021-04-29 10:08:25 +08002818
2819void doVlanSetPvid(int argc, char *argv[])
2820{
2821 unsigned char port = 0;
2822 unsigned short pvid = 0;
2823
2824 port = atoi(argv[3]);
2825 pvid = atoi(argv[4]);
developerbe40a9e2024-03-07 21:44:26 +08002826 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002827 if ((port >= SWITCH_MAX_PORT) || (pvid > MAX_VID_VALUE)) {
2828 printf(HELP_VLAN_PVID);
2829 return;
2830 }
2831
2832 macMT753xVlanSetPvid(port, pvid);
2833
2834 printf("port:%d pvid:%d,vlancap: max_port:%d maxvid:%d\r\n",
2835 port, pvid, SWITCH_MAX_PORT, MAX_VID_VALUE);
developerbe40a9e2024-03-07 21:44:26 +08002836} /*end doVlanSetPvid */
developerfd40db22021-04-29 10:08:25 +08002837
2838void doVlanSetVid(int argc, char *argv[])
2839{
2840 unsigned char index = 0;
2841 unsigned char active = 0;
2842 unsigned char portMap = 0;
2843 unsigned char tagPortMap = 0;
2844 unsigned short vid = 0;
2845
2846 unsigned char ivl_en = 0;
2847 unsigned char fid = 0;
2848 unsigned short stag = 0;
2849
2850 index = atoi(argv[3]);
2851 active = atoi(argv[4]);
2852 vid = atoi(argv[5]);
2853
developerbe40a9e2024-03-07 21:44:26 +08002854 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002855 if ((index >= MAX_VLAN_RULE) || (vid >= 4096) || (active > ACTIVED)) {
2856 printf(HELP_VLAN_VID);
2857 return;
2858 }
2859
developerbe40a9e2024-03-07 21:44:26 +08002860 /*CPU Port is always the membership */
developerfd40db22021-04-29 10:08:25 +08002861 portMap = atoi(argv[6]);
2862 tagPortMap = atoi(argv[7]);
2863
2864 printf("subcmd parameter argc = %d\r\n", argc);
2865 if (argc >= 9) {
2866 ivl_en = atoi(argv[8]);
2867 if (argc >= 10) {
2868 fid = atoi(argv[9]);
2869 if (argc >= 11)
2870 stag = atoi(argv[10]);
2871 }
2872 }
2873 macMT753xVlanSetVid(index, active, vid, portMap, tagPortMap,
2874 ivl_en, fid, stag);
2875 printf("index:%d active:%d vid:%d\r\n", index, active, vid);
developerbe40a9e2024-03-07 21:44:26 +08002876} /*end doVlanSetVid */
developerfd40db22021-04-29 10:08:25 +08002877
2878void doVlanSetAccFrm(int argc, char *argv[])
2879{
2880 unsigned char port = 0;
2881 unsigned char type = 0;
developerbe40a9e2024-03-07 21:44:26 +08002882 unsigned int value = 0;
2883 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08002884
2885 port = atoi(argv[3]);
2886 type = atoi(argv[4]);
2887
2888 printf("port: %d, type: %d\n", port, type);
2889
developerbe40a9e2024-03-07 21:44:26 +08002890 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002891 if ((port > SWITCH_MAX_PORT) || (type > REG_PVC_ACC_FRM_RELMASK)) {
2892 printf(HELP_VLAN_ACC_FRM);
2893 return;
2894 }
2895
2896 reg = REG_PVC_P0_ADDR + port * 0x100;
2897 reg_read(reg, &value);
2898 value &= (~REG_PVC_ACC_FRM_MASK);
2899 value |= ((unsigned int)type << REG_PVC_ACC_FRM_OFFT);
2900
2901 printf("write reg: %x, value: %x\n", reg, value);
2902 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08002903} /*end doVlanSetAccFrm */
developerfd40db22021-04-29 10:08:25 +08002904
2905void doVlanSetPortAttr(int argc, char *argv[])
2906{
2907 unsigned char port = 0;
2908 unsigned char attr = 0;
developerbe40a9e2024-03-07 21:44:26 +08002909 unsigned int value = 0;
2910 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08002911
2912 port = atoi(argv[3]);
2913 attr = atoi(argv[4]);
2914
2915 printf("port: %x, attr: %x\n", port, attr);
2916
developerbe40a9e2024-03-07 21:44:26 +08002917 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002918 if (port > SWITCH_MAX_PORT || attr > 3) {
2919 printf(HELP_VLAN_PORT_ATTR);
2920 return;
2921 }
2922
2923 reg = 0x2010 + port * 0x100;
2924 reg_read(reg, &value);
2925 value &= (0xffffff3f);
2926 value |= (attr << 6);
2927
2928 printf("write reg: %x, value: %x\n", reg, value);
2929 reg_write(reg, value);
2930}
2931
2932void doVlanSetPortMode(int argc, char *argv[])
2933{
2934 unsigned char port = 0;
2935 unsigned char mode = 0;
developerbe40a9e2024-03-07 21:44:26 +08002936 unsigned int value = 0;
2937 unsigned int reg = 0;
2938
developerfd40db22021-04-29 10:08:25 +08002939 port = atoi(argv[3]);
2940 mode = atoi(argv[4]);
2941 printf("port: %x, mode: %x\n", port, mode);
2942
developerbe40a9e2024-03-07 21:44:26 +08002943 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002944 if (port > SWITCH_MAX_PORT || mode > 3) {
2945 printf(HELP_VLAN_PORT_MODE);
2946 return;
2947 }
2948
2949 reg = 0x2004 + port * 0x100;
2950 reg_read(reg, &value);
2951 value &= (~((1 << 0) | (1 << 1)));
2952 value |= (mode & 0x3);
2953 printf("write reg: %x, value: %x\n", reg, value);
2954 reg_write(reg, value);
2955}
2956
2957void doVlanSetEgressTagPCR(int argc, char *argv[])
2958{
2959 unsigned char port = 0;
2960 unsigned char eg_tag = 0;
developerbe40a9e2024-03-07 21:44:26 +08002961 unsigned int value = 0;
2962 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08002963
2964 port = atoi(argv[3]);
2965 eg_tag = atoi(argv[4]);
2966
2967 printf("port: %d, eg_tag: %d\n", port, eg_tag);
2968
developerbe40a9e2024-03-07 21:44:26 +08002969 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002970 if ((port > SWITCH_MAX_PORT) || (eg_tag > REG_PCR_EG_TAG_RELMASK)) {
2971 printf(HELP_VLAN_EGRESS_TAG_PCR);
2972 return;
2973 }
2974
2975 reg = REG_PCR_P0_ADDR + port * 0x100;
2976 reg_read(reg, &value);
2977 value &= (~REG_PCR_EG_TAG_MASK);
2978 value |= ((unsigned int)eg_tag << REG_PCR_EG_TAG_OFFT);
2979
2980 printf("write reg: %x, value: %x\n", reg, value);
2981 reg_write(reg, value);
2982
developerbe40a9e2024-03-07 21:44:26 +08002983} /*end doVlanSetEgressTagPCR */
developerfd40db22021-04-29 10:08:25 +08002984
2985void doVlanSetEgressTagPVC(int argc, char *argv[])
2986{
2987 unsigned char port = 0;
2988 unsigned char eg_tag = 0;
developerbe40a9e2024-03-07 21:44:26 +08002989 unsigned int value = 0;
2990 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08002991
2992 port = atoi(argv[3]);
2993 eg_tag = atoi(argv[4]);
2994
2995 printf("port: %d, eg_tag: %d\n", port, eg_tag);
2996
developerbe40a9e2024-03-07 21:44:26 +08002997 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002998 if ((port > SWITCH_MAX_PORT) || (eg_tag > REG_PVC_EG_TAG_RELMASK)) {
2999 printf(HELP_VLAN_EGRESS_TAG_PVC);
3000 return;
3001 }
3002
3003 reg = REG_PVC_P0_ADDR + port * 0x100;
3004 reg_read(reg, &value);
3005 value &= (~REG_PVC_EG_TAG_MASK);
3006 value |= ((unsigned int)eg_tag << REG_PVC_EG_TAG_OFFT);
3007
3008 printf("write reg: %x, value: %x\n", reg, value);
3009 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003010} /*end doVlanSetEgressTagPVC */
developerfd40db22021-04-29 10:08:25 +08003011
3012void doArlAging(int argc, char *argv[])
3013{
3014 unsigned char aging_en = 0;
developerbe40a9e2024-03-07 21:44:26 +08003015 unsigned int time = 0, aging_cnt = 0, aging_unit = 0, value = 0, reg =
3016 0;
developerfd40db22021-04-29 10:08:25 +08003017
3018 aging_en = atoi(argv[3]);
3019 time = atoi(argv[4]);
3020 printf("aging_en: %x, aging time: %x\n", aging_en, time);
3021
developerbe40a9e2024-03-07 21:44:26 +08003022 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003023 if ((aging_en != 0 && aging_en != 1) || (time <= 0 || time > 65536)) {
3024 printf(HELP_ARL_AGING);
3025 return;
3026 }
3027
3028 reg = 0xa0;
3029 reg_read(reg, &value);
3030 value &= (~(1 << 20));
3031 if (!aging_en) {
3032 value |= (1 << 20);
3033 }
3034
3035 aging_unit = (time / 0x100) + 1;
3036 aging_cnt = (time / aging_unit);
3037 aging_unit--;
3038 aging_cnt--;
3039
3040 value &= (0xfff00000);
3041 value |= ((aging_cnt << 12) | aging_unit);
3042
3043 printf("aging_unit: %x, aging_cnt: %x\n", aging_unit, aging_cnt);
3044 printf("write reg: %x, value: %x\n", reg, value);
3045
3046 reg_write(reg, value);
3047}
3048
3049void doMirrorEn(int argc, char *argv[])
3050{
developerbe40a9e2024-03-07 21:44:26 +08003051 unsigned char mirror_en = 0;
3052 unsigned char mirror_port = 0;
3053 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003054
3055 mirror_en = atoi(argv[3]);
3056 mirror_port = atoi(argv[4]);
3057
3058 printf("mirror_en: %d, mirror_port: %d\n", mirror_en, mirror_port);
3059
developerbe40a9e2024-03-07 21:44:26 +08003060 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003061 if ((mirror_en > 1) || (mirror_port > REG_CFC_MIRROR_PORT_RELMASK)) {
3062 printf(HELP_MIRROR_EN);
3063 return;
3064 }
3065
3066 reg = REG_CFC_ADDR;
3067 reg_read(reg, &value);
3068 value &= (~REG_CFC_MIRROR_EN_MASK);
3069 value |= (mirror_en << REG_CFC_MIRROR_EN_OFFT);
3070 value &= (~REG_CFC_MIRROR_PORT_MASK);
3071 value |= (mirror_port << REG_CFC_MIRROR_PORT_OFFT);
3072
3073 printf("write reg: %x, value: %x\n", reg, value);
3074 reg_write(reg, value);
3075
developerbe40a9e2024-03-07 21:44:26 +08003076} /*end doMirrorEn */
developerfd40db22021-04-29 10:08:25 +08003077
3078void doMirrorPortBased(int argc, char *argv[])
3079{
developerbe40a9e2024-03-07 21:44:26 +08003080 unsigned char port = 0, port_tx_mir = 0, port_rx_mir = 0, vlan_mis =
3081 0, acl_mir = 0, igmp_mir = 0;
3082 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003083
3084 port = atoi(argv[3]);
3085 port_tx_mir = atoi(argv[4]);
3086 port_rx_mir = atoi(argv[5]);
3087 acl_mir = atoi(argv[6]);
3088 vlan_mis = atoi(argv[7]);
3089 igmp_mir = atoi(argv[8]);
3090
developerbe40a9e2024-03-07 21:44:26 +08003091 printf
3092 ("port:%d, port_tx_mir:%d, port_rx_mir:%d, acl_mir:%d, vlan_mis:%d, igmp_mir:%d\n",
3093 port, port_tx_mir, port_rx_mir, acl_mir, vlan_mis, igmp_mir);
developerfd40db22021-04-29 10:08:25 +08003094
developerbe40a9e2024-03-07 21:44:26 +08003095 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003096 //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 +08003097 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 +08003098 printf(HELP_MIRROR_PORTBASED);
3099 return;
3100 }
3101
3102 reg = REG_PCR_P0_ADDR + port * 0x100;
3103 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003104 value &=
3105 ~(REG_PORT_TX_MIR_MASK | REG_PORT_RX_MIR_MASK | REG_PCR_ACL_MIR_MASK
3106 | REG_PCR_VLAN_MIS_MASK);
3107 value |=
3108 (port_tx_mir << REG_PORT_TX_MIR_OFFT) +
3109 (port_rx_mir << REG_PORT_RX_MIR_OFFT);
3110 value |=
3111 (acl_mir << REG_PCR_ACL_MIR_OFFT) +
3112 (vlan_mis << REG_PCR_VLAN_MIS_OFFT);
developerfd40db22021-04-29 10:08:25 +08003113
3114 printf("write reg: %x, value: %x\n", reg, value);
3115 reg_write(reg, value);
3116
3117 reg = REG_PIC_P0_ADDR + port * 0x100;
3118 reg_read(reg, &value);
3119 value &= ~(REG_PIC_IGMP_MIR_MASK);
3120 value |= (igmp_mir << REG_PIC_IGMP_MIR_OFFT);
3121
3122 printf("write reg: %x, value: %x\n", reg, value);
3123 reg_write(reg, value);
3124
developerbe40a9e2024-03-07 21:44:26 +08003125} /*end doMirrorPortBased */
developerfd40db22021-04-29 10:08:25 +08003126
3127void doStp(int argc, char *argv[])
3128{
3129 unsigned char port = 0;
3130 unsigned char fid = 0;
3131 unsigned char state = 0;
developerbe40a9e2024-03-07 21:44:26 +08003132 unsigned int value = 0;
3133 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08003134
3135 port = atoi(argv[2]);
3136 fid = atoi(argv[3]);
3137 state = atoi(argv[4]);
3138
3139 printf("port: %d, fid: %d, state: %d\n", port, fid, state);
3140
developerbe40a9e2024-03-07 21:44:26 +08003141 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003142 if ((port > MAX_PORT + 1) || (fid > 7) || (state > 3)) {
3143 printf(HELP_STP);
3144 return;
3145 }
3146
3147 reg = REG_SSC_P0_ADDR + port * 0x100;
3148 reg_read(reg, &value);
3149 value &= (~(3 << (fid << 2)));
3150 value |= ((unsigned int)state << (fid << 2));
3151
3152 printf("write reg: %x, value: %x\n", reg, value);
3153 reg_write(reg, value);
3154}
3155
developerbe40a9e2024-03-07 21:44:26 +08003156void _ingress_rate_set(int on_off, int port, int bw)
developerfd40db22021-04-29 10:08:25 +08003157{
developerbe40a9e2024-03-07 21:44:26 +08003158 unsigned int reg = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08003159
3160 reg = 0x1800 + (0x100 * port);
3161 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08003162 /*token-bucket */
developerfd40db22021-04-29 10:08:25 +08003163 if (on_off == 1) {
3164 if (chip_name == 0x7530) {
3165 if (bw > 1000000) {
developerbe40a9e2024-03-07 21:44:26 +08003166 printf
3167 ("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",
3168 bw);
3169 return;
developerfd40db22021-04-29 10:08:25 +08003170 }
developerbe40a9e2024-03-07 21:44:26 +08003171 value =
3172 ((bw / 32) << 16) + (1 << 15) + (7 << 8) +
3173 (1 << 7) + 0x0f;
developer8c3871b2022-07-01 14:07:53 +08003174 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3175 if ((chip_name == 0x7531) && (bw > 2500000)) {
developerbe40a9e2024-03-07 21:44:26 +08003176 printf
3177 ("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",
3178 bw);
3179 return;
developerfd40db22021-04-29 10:08:25 +08003180 }
developer8c3871b2022-07-01 14:07:53 +08003181
3182 if ((chip_name == 0x7988) && (bw > 4000000)) {
developerbe40a9e2024-03-07 21:44:26 +08003183 printf
3184 ("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",
3185 bw);
3186 return;
developerfd40db22021-04-29 10:08:25 +08003187 }
developer8c3871b2022-07-01 14:07:53 +08003188
developerbe40a9e2024-03-07 21:44:26 +08003189 if (bw / 32 >= 65536) //supoort 2.5G case
3190 value =
3191 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3192 (1 << 12) + (7 << 8) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003193 else
developerbe40a9e2024-03-07 21:44:26 +08003194 value =
3195 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3196 (7 << 8) + 0xf;
3197 } else
developerfd40db22021-04-29 10:08:25 +08003198 printf("unknow chip\n");
3199 }
developerfd40db22021-04-29 10:08:25 +08003200#if leaky_bucket
3201 reg_read(reg, &value);
3202 value &= 0xffff0000;
developerbe40a9e2024-03-07 21:44:26 +08003203 if (on_off == 1) {
developerfd40db22021-04-29 10:08:25 +08003204 value |= on_off << 15;
3205 //7530 same as 7531
3206 if (bw < 100) {
3207 value |= (0x0 << 8);
3208 value |= bw;
3209 } else if (bw < 1000) {
3210 value |= (0x1 << 8);
3211 value |= bw / 10;
3212 } else if (bw < 10000) {
3213 value |= (0x2 << 8);
3214 value |= bw / 100;
3215 } else if (bw < 100000) {
3216 value |= (0x3 << 8);
3217 value |= bw / 1000;
3218 } else {
3219 value |= (0x4 << 8);
3220 value |= bw / 10000;
3221 }
3222 }
3223#endif
3224 reg_write(reg, value);
3225 reg = 0x1FFC;
3226 reg_read(reg, &value);
3227 value = 0x110104;
3228 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003229
3230 if (on_off)
3231 printf("switch port=%d, bw=%d\n", port, bw);
3232 else
3233 printf("switch port=%d ingress rate limit off\n", port);
developerfd40db22021-04-29 10:08:25 +08003234}
3235
developerbe40a9e2024-03-07 21:44:26 +08003236void ingress_rate_set(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003237{
developerbe40a9e2024-03-07 21:44:26 +08003238 int on_off = 0, port = 0, bw = 0;
3239
3240 port = strtoul(argv[3], NULL, 0);
3241 if (argv[2][1] == 'n') {
3242 bw = strtoul(argv[4], NULL, 0);
3243 on_off = 1;
3244 } else if (argv[2][1] == 'f') {
3245 if (argc != 4)
3246 return;
3247 on_off = 0;
3248 }
3249
3250 _ingress_rate_set(on_off, port, bw);
3251}
3252
3253void _egress_rate_set(int on_off, int port, int bw)
3254{
3255 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003256
3257 reg = 0x1040 + (0x100 * port);
3258 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08003259 /*token-bucket */
developerfd40db22021-04-29 10:08:25 +08003260 if (on_off == 1) {
3261 if (chip_name == 0x7530) {
3262 if (bw < 0 || bw > 1000000) {
developerbe40a9e2024-03-07 21:44:26 +08003263 printf
3264 ("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",
3265 bw);
3266 return;
developerfd40db22021-04-29 10:08:25 +08003267 }
developerbe40a9e2024-03-07 21:44:26 +08003268 value =
3269 ((bw / 32) << 16) + (1 << 15) + (7 << 8) +
3270 (1 << 7) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003271 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3272 if ((chip_name == 0x7531) && (bw < 0 || bw > 2500000)) {
developerbe40a9e2024-03-07 21:44:26 +08003273 printf
3274 ("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",
3275 bw);
3276 return;
developerfd40db22021-04-29 10:08:25 +08003277 }
developer8c3871b2022-07-01 14:07:53 +08003278 if ((chip_name == 0x7988) && (bw < 0 || bw > 4000000)) {
developerbe40a9e2024-03-07 21:44:26 +08003279 printf
3280 ("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",
3281 bw);
3282 return;
developer8c3871b2022-07-01 14:07:53 +08003283 }
3284
developerbe40a9e2024-03-07 21:44:26 +08003285 if (bw / 32 >= 65536) //support 2.5G cases
3286 value =
3287 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3288 (1 << 12) + (7 << 8) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003289 else
developerbe40a9e2024-03-07 21:44:26 +08003290 value =
3291 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3292 (7 << 8) + 0xf;
3293 } else
developerfd40db22021-04-29 10:08:25 +08003294 printf("unknow chip\n");
3295 }
3296 reg_write(reg, value);
3297 reg = 0x10E0;
3298 reg_read(reg, &value);
3299 value &= 0x18;
3300 reg_write(reg, value);
3301
developerbe40a9e2024-03-07 21:44:26 +08003302 if (on_off)
3303 printf("switch port=%d, bw=%d\n", port, bw);
3304 else
3305 printf("switch port=%d egress rate limit off\n", port);
3306}
3307
3308void egress_rate_set(int argc, char *argv[])
3309{
3310 unsigned int value = 0, reg = 0;
3311 int on_off = 0, port = 0, bw = 0;
3312
3313 port = strtoul(argv[3], NULL, 0);
3314 if (argv[2][1] == 'n') {
3315 bw = strtoul(argv[4], NULL, 0);
3316 on_off = 1;
3317 } else if (argv[2][1] == 'f') {
3318 if (argc != 4)
3319 return;
3320 on_off = 0;
3321 }
3322
3323 _egress_rate_set(on_off, port, bw);
developerfd40db22021-04-29 10:08:25 +08003324}
3325
3326void rate_control(int argc, char *argv[])
3327{
3328 unsigned char dir = 0;
3329 unsigned char port = 0;
3330 unsigned int rate = 0;
3331
3332 dir = atoi(argv[2]);
3333 port = atoi(argv[3]);
3334 rate = atoi(argv[4]);
3335
3336 if (port > 6)
3337 return;
3338
developerbe40a9e2024-03-07 21:44:26 +08003339 if (dir == 1) //ingress
3340 _ingress_rate_set(1, port, rate);
3341 else if (dir == 0) //egress
3342 _egress_rate_set(1, port, rate);
developerfd40db22021-04-29 10:08:25 +08003343 else
3344 return;
3345}
3346
developerbe40a9e2024-03-07 21:44:26 +08003347void collision_pool_enable(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003348{
3349
developerbe40a9e2024-03-07 21:44:26 +08003350 unsigned char enable = 0;
3351 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003352
3353 enable = atoi(argv[3]);
3354
developerfd40db22021-04-29 10:08:25 +08003355 printf("collision pool enable: %d \n", enable);
3356
developerbe40a9e2024-03-07 21:44:26 +08003357 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003358 if (enable > 1) {
3359 printf(HELP_COLLISION_POOL_EN);
developerbe40a9e2024-03-07 21:44:26 +08003360 return;
developerfd40db22021-04-29 10:08:25 +08003361 }
3362
developer8c3871b2022-07-01 14:07:53 +08003363 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003364 reg = REG_CPGC_ADDR;
developerbe40a9e2024-03-07 21:44:26 +08003365 if (enable == 1) {
developerfd40db22021-04-29 10:08:25 +08003366 /* active reset */
3367 reg_read(reg, &value);
3368 value &= (~REG_CPCG_COL_RST_N_MASK);
3369 reg_write(reg, value);
3370
3371 /* enanble clock */
3372 reg_read(reg, &value);
3373 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3374 value |= (1 << REG_CPCG_COL_CLK_EN_OFFT);
3375 reg_write(reg, value);
3376
3377 /* inactive reset */
3378 reg_read(reg, &value);
3379 value &= (~REG_CPCG_COL_RST_N_MASK);
3380 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3381 reg_write(reg, value);
3382
3383 /* enable collision pool */
3384 reg_read(reg, &value);
3385 value &= (~REG_CPCG_COL_EN_MASK);
3386 value |= (1 << REG_CPCG_COL_EN_OFFT);
3387 reg_write(reg, value);
3388
3389 reg_read(reg, &value);
3390 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003391 } else {
developerfd40db22021-04-29 10:08:25 +08003392
3393 /* disable collision pool */
3394 reg_read(reg, &value);
3395 value &= (~REG_CPCG_COL_EN_MASK);
3396 reg_write(reg, value);
3397
3398 /* active reset */
3399 reg_read(reg, &value);
3400 value &= (~REG_CPCG_COL_RST_N_MASK);
3401 reg_write(reg, value);
3402
3403 /* inactive reset */
3404 reg_read(reg, &value);
3405 value &= (~REG_CPCG_COL_RST_N_MASK);
3406 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3407 reg_write(reg, value);
3408
3409 /* disable clock */
3410 reg_read(reg, &value);
3411 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3412 reg_write(reg, value);
3413
3414 reg_read(reg, &value);
3415 printf("write reg: %x, value: %x\n", reg, value);
3416
3417 }
developerbe40a9e2024-03-07 21:44:26 +08003418 } else {
developerfd40db22021-04-29 10:08:25 +08003419 printf("\nCommand not support by this chip.\n");
developerbe40a9e2024-03-07 21:44:26 +08003420 }
developerfd40db22021-04-29 10:08:25 +08003421}
3422
developerbe40a9e2024-03-07 21:44:26 +08003423void collision_pool_mac_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003424{
developerbe40a9e2024-03-07 21:44:26 +08003425 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003426
developer8c3871b2022-07-01 14:07:53 +08003427 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003428 reg = REG_CPGC_ADDR;
3429 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003430 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003431 table_dump_internal(COLLISION_TABLE);
3432 else
developerbe40a9e2024-03-07 21:44:26 +08003433 printf
3434 ("\ncollision pool is disabled, please enable it before use this command.\n");
3435 } else {
developerfd40db22021-04-29 10:08:25 +08003436 printf("\nCommand not support by this chip.\n");
3437 }
3438}
3439
developerbe40a9e2024-03-07 21:44:26 +08003440void collision_pool_dip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003441{
developerbe40a9e2024-03-07 21:44:26 +08003442 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003443
developer8c3871b2022-07-01 14:07:53 +08003444 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003445 reg = REG_CPGC_ADDR;
3446 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003447 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003448 dip_dump_internal(COLLISION_TABLE);
3449 else
developerbe40a9e2024-03-07 21:44:26 +08003450 printf
3451 ("\ncollision pool is disabled, please enable it before use this command.\n");
3452 } else {
developerfd40db22021-04-29 10:08:25 +08003453 printf("\nCommand not support by this chip.\n");
3454 }
developerfd40db22021-04-29 10:08:25 +08003455}
3456
developerbe40a9e2024-03-07 21:44:26 +08003457void collision_pool_sip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003458{
developerbe40a9e2024-03-07 21:44:26 +08003459 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003460
developerbe40a9e2024-03-07 21:44:26 +08003461 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003462 reg = REG_CPGC_ADDR;
3463 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003464 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003465 sip_dump_internal(COLLISION_TABLE);
3466 else
developerbe40a9e2024-03-07 21:44:26 +08003467 printf
3468 ("\ncollision pool is disabled, please enable it before use this command.\n");
3469 } else {
developerfd40db22021-04-29 10:08:25 +08003470 printf("\nCommand not support by this chip.\n");
3471 }
developerfd40db22021-04-29 10:08:25 +08003472}
3473
3474void pfc_get_rx_counter(int argc, char *argv[])
3475{
developerbe40a9e2024-03-07 21:44:26 +08003476 int port = 0;
3477 unsigned int value = 0, reg = 0;
3478 unsigned int user_pri = 0;
developerfd40db22021-04-29 10:08:25 +08003479
3480 port = strtoul(argv[3], NULL, 0);
3481 if (port < 0 || 6 < port) {
3482 printf("wrong port range, should be within 0~6\n");
3483 return;
3484 }
3485
developerbe40a9e2024-03-07 21:44:26 +08003486 if (chip_name == 0x7531 || chip_name == 0x7988) {
3487 reg = PFC_RX_COUNTER_L(port);
developerfd40db22021-04-29 10:08:25 +08003488 reg_read(reg, &value);
3489 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003490 printf("\n port %d rx pfc (up=0)pause on counter is %d.\n",
3491 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003492 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003493 printf("\n port %d rx pfc (up=1)pause on counter is %d.\n",
3494 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003495 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003496 printf("\n port %d rx pfc (up=2)pause on counter is %d.\n",
3497 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003498 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003499 printf("\n port %d rx pfc (up=3)pause on counter is %d.\n",
3500 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003501
developerbe40a9e2024-03-07 21:44:26 +08003502 reg = PFC_RX_COUNTER_H(port);
developerfd40db22021-04-29 10:08:25 +08003503 reg_read(reg, &value);
3504 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003505 printf("\n port %d rx pfc (up=4)pause on counter is %d.\n",
3506 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003507 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003508 printf("\n port %d rx pfc (up=5)pause on counter is %d.\n",
3509 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003510 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003511 printf("\n port %d rx pfc (up=6)pause on counter is %d.\n",
3512 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003513 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003514 printf("\n port %d rx pfc (up=7)pause on counter is %d.\n",
3515 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003516
3517 /* for rx counter could be updated successfully */
3518 reg_read(PMSR_P(port), &value);
3519 reg_read(PMSR_P(port), &value);
developerbe40a9e2024-03-07 21:44:26 +08003520 } else {
developerfd40db22021-04-29 10:08:25 +08003521 printf("\nCommand not support by this chip.\n");
3522 }
3523
3524}
3525
3526void pfc_get_tx_counter(int argc, char *argv[])
3527{
developerbe40a9e2024-03-07 21:44:26 +08003528 int port = 0;
3529 unsigned int value = 0, reg = 0;
3530 unsigned int user_pri = 0;
developerfd40db22021-04-29 10:08:25 +08003531
3532 port = strtoul(argv[3], NULL, 0);
3533 if (port < 0 || 6 < port) {
3534 printf("wrong port range, should be within 0~6\n");
3535 return;
3536 }
3537
developer8c3871b2022-07-01 14:07:53 +08003538 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerbe40a9e2024-03-07 21:44:26 +08003539 reg = PFC_TX_COUNTER_L(port);
developerfd40db22021-04-29 10:08:25 +08003540 reg_read(reg, &value);
3541 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003542 printf("\n port %d tx pfc (up=0)pause on counter is %d.\n",
3543 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003544 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003545 printf("\n port %d tx pfc (up=1)pause on counter is %d.\n",
3546 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003547 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003548 printf("\n port %d tx pfc (up=2)pause on counter is %d.\n",
3549 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003550 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003551 printf("\n port %d tx pfc (up=3)pause on counter is %d.\n",
3552 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003553
developerbe40a9e2024-03-07 21:44:26 +08003554 reg = PFC_TX_COUNTER_H(port);
developerfd40db22021-04-29 10:08:25 +08003555 reg_read(reg, &value);
3556 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003557 printf("\n port %d tx pfc (up=4)pause on counter is %d.\n",
3558 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003559 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003560 printf("\n port %d tx pfc (up=5)pause on counter is %d.\n",
3561 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003562 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003563 printf("\n port %d tx pfc (up=6)pause on counter is %d.\n",
3564 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003565 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003566 printf("\n port %d tx pfc (up=7)pause on counter is %d.\n",
3567 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003568
3569 /* for tx counter could be updated successfully */
3570 reg_read(PMSR_P(port), &value);
3571 reg_read(PMSR_P(port), &value);
developerbe40a9e2024-03-07 21:44:26 +08003572 } else {
3573 printf("\nCommand not support by this chip.\n");
developerfd40db22021-04-29 10:08:25 +08003574 }
3575}
3576
developerbe40a9e2024-03-07 21:44:26 +08003577void read_output_queue_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003578{
developerbe40a9e2024-03-07 21:44:26 +08003579 unsigned int port = 0;
3580 unsigned int value = 0, output_queue = 0;
3581 unsigned int base = 0x220;
developerfd40db22021-04-29 10:08:25 +08003582
3583 for (port = 0; port < 7; port++) {
developerbe40a9e2024-03-07 21:44:26 +08003584 reg_write(0x7038, base + (port * 4));
developerfd40db22021-04-29 10:08:25 +08003585 reg_read(0x7034, &value);
3586 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003587 printf("\n port %d output queue 0 counter is %d.\n", port,
3588 output_queue);
developerfd40db22021-04-29 10:08:25 +08003589 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003590 printf("\n port %d output queue 1 counter is %d.\n", port,
3591 output_queue);
developerfd40db22021-04-29 10:08:25 +08003592
developerbe40a9e2024-03-07 21:44:26 +08003593 reg_write(0x7038, base + (port * 4) + 1);
developerfd40db22021-04-29 10:08:25 +08003594 reg_read(0x7034, &value);
3595 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003596 printf("\n port %d output queue 2 counter is %d.\n", port,
3597 output_queue);
developerfd40db22021-04-29 10:08:25 +08003598 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003599 printf("\n port %d output queue 3 counter is %d.\n", port,
3600 output_queue);
developerfd40db22021-04-29 10:08:25 +08003601
developerbe40a9e2024-03-07 21:44:26 +08003602 reg_write(0x7038, base + (port * 4) + 2);
developerfd40db22021-04-29 10:08:25 +08003603 reg_read(0x7034, &value);
3604 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003605 printf("\n port %d output queue 4 counter is %d.\n", port,
3606 output_queue);
developerfd40db22021-04-29 10:08:25 +08003607 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003608 printf("\n port %d output queue 5 counter is %d.\n", port,
3609 output_queue);
developerfd40db22021-04-29 10:08:25 +08003610
developerbe40a9e2024-03-07 21:44:26 +08003611 reg_write(0x7038, base + (port * 4) + 3);
developerfd40db22021-04-29 10:08:25 +08003612 reg_read(0x7034, &value);
3613 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003614 printf("\n port %d output queue 6 counter is %d.\n", port,
3615 output_queue);
developerfd40db22021-04-29 10:08:25 +08003616 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003617 printf("\n port %d output queue 7 counter is %d.\n", port,
3618 output_queue);
developerfd40db22021-04-29 10:08:25 +08003619 }
3620}
3621
developerbe40a9e2024-03-07 21:44:26 +08003622void read_free_page_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003623{
developerbe40a9e2024-03-07 21:44:26 +08003624 unsigned int value = 0;
3625 unsigned int free_page = 0, free_page_last_read = 0;
3626 unsigned int fc_free_blk_lothd = 0, fc_free_blk_hithd = 0;
3627 unsigned int fc_port_blk_thd = 0, fc_port_blk_hi_thd = 0;
3628 unsigned int queue[8] = { 0 };
developerfd40db22021-04-29 10:08:25 +08003629
developer8c3871b2022-07-01 14:07:53 +08003630 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerbe40a9e2024-03-07 21:44:26 +08003631 /* get system free page link counter */
developerfd40db22021-04-29 10:08:25 +08003632 reg_read(0x1fc0, &value);
3633 free_page = value & 0xFFF;
3634 free_page_last_read = (value & 0xFFF0000) >> 16;
3635
3636 /* get system flow control waterwark */
3637 reg_read(0x1fe0, &value);
3638 fc_free_blk_lothd = value & 0x3FF;
3639 fc_free_blk_hithd = (value & 0x3FF0000) >> 16;
3640
3641 /* get port flow control waterwark */
3642 reg_read(0x1fe4, &value);
3643 fc_port_blk_thd = value & 0x3FF;
3644 fc_port_blk_hi_thd = (value & 0x3FF0000) >> 16;
3645
3646 /* get queue flow control waterwark */
3647 reg_read(0x1fe8, &value);
developerbe40a9e2024-03-07 21:44:26 +08003648 queue[0] = value & 0x3F;
3649 queue[1] = (value & 0x3F00) >> 8;
3650 queue[2] = (value & 0x3F0000) >> 16;
3651 queue[3] = (value & 0x3F000000) >> 24;
developerfd40db22021-04-29 10:08:25 +08003652 reg_read(0x1fec, &value);
developerbe40a9e2024-03-07 21:44:26 +08003653 queue[4] = value & 0x3F;
3654 queue[5] = (value & 0x3F00) >> 8;
3655 queue[6] = (value & 0x3F0000) >> 16;
3656 queue[7] = (value & 0x3F000000) >> 24;
developerfd40db22021-04-29 10:08:25 +08003657 } else {
developerbe40a9e2024-03-07 21:44:26 +08003658 /* get system free page link counter */
developerfd40db22021-04-29 10:08:25 +08003659 reg_read(0x1fc0, &value);
3660 free_page = value & 0x3FF;
3661 free_page_last_read = (value & 0x3FF0000) >> 16;
3662
3663 /* get system flow control waterwark */
3664 reg_read(0x1fe0, &value);
3665 fc_free_blk_lothd = value & 0xFF;
3666 fc_free_blk_hithd = (value & 0xFF00) >> 8;
3667
3668 /* get port flow control waterwark */
3669 reg_read(0x1fe0, &value);
3670 fc_port_blk_thd = (value & 0xFF0000) >> 16;
3671 reg_read(0x1ff4, &value);
3672 fc_port_blk_hi_thd = (value & 0xFF00) >> 8;
3673
3674 /* get queue flow control waterwark */
3675 reg_read(0x1fe4, &value);
developerbe40a9e2024-03-07 21:44:26 +08003676 queue[0] = value & 0xF;
3677 queue[1] = (value & 0xF0) >> 4;
3678 queue[2] = (value & 0xF00) >> 8;
3679 queue[3] = (value & 0xF000) >> 12;
3680 queue[4] = (value & 0xF0000) >> 16;
3681 queue[5] = (value & 0xF00000) >> 20;
3682 queue[6] = (value & 0xF000000) >> 24;
3683 queue[7] = (value & 0xF0000000) >> 28;
developerfd40db22021-04-29 10:08:25 +08003684 }
3685
developerbe40a9e2024-03-07 21:44:26 +08003686 printf("<===Free Page=======Current=======Last Read access=====>\n");
3687 printf("\n");
3688 printf(" page counter %u %u\n ",
3689 free_page, free_page_last_read);
3690 printf("\n ");
3691 printf("=========================================================\n");
3692 printf("<===Type=======High threshold======Low threshold=========\n");
3693 printf("\n ");
3694 printf(" system: %u %u\n",
3695 fc_free_blk_hithd * 2, fc_free_blk_lothd * 2);
3696 printf(" port: %u %u\n",
3697 fc_port_blk_hi_thd * 2, fc_port_blk_thd * 2);
3698 printf(" queue 0: %u NA\n",
3699 queue[0]);
3700 printf(" queue 1: %u NA\n",
3701 queue[1]);
3702 printf(" queue 2: %u NA\n",
3703 queue[2]);
3704 printf(" queue 3: %u NA\n",
3705 queue[3]);
3706 printf(" queue 4: %u NA\n",
3707 queue[4]);
3708 printf(" queue 5: %u NA\n",
3709 queue[5]);
3710 printf(" queue 6: %u NA\n",
3711 queue[6]);
3712 printf(" queue 7: %u NA\n",
3713 queue[7]);
3714 printf("=========================================================\n");
developerfd40db22021-04-29 10:08:25 +08003715}
3716
3717void eee_enable(int argc, char *argv[])
3718{
developerbe40a9e2024-03-07 21:44:26 +08003719 unsigned long enable = 0;
3720 unsigned int value = 0;
3721 unsigned int eee_cap = 0;
developerfd40db22021-04-29 10:08:25 +08003722 unsigned int eee_en_bitmap = 0;
developerbe40a9e2024-03-07 21:44:26 +08003723 unsigned long port_map = 0;
developerfd40db22021-04-29 10:08:25 +08003724 long port_num = -1;
developerbe40a9e2024-03-07 21:44:26 +08003725 int p = 0;
developerfd40db22021-04-29 10:08:25 +08003726
3727 if (argc < 3)
3728 goto error;
3729
developerbe40a9e2024-03-07 21:44:26 +08003730 /* Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003731 if (!strncmp(argv[2], "enable", 7))
3732 enable = 1;
3733 else if (!strncmp(argv[2], "disable", 8))
3734 enable = 0;
3735 else
3736 goto error;
3737
3738 if (argc > 3) {
3739 if (strlen(argv[3]) == 1) {
3740 port_num = strtol(argv[3], (char **)NULL, 10);
3741 if (port_num < 0 || port_num > MAX_PHY_PORT - 1) {
3742 printf("Illegal port index and port:0~4\n");
3743 goto error;
3744 }
3745 port_map = 1 << port_num;
3746 } else if (strlen(argv[3]) == 5) {
3747 port_map = 0;
3748 for (p = 0; p < MAX_PHY_PORT; p++) {
3749 if (argv[3][p] != '0' && argv[3][p] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08003750 printf
3751 ("portmap format error, should be combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08003752 goto error;
3753 }
3754 port_map |= ((argv[3][p] - '0') << p);
3755 }
3756 } else {
developerbe40a9e2024-03-07 21:44:26 +08003757 printf
3758 ("port_no or portmap format error, should be length of 1 or 5\n");
developerfd40db22021-04-29 10:08:25 +08003759 goto error;
3760 }
3761 } else {
3762 port_map = 0x1f;
3763 }
3764
developerbe40a9e2024-03-07 21:44:26 +08003765 eee_cap = (enable) ? 6 : 0;
developerfd40db22021-04-29 10:08:25 +08003766 for (p = 0; p < MAX_PHY_PORT; p++) {
3767 /* port_map describe p0p1p2p3p4 from left to rignt */
developerbe40a9e2024-03-07 21:44:26 +08003768 if (!!(port_map & (1 << p)))
developerfd40db22021-04-29 10:08:25 +08003769 mii_mgr_c45_write(p, 0x7, 0x3c, eee_cap);
3770
3771 mii_mgr_c45_read(p, 0x7, 0x3c, &value);
3772 /* mt7531: Always readback eee_cap = 0 when global EEE switch
3773 * is turned off.
3774 */
3775 if (value | eee_cap)
3776 eee_en_bitmap |= (1 << (MAX_PHY_PORT - 1 - p));
3777 }
3778
3779 /* Turn on/off global EEE switch */
developer8c3871b2022-07-01 14:07:53 +08003780 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003781 mii_mgr_c45_read(0, 0x1f, 0x403, &value);
3782 if (eee_en_bitmap)
3783 value |= (1 << 6);
3784 else
3785 value &= ~(1 << 6);
3786 mii_mgr_c45_write(0, 0x1f, 0x403, value);
3787 } else {
3788 printf("\nCommand not support by this chip.\n");
3789 }
3790
developerbe40a9e2024-03-07 21:44:26 +08003791 printf("EEE(802.3az) %s", (enable) ? "enable" : "disable");
developerfd40db22021-04-29 10:08:25 +08003792 if (argc == 4) {
3793 if (port_num >= 0)
3794 printf(" port%ld", port_num);
3795 else
3796 printf(" port_map: %s", argv[3]);
3797 } else {
3798 printf(" all ports");
3799 }
3800 printf("\n");
3801
3802 return;
3803error:
3804 printf(HELP_EEE_EN);
3805 return;
3806}
3807
3808void eee_dump(int argc, char *argv[])
3809{
developerbe40a9e2024-03-07 21:44:26 +08003810 unsigned int cap = 0, lp_cap = 0;
developerfd40db22021-04-29 10:08:25 +08003811 long port = -1;
developerbe40a9e2024-03-07 21:44:26 +08003812 int p = 0;
developerfd40db22021-04-29 10:08:25 +08003813
3814 if (argc > 3) {
3815 if (strlen(argv[3]) > 1) {
3816 printf("port# format error, should be of length 1\n");
3817 return;
3818 }
3819
3820 port = strtol(argv[3], (char **)NULL, 0);
3821 if (port < 0 || port > MAX_PHY_PORT) {
3822 printf("port# format error, should be 0 to %d\n",
developerbe40a9e2024-03-07 21:44:26 +08003823 MAX_PHY_PORT);
developerfd40db22021-04-29 10:08:25 +08003824 return;
3825 }
3826 }
3827
3828 for (p = 0; p < MAX_PHY_PORT; p++) {
3829 if (port >= 0 && p != port)
3830 continue;
3831
3832 mii_mgr_c45_read(p, 0x7, 0x3c, &cap);
3833 mii_mgr_c45_read(p, 0x7, 0x3d, &lp_cap);
3834 printf("port%d EEE cap=0x%02x, link partner EEE cap=0x%02x",
3835 p, cap, lp_cap);
3836
3837 if (port >= 0 && p == port) {
3838 mii_mgr_c45_read(p, 0x3, 0x1, &cap);
3839 printf(", st=0x%03x", cap);
3840 }
3841 printf("\n");
3842 }
3843}
3844
3845void dump_each_port(unsigned int base)
3846{
3847 unsigned int pkt_cnt = 0;
3848 int i = 0;
3849
3850 for (i = 0; i < 7; i++) {
developer0dea3402022-10-14 13:41:11 +08003851 if (chip_name == 0x7988) {
3852 if ((base == 0x402C) && (i == 6))
3853 base = 0x408C;
3854 else if ((base == 0x408C) && (i == 6))
3855 base = 0x402C;
3856 else
3857 ;
3858 }
developerfd40db22021-04-29 10:08:25 +08003859 reg_read((base) + (i * 0x100), &pkt_cnt);
3860 printf("%8u ", pkt_cnt);
3861 }
3862 printf("\n");
3863}
3864
developerbe40a9e2024-03-07 21:44:26 +08003865void read_mib_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003866{
3867 printf("===================== %8s %8s %8s %8s %8s %8s %8s\n",
3868 "Port0", "Port1", "Port2", "Port3", "Port4", "Port5", "Port6");
3869 printf("Tx Drop Packet :");
3870 dump_each_port(0x4000);
3871 printf("Tx CRC Error :");
3872 dump_each_port(0x4004);
3873 printf("Tx Unicast Packet :");
3874 dump_each_port(0x4008);
3875 printf("Tx Multicast Packet :");
3876 dump_each_port(0x400C);
3877 printf("Tx Broadcast Packet :");
3878 dump_each_port(0x4010);
3879 printf("Tx Collision Event :");
3880 dump_each_port(0x4014);
3881 printf("Tx Pause Packet :");
3882 dump_each_port(0x402C);
3883 printf("Rx Drop Packet :");
3884 dump_each_port(0x4060);
3885 printf("Rx Filtering Packet :");
3886 dump_each_port(0x4064);
3887 printf("Rx Unicast Packet :");
3888 dump_each_port(0x4068);
3889 printf("Rx Multicast Packet :");
3890 dump_each_port(0x406C);
3891 printf("Rx Broadcast Packet :");
3892 dump_each_port(0x4070);
3893 printf("Rx Alignment Error :");
3894 dump_each_port(0x4074);
3895 printf("Rx CRC Error :");
3896 dump_each_port(0x4078);
3897 printf("Rx Undersize Error :");
3898 dump_each_port(0x407C);
3899 printf("Rx Fragment Error :");
3900 dump_each_port(0x4080);
3901 printf("Rx Oversize Error :");
3902 dump_each_port(0x4084);
3903 printf("Rx Jabber Error :");
3904 dump_each_port(0x4088);
3905 printf("Rx Pause Packet :");
3906 dump_each_port(0x408C);
3907}
3908
developerbe40a9e2024-03-07 21:44:26 +08003909void clear_mib_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003910{
3911 reg_write(0x4fe0, 0xf0);
developerbe40a9e2024-03-07 21:44:26 +08003912 read_mib_counters(argc, argv);
developerfd40db22021-04-29 10:08:25 +08003913 reg_write(0x4fe0, 0x800000f0);
3914}
3915
developerfd40db22021-04-29 10:08:25 +08003916void exit_free()
3917{
3918 free(attres);
3919 attres = NULL;
3920 switch_ioctl_fini();
3921 mt753x_netlink_free();
3922}