blob: 0c6bdcd97caffd33bb0bbf997cb7b191b32b7b87 [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001/*
2* switch_fun.c: switch function sets
3*/
4#include <stdio.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <string.h>
8#include <stdbool.h>
9#include <sys/ioctl.h>
10#include <sys/socket.h>
11#include <linux/if.h>
12#include <stdbool.h>
13#include <time.h>
developer997ed6b2024-03-26 14:03:42 +080014#include <errno.h>
developerfd40db22021-04-29 10:08:25 +080015
16#include "switch_extend.h"
17#include "switch_netlink.h"
18#include "switch_ioctl.h"
19#include "switch_fun.h"
20
21#define leaky_bucket 0
22
developerbe40a9e2024-03-07 21:44:26 +080023struct switch_func_s mt753x_switch_func = {
24 .pf_table_dump = table_dump,
25 .pf_table_clear = table_clear,
26 .pf_switch_reset = switch_reset,
27 .pf_doArlAging = doArlAging,
28 .pf_read_mib_counters = read_mib_counters,
29 .pf_clear_mib_counters = clear_mib_counters,
30 .pf_read_output_queue_counters = read_output_queue_counters,
31 .pf_read_free_page_counters = read_free_page_counters,
32 .pf_rate_control = rate_control,
33 .pf_igress_rate_set = ingress_rate_set,
34 .pf_egress_rate_set = egress_rate_set,
35 .pf_table_add = table_add,
36 .pf_table_del_fid = table_del_fid,
37 .pf_table_del_vid = table_del_vid,
38 .pf_table_search_mac_fid = table_search_mac_fid,
39 .pf_table_search_mac_vid = table_search_mac_vid,
40 .pf_global_set_mac_fc = global_set_mac_fc,
41 .pf_set_mac_pfc = set_mac_pfc,
42 .pf_qos_sch_select = qos_sch_select,
43 .pf_qos_set_base = qos_set_base,
44 .pf_qos_wfq_set_weight = qos_wfq_set_weight,
45 .pf_qos_set_portpri = qos_set_portpri,
46 .pf_qos_set_dscppri = qos_set_dscppri,
47 .pf_qos_pri_mapping_queue = qos_pri_mapping_queue,
48 .pf_doStp = doStp,
49 .pf_sip_dump = sip_dump,
50 .pf_sip_add = sip_add,
51 .pf_sip_del = sip_del,
52 .pf_sip_clear = sip_clear,
53 .pf_dip_dump = dip_dump,
54 .pf_dip_add = dip_add,
55 .pf_dip_del = dip_del,
56 .pf_dip_clear = dip_clear,
57 .pf_set_mirror_to = set_mirror_to,
58 .pf_set_mirror_from = set_mirror_from,
59 .pf_doMirrorEn = doMirrorEn,
60 .pf_doMirrorPortBased = doMirrorPortBased,
61 .pf_acl_dip_add = acl_dip_add,
62 .pf_acl_dip_modify = acl_dip_modify,
63 .pf_acl_dip_pppoe = acl_dip_pppoe,
64 .pf_acl_dip_trtcm = acl_dip_trtcm,
65 .pf_acl_dip_meter = acl_dip_meter,
66 .pf_acl_mac_add = acl_mac_add,
67 .pf_acl_ethertype = acl_ethertype,
68 .pf_acl_sp_add = acl_sp_add,
69 .pf_acl_l4_add = acl_l4_add,
70 .pf_acl_port_enable = acl_port_enable,
71 .pf_acl_table_add = acl_table_add,
72 .pf_acl_mask_table_add = acl_mask_table_add,
73 .pf_acl_rule_table_add = acl_rule_table_add,
74 .pf_acl_rate_table_add = acl_rate_table_add,
75 .pf_vlan_dump = vlan_dump,
76 .pf_vlan_set = vlan_set,
77 .pf_vlan_clear = vlan_clear,
78 .pf_doVlanSetVid = doVlanSetVid,
79 .pf_doVlanSetPvid = doVlanSetPvid,
80 .pf_doVlanSetAccFrm = doVlanSetAccFrm,
81 .pf_doVlanSetPortAttr = doVlanSetPortAttr,
82 .pf_doVlanSetPortMode = doVlanSetPortMode,
83 .pf_doVlanSetEgressTagPCR = doVlanSetEgressTagPCR,
84 .pf_doVlanSetEgressTagPVC = doVlanSetEgressTagPVC,
85 .pf_igmp_on = igmp_on,
86 .pf_igmp_off = igmp_off,
87 .pf_igmp_enable = igmp_enable,
88 .pf_igmp_disable = igmp_disable,
89 .pf_collision_pool_enable = collision_pool_enable,
90 .pf_collision_pool_mac_dump = collision_pool_mac_dump,
91 .pf_collision_pool_dip_dump = collision_pool_dip_dump,
92 .pf_collision_pool_sip_dump = collision_pool_sip_dump,
93 .pf_pfc_get_rx_counter = pfc_get_rx_counter,
94 .pf_pfc_get_tx_counter = pfc_get_tx_counter,
95 .pf_eee_enable = eee_enable,
96 .pf_eee_dump = eee_dump,
97};
98
developerfd40db22021-04-29 10:08:25 +080099static int getnext(char *src, int separator, char *dest)
100{
101 char *c;
102 int len;
103
104 if ((src == NULL) || (dest == NULL))
105 return -1;
106
107 c = strchr(src, separator);
108 if (c == NULL)
109 return -1;
110
111 len = c - src;
112 strncpy(dest, src, len);
113 dest[len] = '\0';
114 return len + 1;
115}
116
117static int str_to_ip(unsigned int *ip, char *str)
118{
119 int i;
120 int len;
121 char *ptr = str;
122 char buf[128];
123 unsigned char c[4];
124
125 for (i = 0; i < 3; ++i) {
126 if ((len = getnext(ptr, '.', buf)) == -1)
127 return 1;
128 c[i] = atoi(buf);
129 ptr += len;
130 }
131 c[3] = atoi(ptr);
132 *ip = (c[0] << 24) + (c[1] << 16) + (c[2] << 8) + c[3];
133 return 0;
134}
135
136/*convert IP address from number to string */
developer546b2792024-06-15 20:31:38 +0800137static void ip_to_str(char *str, size_t size, unsigned int ip)
developerfd40db22021-04-29 10:08:25 +0800138{
139 unsigned char *ptr = (unsigned char *)&ip;
140 unsigned char c[4];
developer546b2792024-06-15 20:31:38 +0800141 int ret;
142
143 if (str == NULL || size == 0) {
144 printf("convert IP address failed\n");
145 return;
146 }
developerfd40db22021-04-29 10:08:25 +0800147
148 c[0] = *(ptr);
149 c[1] = *(ptr + 1);
150 c[2] = *(ptr + 2);
151 c[3] = *(ptr + 3);
developer546b2792024-06-15 20:31:38 +0800152
153 ret = snprintf(str, size, "%d.%d.%d.%d", c[3], c[2], c[1], c[0]);
154 if (ret < 0) {
155 printf("Encoding error in snprintf\n");
156 return;
157 } else if ((size_t)ret >= size) {
158 printf("Required size %d, provided size %zu\n", ret, size);
159 return;
160 }
developerfd40db22021-04-29 10:08:25 +0800161}
162
163int reg_read(unsigned int offset, unsigned int *value)
164{
165 int ret = -1;
166
167 if (nl_init_flag == true) {
168 ret = reg_read_netlink(attres, offset, value);
169 } else {
170 if (attres->dev_id == -1)
171 ret = reg_read_ioctl(offset, value);
172 }
173 if (ret < 0) {
174 printf("Read fail\n");
175 *value = 0;
176 return ret;
177 }
178
179 return 0;
180}
181
182int reg_write(unsigned int offset, unsigned int value)
183{
184 int ret = -1;
185
186 if (nl_init_flag == true) {
187 ret = reg_write_netlink(attres, offset, value);
188 } else {
189 if (attres->dev_id == -1)
190 ret = reg_write_ioctl(offset, value);
191 }
192 if (ret < 0) {
193 printf("Write fail\n");
194 exit_free();
195 exit(0);
196 }
197 return 0;
198}
199
200int mii_mgr_read(unsigned int port_num, unsigned int reg, unsigned int *value)
201{
202 int ret;
203
204 if (port_num > 31) {
205 printf("Invalid Port or PHY addr \n");
206 return -1;
207 }
208
209 if (nl_init_flag == true)
210 ret = phy_cl22_read_netlink(attres, port_num, reg, value);
211 else
212 ret = mii_mgr_cl22_read_ioctl(port_num, reg, value);
213
214 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800215 printf("Phy cl22 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800216 exit_free();
217 exit(0);
218 }
219
220 return 0;
221}
222
223int mii_mgr_write(unsigned int port_num, unsigned int reg, unsigned int value)
224{
225 int ret;
226
227 if (port_num > 31) {
228 printf("Invalid Port or PHY addr \n");
229 return -1;
230 }
231
232 if (nl_init_flag == true)
233 ret = phy_cl22_write_netlink(attres, port_num, reg, value);
234 else
235 ret = mii_mgr_cl22_write_ioctl(port_num, reg, value);
236
237 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800238 printf("Phy cl22 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800239 exit_free();
240 exit(0);
241 }
242
243 return 0;
244}
245
developerbe40a9e2024-03-07 21:44:26 +0800246int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg,
247 unsigned int *value)
developerfd40db22021-04-29 10:08:25 +0800248{
249 int ret;
250
251 if (port_num > 31) {
252 printf("Invalid Port or PHY addr \n");
253 return -1;
254 }
255
256 if (nl_init_flag == true)
257 ret = phy_cl45_read_netlink(attres, port_num, dev, reg, value);
258 else
259 ret = mii_mgr_cl45_read_ioctl(port_num, dev, reg, value);
260
261 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800262 printf("Phy cl45 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800263 exit_free();
264 exit(0);
265 }
266
267 return 0;
268}
269
developerbe40a9e2024-03-07 21:44:26 +0800270int mii_mgr_c45_write(unsigned int port_num, unsigned int dev, unsigned int reg,
271 unsigned int value)
developerfd40db22021-04-29 10:08:25 +0800272{
273 int ret;
274
275 if (port_num > 31) {
276 printf("Invalid Port or PHY addr \n");
277 return -1;
278 }
279
280 if (nl_init_flag == true)
281 ret = phy_cl45_write_netlink(attres, port_num, dev, reg, value);
282 else
283 ret = mii_mgr_cl45_write_ioctl(port_num, dev, reg, value);
284
285 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800286 printf("Phy cl45 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800287 exit_free();
288 exit(0);
289 }
290
291 return 0;
292}
293
developerfd40db22021-04-29 10:08:25 +0800294int phy_dump(int phy_addr)
295{
296 int ret;
297
298 if (nl_init_flag == true)
299 ret = phy_dump_netlink(attres, phy_addr);
300 else
301 ret = phy_dump_ioctl(phy_addr);
302
303 if (ret < 0) {
304 printf("Phy dump fail\n");
305 exit_free();
306 exit(0);
307 }
308
309 return 0;
310}
311
312void phy_crossover(int argc, char *argv[])
313{
314 unsigned int port_num = strtoul(argv[2], NULL, 10);
developerbe40a9e2024-03-07 21:44:26 +0800315 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +0800316 int ret;
317
318 if (port_num > 4) {
319 printf("invaild value, port_name:0~4\n");
320 return;
321 }
322
323 if (nl_init_flag == true)
developerbe40a9e2024-03-07 21:44:26 +0800324 ret =
325 phy_cl45_read_netlink(attres, port_num, 0x1E,
326 MT7530_T10_TEST_CONTROL, &value);
developerfd40db22021-04-29 10:08:25 +0800327 else
developerbe40a9e2024-03-07 21:44:26 +0800328 ret =
329 mii_mgr_cl45_read_ioctl(port_num, 0x1E,
330 MT7530_T10_TEST_CONTROL, &value);
developerfd40db22021-04-29 10:08:25 +0800331 if (ret < 0) {
332 printf("phy_cl45 read fail\n");
333 exit_free();
334 exit(0);
335 }
336
337 printf("mii_mgr_cl45:");
developerbe40a9e2024-03-07 21:44:26 +0800338 printf("Read: port#=%d, device=0x%x, reg=0x%x, value=0x%x\n", port_num,
339 0x1E, MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800340
developerbe40a9e2024-03-07 21:44:26 +0800341 if (!strncmp(argv[3], "auto", 5)) {
developerfd40db22021-04-29 10:08:25 +0800342 value &= (~(0x3 << 3));
343 } else if (!strncmp(argv[3], "mdi", 4)) {
344 value &= (~(0x3 << 3));
345 value |= (0x2 << 3);
346 } else if (!strncmp(argv[3], "mdix", 5)) {
347 value |= (0x3 << 3);
348 } else {
349 printf("invaild parameter\n");
350 return;
351 }
developerbe40a9e2024-03-07 21:44:26 +0800352 printf("Write: port#=%d, device=0x%x, reg=0x%x. value=0x%x\n", port_num,
353 0x1E, MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800354
355 if (nl_init_flag == true)
developerbe40a9e2024-03-07 21:44:26 +0800356 ret =
357 phy_cl45_write_netlink(attres, port_num, 0x1E,
358 MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800359 else
developerbe40a9e2024-03-07 21:44:26 +0800360 ret =
361 mii_mgr_cl45_write_ioctl(port_num, 0x1E,
362 MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800363
364 if (ret < 0) {
365 printf("phy_cl45 write fail\n");
366 exit_free();
367 exit(0);
368 }
369}
370
371int rw_phy_token_ring(int argc, char *argv[])
372{
373 int ch_addr, node_addr, data_addr;
374 unsigned int tr_reg_control;
375 unsigned int val_l = 0;
376 unsigned int val_h = 0;
377 unsigned int port_num;
378
379 if (argc < 4)
380 return -1;
381
382 if (argv[2][0] == 'r') {
383 if (argc != 7)
384 return -1;
developerbe40a9e2024-03-07 21:44:26 +0800385 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
developerfd40db22021-04-29 10:08:25 +0800386 port_num = strtoul(argv[3], NULL, 0);
387 if (port_num > MAX_PORT) {
388 printf("Illegal port index and port:0~6\n");
389 return -1;
390 }
391 ch_addr = strtoul(argv[4], NULL, 0);
392 node_addr = strtoul(argv[5], NULL, 0);
393 data_addr = strtoul(argv[6], NULL, 0);
developerbe40a9e2024-03-07 21:44:26 +0800394 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n",
395 port_num, ch_addr, node_addr, data_addr);
396 tr_reg_control =
397 (1 << 15) | (1 << 13) | (ch_addr << 11) | (node_addr << 7) |
398 (data_addr << 1);
399 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
developerfd40db22021-04-29 10:08:25 +0800400 mii_mgr_read(port_num, 17, &val_l);
401 mii_mgr_read(port_num, 18, &val_h);
developerbe40a9e2024-03-07 21:44:26 +0800402 printf
403 ("switch trreg read tr_reg_control=%x, value_H=%x, value_L=%x\n",
404 tr_reg_control, val_h, val_l);
developerfd40db22021-04-29 10:08:25 +0800405 } else if (argv[2][0] == 'w') {
406 if (argc != 9)
407 return -1;
developerbe40a9e2024-03-07 21:44:26 +0800408 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
developerfd40db22021-04-29 10:08:25 +0800409 port_num = strtoul(argv[3], NULL, 0);
410 if (port_num > MAX_PORT) {
411 printf("\n**Illegal port index and port:0~6\n");
412 return -1;
413 }
414 ch_addr = strtoul(argv[4], NULL, 0);
415 node_addr = strtoul(argv[5], NULL, 0);
416 data_addr = strtoul(argv[6], NULL, 0);
417 val_h = strtoul(argv[7], NULL, 0);
418 val_l = strtoul(argv[8], NULL, 0);
developerbe40a9e2024-03-07 21:44:26 +0800419 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n",
420 port_num, ch_addr, node_addr, data_addr);
421 tr_reg_control =
422 (1 << 15) | (0 << 13) | (ch_addr << 11) | (node_addr << 7) |
423 (data_addr << 1);
developerfd40db22021-04-29 10:08:25 +0800424 mii_mgr_write(port_num, 17, val_l);
425 mii_mgr_write(port_num, 18, val_h);
developerbe40a9e2024-03-07 21:44:26 +0800426 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
427 printf
428 ("switch trreg Write tr_reg_control=%x, value_H=%x, value_L=%x\n",
429 tr_reg_control, val_h, val_l);
developerfd40db22021-04-29 10:08:25 +0800430 } else
431 return -1;
432 return 0;
433}
434
developerbe40a9e2024-03-07 21:44:26 +0800435void write_acl_table(unsigned char tbl_idx, unsigned int vawd1,
436 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800437{
developerbe40a9e2024-03-07 21:44:26 +0800438 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800439 unsigned int max_index;
440
developer8c3871b2022-07-01 14:07:53 +0800441 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800442 max_index = 256;
443 else
444 max_index = 64;
445
446 printf("Pattern_acl_tbl_idx:%d\n", tbl_idx);
447
448 if (tbl_idx >= max_index) {
449 printf(HELP_ACL_ACL_TBL_ADD);
450 return;
451 }
452
453 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800454 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800455 reg_read(reg, &value);
456 if ((value & REG_VTCR_BUSY_MASK) == 0) {
457 break;
458 }
459 }
460 reg_write(REG_VAWD1_ADDR, vawd1);
461 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
462 reg_write(REG_VAWD2_ADDR, vawd2);
463 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
464 reg = REG_VTCR_ADDR;
465 value = REG_VTCR_BUSY_MASK | (0x05 << REG_VTCR_FUNC_OFFT) | tbl_idx;
466 reg_write(reg, value);
467 printf("write reg: %x, value: %x\n", reg, value);
468
developerbe40a9e2024-03-07 21:44:26 +0800469 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800470 reg_read(reg, &value);
471 if ((value & REG_VTCR_BUSY_MASK) == 0)
472 break;
473 }
474}
475
476void acl_table_add(int argc, char *argv[])
477{
developerbe40a9e2024-03-07 21:44:26 +0800478 unsigned int vawd1 = 0, vawd2 = 0;
479 unsigned char tbl_idx = 0;
developer546b2792024-06-15 20:31:38 +0800480 char *endptr;
developerfd40db22021-04-29 10:08:25 +0800481
developer546b2792024-06-15 20:31:38 +0800482 errno = 0;
483 tbl_idx = strtoul(argv[3], &endptr, 10);
484 if (errno != 0 || *endptr != '\0') {
485 printf("Error: wrong ACL rule table index\n");
486 return;
487 }
488
489 errno = 0;
490 vawd1 = strtoul(argv[4], &endptr, 16);
491 if (errno != 0 || *endptr != '\0') {
492 printf("Error: wrong ACL rule table write data 1\n");
493 return;
494 }
495
496 errno = 0;
497 vawd2 = strtoul(argv[5], &endptr, 16);
498 if (errno != 0 || *endptr != '\0') {
499 printf("Error: wrong ACL rule table write data 2\n");
500 return;
501 }
502
developerfd40db22021-04-29 10:08:25 +0800503 write_acl_table(tbl_idx, vawd1, vawd2);
504}
505
developerbe40a9e2024-03-07 21:44:26 +0800506void write_acl_mask_table(unsigned char tbl_idx, unsigned int vawd1,
507 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800508{
developerbe40a9e2024-03-07 21:44:26 +0800509 unsigned int value = 0, reg = 0;
510 unsigned int max_index = 0;
developerfd40db22021-04-29 10:08:25 +0800511
developer8c3871b2022-07-01 14:07:53 +0800512 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800513 max_index = 128;
514 else
515 max_index = 32;
516
517 printf("Rule_mask_tbl_idx:%d\n", tbl_idx);
518
519 if (tbl_idx >= max_index) {
520 printf(HELP_ACL_MASK_TBL_ADD);
521 return;
522 }
523 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800524 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800525 reg_read(reg, &value);
526 if ((value & REG_VTCR_BUSY_MASK) == 0)
527 break;
528 }
529 reg_write(REG_VAWD1_ADDR, vawd1);
530 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
531 reg_write(REG_VAWD2_ADDR, vawd2);
532 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
533 reg = REG_VTCR_ADDR;
534 value = REG_VTCR_BUSY_MASK | (0x09 << REG_VTCR_FUNC_OFFT) | tbl_idx;
535 reg_write(reg, value);
536 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +0800537 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800538 reg_read(reg, &value);
539 if ((value & REG_VTCR_BUSY_MASK) == 0)
540 break;
541 }
542}
543
544void acl_mask_table_add(int argc, char *argv[])
545{
developerbe40a9e2024-03-07 21:44:26 +0800546 unsigned int vawd1 = 0, vawd2 = 0;
547 unsigned char tbl_idx = 0;
developer546b2792024-06-15 20:31:38 +0800548 char *endptr;
developerfd40db22021-04-29 10:08:25 +0800549
developer546b2792024-06-15 20:31:38 +0800550 errno = 0;
551 tbl_idx = strtoul(argv[3], &endptr, 10);
552 if (errno != 0 || *endptr != '\0') {
553 printf("Error: wrong ACL mask table index\n");
554 return;
555 }
556
557 errno = 0;
558 vawd1 = strtoul(argv[4], &endptr, 16);
559 if (errno != 0 || *endptr != '\0') {
560 printf("Error: wrong ACL mask table write data 1\n");
561 return;
562 }
563
564 errno = 0;
565 vawd2 = strtoul(argv[5], &endptr, 16);
566 if (errno != 0 || *endptr != '\0') {
567 printf("Error: wrong ACL mask table write data 2\n");
568 return;
569 }
570
developerfd40db22021-04-29 10:08:25 +0800571 write_acl_mask_table(tbl_idx, vawd1, vawd2);
572}
573
developerbe40a9e2024-03-07 21:44:26 +0800574void write_acl_rule_table(unsigned char tbl_idx, unsigned int vawd1,
575 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800576{
developerbe40a9e2024-03-07 21:44:26 +0800577 unsigned int value = 0, reg = 0;
578 unsigned int max_index = 0;
developerfd40db22021-04-29 10:08:25 +0800579
developer8c3871b2022-07-01 14:07:53 +0800580 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800581 max_index = 128;
582 else
583 max_index = 32;
584
585 printf("Rule_control_tbl_idx:%d\n", tbl_idx);
586
developerbe40a9e2024-03-07 21:44:26 +0800587 if (tbl_idx >= max_index) { /* Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +0800588 printf(HELP_ACL_RULE_TBL_ADD);
589 return;
590 }
591 reg = REG_VTCR_ADDR;
592
developerbe40a9e2024-03-07 21:44:26 +0800593 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800594 reg_read(reg, &value);
595 if ((value & REG_VTCR_BUSY_MASK) == 0) {
596 break;
597 }
598 }
599 reg_write(REG_VAWD1_ADDR, vawd1);
600 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
601 reg_write(REG_VAWD2_ADDR, vawd2);
602 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
603 reg = REG_VTCR_ADDR;
604 value = REG_VTCR_BUSY_MASK | (0x0B << REG_VTCR_FUNC_OFFT) | tbl_idx;
605 reg_write(reg, value);
606 printf("write reg: %x, value: %x\n", reg, value);
607
developerbe40a9e2024-03-07 21:44:26 +0800608 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800609 reg_read(reg, &value);
610 if ((value & REG_VTCR_BUSY_MASK) == 0) {
611 break;
612 }
613 }
614}
615
616void acl_rule_table_add(int argc, char *argv[])
617{
developerbe40a9e2024-03-07 21:44:26 +0800618 unsigned int vawd1 = 0, vawd2 = 0;
619 unsigned char tbl_idx = 0;
developer546b2792024-06-15 20:31:38 +0800620 char *endptr;
621
622 errno = 0;
623 tbl_idx = strtoul(argv[3], &endptr, 10);
624 if (errno != 0 || *endptr != '\0') {
625 printf("Error: wrong ACL rule control table index\n");
626 return;
627 }
628
629 errno = 0;
630 vawd1 = strtoul(argv[4], &endptr, 16);
631 if (errno != 0 || *endptr != '\0') {
632 printf("Error: wrong ACL rule control table write data 1\n");
633 return;
634 }
635
636 errno = 0;
637 vawd2 = strtoul(argv[5], &endptr, 16);
638 if (errno != 0 || *endptr != '\0') {
639 printf("Error: wrong ACL rule control table write data 2\n");
640 return;
641 }
developerfd40db22021-04-29 10:08:25 +0800642
developerfd40db22021-04-29 10:08:25 +0800643 write_acl_rule_table(tbl_idx, vawd1, vawd2);
644}
645
developerbe40a9e2024-03-07 21:44:26 +0800646void write_rate_table(unsigned char tbl_idx, unsigned int vawd1,
647 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800648{
developerbe40a9e2024-03-07 21:44:26 +0800649 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800650 unsigned int max_index = 32;
651
652 printf("Rule_action_tbl_idx:%d\n", tbl_idx);
653
654 if (tbl_idx >= max_index) {
655 printf(HELP_ACL_RATE_TBL_ADD);
656 return;
657 }
658
659 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800660 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800661 reg_read(reg, &value);
662 if ((value & REG_VTCR_BUSY_MASK) == 0)
663 break;
664 }
665
666 reg_write(REG_VAWD1_ADDR, vawd1);
667 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
668 reg_write(REG_VAWD2_ADDR, vawd2);
669 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
670 reg = REG_VTCR_ADDR;
671 value = REG_VTCR_BUSY_MASK | (0x0D << REG_VTCR_FUNC_OFFT) | tbl_idx;
672 reg_write(reg, value);
673 printf("write reg: %x, value: %x\n", reg, value);
674
developerbe40a9e2024-03-07 21:44:26 +0800675 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800676 reg_read(reg, &value);
677 if ((value & REG_VTCR_BUSY_MASK) == 0)
678 break;
679 }
680}
681
682void acl_rate_table_add(int argc, char *argv[])
683{
developerbe40a9e2024-03-07 21:44:26 +0800684 unsigned int vawd1 = 0, vawd2 = 0;
685 unsigned char tbl_idx = 0;
developer546b2792024-06-15 20:31:38 +0800686 char *endptr;
developerfd40db22021-04-29 10:08:25 +0800687
developer546b2792024-06-15 20:31:38 +0800688 errno = 0;
689 tbl_idx = strtoul(argv[3], &endptr, 10);
690 if (errno != 0 || *endptr != '\0') {
691 printf("Error: wrong ACL rate control table index\n");
692 return;
693 }
694
695 errno = 0;
696 vawd1 = strtoul(argv[4], &endptr, 16);
697 if (errno != 0 || *endptr != '\0') {
698 printf("Error: wrong ACL rate control table write data 1\n");
699 return;
700 }
701
702 errno = 0;
703 vawd2 = strtoul(argv[5], &endptr, 16);
704 if (errno != 0 || *endptr != '\0') {
705 printf("Error: wrong ACL rate control table write data 2\n");
706 return;
707 }
developerfd40db22021-04-29 10:08:25 +0800708
709 write_rate_table(tbl_idx, vawd1, vawd2);
710}
711
developerbe40a9e2024-03-07 21:44:26 +0800712void write_trTCM_table(unsigned char tbl_idx, unsigned int vawd1,
713 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800714{
developerbe40a9e2024-03-07 21:44:26 +0800715 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800716 unsigned int max_index = 32;
717
718 printf("trTCM_tbl_idx:%d\n", tbl_idx);
719
720 if (tbl_idx >= max_index) {
721 printf(HELP_ACL_TRTCM_TBL_ADD);
722 return;
723 }
724
725 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800726 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800727 reg_read(reg, &value);
728 if ((value & REG_VTCR_BUSY_MASK) == 0)
729 break;
730 }
731
732 reg_write(REG_VAWD1_ADDR, vawd1);
733 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
734 reg_write(REG_VAWD2_ADDR, vawd2);
735 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
736 reg = REG_VTCR_ADDR;
737 value = REG_VTCR_BUSY_MASK | (0x07 << REG_VTCR_FUNC_OFFT) | tbl_idx;
738 reg_write(reg, value);
739 printf("write reg: %x, value: %x\n", reg, value);
740
developerbe40a9e2024-03-07 21:44:26 +0800741 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800742 reg_read(reg, &value);
743 if ((value & REG_VTCR_BUSY_MASK) == 0)
744 break;
745 }
746}
747
developerbe40a9e2024-03-07 21:44:26 +0800748int acl_parameters_pre_del(int len1, int len2, int argc, char *argv[],
749 int *port)
developerfd40db22021-04-29 10:08:25 +0800750{
developerbe40a9e2024-03-07 21:44:26 +0800751 int i = 0;
developerfd40db22021-04-29 10:08:25 +0800752
753 *port = 0;
754 if (argc < len1) {
755 printf("insufficient arguments!\n");
756 return -1;
757 }
758
developerbe40a9e2024-03-07 21:44:26 +0800759 if (len2 == 12) {
developerfd40db22021-04-29 10:08:25 +0800760 if (!argv[4] || strlen(argv[4]) != len2) {
developerbe40a9e2024-03-07 21:44:26 +0800761 printf
762 ("The [%s] format error, should be of length %d\n",
763 argv[4], len2);
developerfd40db22021-04-29 10:08:25 +0800764 return -1;
765 }
766 }
767
768 if (!argv[5] || strlen(argv[5]) != 8) {
769 printf("portsmap format error, should be of length 7\n");
770 return -1;
771 }
772
773 for (i = 0; i < 7; i++) {
774 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +0800775 printf
776 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +0800777 return -1;
778 }
779 *port += (argv[5][i] - '0') * (1 << i);
780 }
781 return 0;
782}
783
developerbe40a9e2024-03-07 21:44:26 +0800784void acl_compare_pattern(int ports, int comparion, int base, int word,
785 unsigned char table_index)
developerfd40db22021-04-29 10:08:25 +0800786{
developerbe40a9e2024-03-07 21:44:26 +0800787 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +0800788
developerbe40a9e2024-03-07 21:44:26 +0800789 comparion |= 0xffff0000; //compare mask
developerfd40db22021-04-29 10:08:25 +0800790
developerbe40a9e2024-03-07 21:44:26 +0800791 value = ports << 8; //w_port_map
792 value |= 0x1 << 19; //enable
793 value |= base << 16; //mac header
794 value |= word << 1; //word offset
developerfd40db22021-04-29 10:08:25 +0800795
796 write_acl_table(table_index, comparion, value);
797}
798
799void acl_mac_add(int argc, char *argv[])
800{
developerbe40a9e2024-03-07 21:44:26 +0800801 unsigned int value = 0;
802 int ports = 0;
developerfd40db22021-04-29 10:08:25 +0800803 char tmpstr[5];
804 int ret;
developer546b2792024-06-15 20:31:38 +0800805 char *endptr;
developerfd40db22021-04-29 10:08:25 +0800806
807 ret = acl_parameters_pre_del(6, 12, argc, argv, &ports);
808 if (ret < 0)
809 return;
developerbe40a9e2024-03-07 21:44:26 +0800810 /* Set pattern */
developerfd40db22021-04-29 10:08:25 +0800811 strncpy(tmpstr, argv[4], 4);
812 tmpstr[4] = '\0';
developer546b2792024-06-15 20:31:38 +0800813 errno = 0;
814 value = strtoul(tmpstr, &endptr, 16);
815 if (errno != 0 || *endptr != '\0')
816 goto error;
817
developerfd40db22021-04-29 10:08:25 +0800818 acl_compare_pattern(ports, value, 0x0, 0, 0);
819
820 strncpy(tmpstr, argv[4] + 4, 4);
821 tmpstr[4] = '\0';
developer546b2792024-06-15 20:31:38 +0800822 errno = 0;
823 value = strtoul(tmpstr, &endptr, 16);
824 if (errno != 0 || *endptr != '\0')
825 goto error;
developerfd40db22021-04-29 10:08:25 +0800826 acl_compare_pattern(ports, value, 0x0, 1, 1);
827
828 strncpy(tmpstr, argv[4] + 8, 4);
829 tmpstr[4] = '\0';
developer546b2792024-06-15 20:31:38 +0800830 errno = 0;
831 value = strtoul(tmpstr, &endptr, 16);
832 if (errno != 0 || *endptr != '\0')
833 goto error;
developerfd40db22021-04-29 10:08:25 +0800834 acl_compare_pattern(ports, value, 0x0, 2, 2);
835
836 //set mask
developerbe40a9e2024-03-07 21:44:26 +0800837 write_acl_mask_table(0, 0x7, 0);
developerfd40db22021-04-29 10:08:25 +0800838
839 //set action
developerbe40a9e2024-03-07 21:44:26 +0800840 value = 0x7; //drop
841 value |= 1 << 28; //acl intterupt enable
842 value |= 1 << 27; //acl hit count
843 value |= 2 << 24; //acl hit count group index (0~3)
844 write_acl_rule_table(0, value, 0);
developer546b2792024-06-15 20:31:38 +0800845 return;
846
847error:
848 printf("Error: string converting\n");
849 return;
developerfd40db22021-04-29 10:08:25 +0800850}
851
852void acl_dip_meter(int argc, char *argv[])
853{
developerbe40a9e2024-03-07 21:44:26 +0800854 unsigned int value = 0, ip_value = 0, meter = 0;
855 int ports = 0;
developerfd40db22021-04-29 10:08:25 +0800856 int ret;
857
858 ip_value = 0;
859 ret = acl_parameters_pre_del(7, -1, argc, argv, &ports);
860 if (ret < 0)
861 return;
862
863 str_to_ip(&ip_value, argv[4]);
864 //set pattern
865 value = (ip_value >> 16);
866 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
867
868 //set pattern
869 value = (ip_value & 0xffff);
870 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
871
872 //set mask
developerbe40a9e2024-03-07 21:44:26 +0800873 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800874
875 //set action
876 meter = strtoul(argv[6], NULL, 0);
877 if (((chip_name == 0x7530) && (meter > 1000000)) ||
developerbe40a9e2024-03-07 21:44:26 +0800878 ((chip_name == 0x7531) && (meter > 2500000)) ||
879 ((chip_name == 0x7988) && (meter > 4000000))) {
developer8c3871b2022-07-01 14:07:53 +0800880 printf("\n**Illegal meter input, and 7530: 0~1000000Kpbs, 7531: 0~2500000Kpbs, 7988: 0~4000000Kpbs**\n");
developerfd40db22021-04-29 10:08:25 +0800881 return;
882 }
developer8c3871b2022-07-01 14:07:53 +0800883 if (((chip_name == 0x7531 || chip_name == 0x7988) && (meter > 1000000))) {
developerbe40a9e2024-03-07 21:44:26 +0800884 reg_read(0xc, &value);
developerfd40db22021-04-29 10:08:25 +0800885 value |= 0x1 << 30;
developerbe40a9e2024-03-07 21:44:26 +0800886 reg_write(0xC, value);
887 printf("AGC: 0x%x\n", value);
888 value = meter / 1000; //uint is 1Mbps
developerfd40db22021-04-29 10:08:25 +0800889 } else {
developerbe40a9e2024-03-07 21:44:26 +0800890 reg_read(0xc, &value);
developerfd40db22021-04-29 10:08:25 +0800891 value &= ~(0x1 << 30);
developerbe40a9e2024-03-07 21:44:26 +0800892 reg_write(0xC, value);
893 printf("AGC: 0x%x\n", value);
894 value = meter >> 6; //uint is 64Kbps
developerfd40db22021-04-29 10:08:25 +0800895 }
developerbe40a9e2024-03-07 21:44:26 +0800896 value |= 0x1 << 15; //enable rate control
897 printf("Acl rate control:0x%x\n", value);
developerfd40db22021-04-29 10:08:25 +0800898 write_rate_table(0, value, 0);
899}
900
901void acl_dip_trtcm(int argc, char *argv[])
902{
903 unsigned int value, value2, ip_value;
904 unsigned int CIR, CBS, PIR, PBS;
905 int ports;
906 int ret;
907
908 ip_value = 0;
909 ret = acl_parameters_pre_del(10, -1, argc, argv, &ports);
910 if (ret < 0)
911 return;
912
913 str_to_ip(&ip_value, argv[4]);
914 //set pattern
915 value = (ip_value >> 16);
916 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
917
918 //set pattern
919 value = (ip_value & 0xffff);
920 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
921
922 //set CBS PBS
923 CIR = strtoul(argv[6], NULL, 0);
924 CBS = strtoul(argv[7], NULL, 0);
925 PIR = strtoul(argv[8], NULL, 0);
926 PBS = strtoul(argv[9], NULL, 0);
927
developerbe40a9e2024-03-07 21:44:26 +0800928 if (CIR > 65535 * 64 || CBS > 65535 || PIR > 65535 * 64 || PBS > 65535) {
developerfd40db22021-04-29 10:08:25 +0800929 printf("\n**Illegal input parameters**\n");
930 return;
931 }
932
developerbe40a9e2024-03-07 21:44:26 +0800933 value = CBS << 16; //bit16~31
934 value |= PBS; //bit0~15
935 //value |= 1;//valid
developerfd40db22021-04-29 10:08:25 +0800936 CIR = CIR >> 6;
937 PIR = PIR >> 6;
938
developerbe40a9e2024-03-07 21:44:26 +0800939 value2 = CIR << 16; //bit16~31
940 value2 |= PIR; //bit0~15
941 write_trTCM_table(0, value, value2);
developerfd40db22021-04-29 10:08:25 +0800942
943 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800944 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800945
946 //set action
developerbe40a9e2024-03-07 21:44:26 +0800947 value = 0x1 << (11 + 1); //TrTCM green meter#0 Low drop
948 value |= 0x2 << (8 + 1); //TrTCM yellow meter#0 Med drop
949 value |= 0x3 << (5 + 1); //TrTCM red meter#0 Hig drop
950 value |= 0x1 << 0; //TrTCM drop pcd select
951 write_acl_rule_table(0, 0, value);
developerfd40db22021-04-29 10:08:25 +0800952}
953
954void acl_ethertype(int argc, char *argv[])
955{
956 unsigned int value, ethertype;
957 int ports;
958 int ret;
959
960 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
961 if (ret < 0)
962 return;
developerbe40a9e2024-03-07 21:44:26 +0800963 printf("ports:0x%x\n", ports);
developerfd40db22021-04-29 10:08:25 +0800964 ethertype = strtoul(argv[4], NULL, 16);
965 //set pattern
966 value = ethertype;
967 acl_compare_pattern(ports, value, 0x0, 0x6, 0);
968
969 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800970 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +0800971
972 //set action(drop)
developerbe40a9e2024-03-07 21:44:26 +0800973 value = 0x7; //default. Nodrop
974 value |= 1 << 28; //acl intterupt enable
975 value |= 1 << 27; //acl hit count
developerfd40db22021-04-29 10:08:25 +0800976
developerbe40a9e2024-03-07 21:44:26 +0800977 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +0800978}
979
980void acl_dip_modify(int argc, char *argv[])
981{
982 unsigned int value, ip_value;
983 int ports;
984 int priority;
985 int ret;
986
987 ip_value = 0;
988 priority = strtoul(argv[6], NULL, 16);
989 if (priority < 0 || priority > 7) {
990 printf("\n**Illegal priority value!**\n");
991 return;
992 }
993
994 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
995 if (ret < 0)
996 return;
997
998 str_to_ip(&ip_value, argv[4]);
999 //set pattern
1000 value = (ip_value >> 16);
1001 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
1002
1003 //set pattern
1004 value = (ip_value & 0xffff);
1005 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
1006
1007 //set pattern
developerbe40a9e2024-03-07 21:44:26 +08001008 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +08001009
1010 //set action
developerbe40a9e2024-03-07 21:44:26 +08001011 value = 0x0; //default. Nodrop
1012 value |= 1 << 28; //acl intterupt enable
1013 value |= 1 << 27; //acl hit count
1014 value |= priority << 4; //acl UP
1015 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001016}
1017
1018void acl_dip_pppoe(int argc, char *argv[])
1019{
1020 unsigned int value, ip_value;
1021 int ports;
1022 int ret;
1023
1024 ip_value = 0;
1025 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1026 if (ret < 0)
1027 return;
1028
1029 str_to_ip(&ip_value, argv[4]);
1030 //set pattern
1031 value = (ip_value >> 16);
1032 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
1033
1034 //set pattern
1035 value = (ip_value & 0xffff);
1036 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
1037
1038 //set pattern
developerbe40a9e2024-03-07 21:44:26 +08001039 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +08001040
1041 //set action
developerbe40a9e2024-03-07 21:44:26 +08001042 value = 0x0; //default. Nodrop
1043 value |= 1 << 28; //acl intterupt enable
1044 value |= 1 << 27; //acl hit count
1045 value |= 1 << 20; //pppoe header remove
1046 value |= 1 << 21; //SA MAC SWAP
1047 value |= 1 << 22; //DA MAC SWAP
1048 write_acl_rule_table(0, value, 7);
developerfd40db22021-04-29 10:08:25 +08001049}
1050
1051void acl_dip_add(int argc, char *argv[])
1052{
1053 unsigned int value, ip_value;
1054 int ports;
1055 int ret;
1056
1057 ip_value = 0;
1058 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1059 if (ret < 0)
1060 return;
1061
1062 str_to_ip(&ip_value, argv[4]);
1063 //set pattern
1064 value = (ip_value >> 16);
1065 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
1066
1067 //set pattern
1068 value = (ip_value & 0xffff);
1069 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
1070
1071 //set pattern
developerbe40a9e2024-03-07 21:44:26 +08001072 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +08001073
1074 //set action
1075 //value = 0x0; //default
developerbe40a9e2024-03-07 21:44:26 +08001076 value = 0x7; //drop
1077 value |= 1 << 28; //acl intterupt enable
1078 value |= 1 << 27; //acl hit count
1079 value |= 2 << 24; //acl hit count group index (0~3)
1080 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001081}
1082
1083void acl_l4_add(int argc, char *argv[])
1084{
developerbe40a9e2024-03-07 21:44:26 +08001085 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001086 int ports;
1087 int ret;
1088
1089 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1090 if (ret < 0)
1091 return;
1092
1093 //set pattern
1094 value = strtoul(argv[4], NULL, 16);
1095 acl_compare_pattern(ports, value, 0x5, 0x0, 0);
1096
1097 //set rue mask
developerbe40a9e2024-03-07 21:44:26 +08001098 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +08001099 //set action
developerbe40a9e2024-03-07 21:44:26 +08001100 value = 0x7; //drop
1101 //value |= 1;//valid
1102 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001103}
1104
1105void acl_sp_add(int argc, char *argv[])
1106{
developerbe40a9e2024-03-07 21:44:26 +08001107 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001108 int ports;
1109 int ret;
1110
1111 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1112 if (ret < 0)
1113 return;
1114 //set pattern
1115 value = strtoul(argv[4], NULL, 0);
1116 acl_compare_pattern(ports, value, 0x4, 0x0, 0);
1117
1118 //set rue mask
developerbe40a9e2024-03-07 21:44:26 +08001119 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +08001120
1121 //set action
developerbe40a9e2024-03-07 21:44:26 +08001122 value = 0x7; //drop
1123 //value |= 1;//valid
1124 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001125}
1126
1127void acl_port_enable(int argc, char *argv[])
1128{
developerbe40a9e2024-03-07 21:44:26 +08001129 unsigned int value = 0, reg = 0;
1130 unsigned char acl_port = 0, acl_en = 0;
developer546b2792024-06-15 20:31:38 +08001131 char *endptr;
developerfd40db22021-04-29 10:08:25 +08001132
developer546b2792024-06-15 20:31:38 +08001133 errno = 0;
1134 acl_port = strtoul(argv[3], &endptr, 10);
1135 if (errno != 0 || *endptr != '\0' || acl_port > MAX_PORT) {
1136 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
1137 return;
1138 }
developerfd40db22021-04-29 10:08:25 +08001139
developer546b2792024-06-15 20:31:38 +08001140 errno = 0;
1141 acl_en = strtoul(argv[4], &endptr, 10);
1142 if (errno != 0 || *endptr != '\0' || acl_en > 1) {
developerfd40db22021-04-29 10:08:25 +08001143 printf(HELP_ACL_SETPORTEN);
1144 return;
1145 }
1146
developer546b2792024-06-15 20:31:38 +08001147 printf("acl_port:%d, acl_en:%d\n", acl_port, acl_en);
1148
developerbe40a9e2024-03-07 21:44:26 +08001149 reg = REG_PCR_P0_ADDR + (0x100 * acl_port); // 0x2004[10]
developerfd40db22021-04-29 10:08:25 +08001150 reg_read(reg, &value);
1151 value &= (~REG_PORT_ACL_EN_MASK);
1152 value |= (acl_en << REG_PORT_ACL_EN_OFFT);
1153
1154 printf("write reg: %x, value: %x\n", reg, value);
1155 reg_write(reg, value);
1156}
1157
1158static void dip_dump_internal(int type)
1159{
1160 unsigned int i, j, value, mac, mac2, value2;
developerbe40a9e2024-03-07 21:44:26 +08001161 char tmpstr[16] = { 0 };
developerfd40db22021-04-29 10:08:25 +08001162 int table_size = 0;
1163 int hit_value1 = 0;
1164 int hit_value2 = 0;
1165
developerbe40a9e2024-03-07 21:44:26 +08001166 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001167 table_size = 0x800;
developerbe40a9e2024-03-07 21:44:26 +08001168 reg_write(REG_ATC_ADDR, 0x8104); //dip search command
1169 } else {
developerfd40db22021-04-29 10:08:25 +08001170 table_size = 0x40;
developerbe40a9e2024-03-07 21:44:26 +08001171 reg_write(REG_ATC_ADDR, 0x811c); //dip search command
developerfd40db22021-04-29 10:08:25 +08001172 }
developerbe40a9e2024-03-07 21:44:26 +08001173 printf
1174 ("hash port(0:6) rsp_cnt flag timer dip-address ATRD\n");
developerfd40db22021-04-29 10:08:25 +08001175 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001176 while (1) {
developerfd40db22021-04-29 10:08:25 +08001177 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001178 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001179 hit_value1 = value & (0x1 << 13);
1180 hit_value2 = 1;
developerbe40a9e2024-03-07 21:44:26 +08001181 } else {
developerfd40db22021-04-29 10:08:25 +08001182 hit_value1 = value & (0x1 << 13);
1183 hit_value2 = value & (0x1 << 28);
1184 }
1185
developerbe40a9e2024-03-07 21:44:26 +08001186 if (hit_value1 && hit_value2) { //search_rdy
developerfd40db22021-04-29 10:08:25 +08001187 reg_read(REG_ATRD_ADDR, &value2);
1188 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1189
developerbe40a9e2024-03-07 21:44:26 +08001190 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1191 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001192 printf("%c", (j & 0x01) ? '1' : '-');
1193 printf("%c", (j & 0x02) ? '1' : '-');
1194 printf("%c", (j & 0x04) ? '1' : '-');
1195 printf("%c ", (j & 0x08) ? '1' : '-');
1196 printf("%c", (j & 0x10) ? '1' : '-');
1197 printf("%c", (j & 0x20) ? '1' : '-');
1198 printf("%c", (j & 0x40) ? '1' : '-');
1199
1200 reg_read(REG_TSRA2_ADDR, &mac2);
1201
developerbe40a9e2024-03-07 21:44:26 +08001202 printf(" 0x%4x", (mac2 & 0xffff)); //RESP_CNT
1203 printf(" 0x%2x", ((mac2 >> 16) & 0xff)); //RESP_FLAG
1204 printf(" %3d", ((mac2 >> 24) & 0xff)); //RESP_TIMER
1205 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001206 reg_read(REG_TSRA1_ADDR, &mac);
developer546b2792024-06-15 20:31:38 +08001207 ip_to_str(tmpstr, sizeof(tmpstr), mac);
developerfd40db22021-04-29 10:08:25 +08001208 printf(" %s", tmpstr);
developerbe40a9e2024-03-07 21:44:26 +08001209 printf(" 0x%8x\n", value2); //ATRD
1210 //printf("%04x", ((mac2 >> 16) & 0xffff));
1211 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
developerfd40db22021-04-29 10:08:25 +08001212 if (value & 0x4000) {
1213 printf("end of table %d\n", i);
1214 return;
1215 }
1216 break;
developerbe40a9e2024-03-07 21:44:26 +08001217 } else if (value & 0x4000) { //at_table_end
1218 printf("found the last entry %d (not ready)\n",
1219 i);
developerfd40db22021-04-29 10:08:25 +08001220 return;
1221 }
1222 usleep(5000);
1223 }
1224
developerbe40a9e2024-03-07 21:44:26 +08001225 if (type == GENERAL_TABLE)
1226 reg_write(REG_ATC_ADDR, 0x8105); //search for next dip address
developerfd40db22021-04-29 10:08:25 +08001227 else
developerbe40a9e2024-03-07 21:44:26 +08001228 reg_write(REG_ATC_ADDR, 0x811d); //search for next dip address
developerfd40db22021-04-29 10:08:25 +08001229 usleep(5000);
1230 }
1231}
1232
developerbe40a9e2024-03-07 21:44:26 +08001233void dip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001234{
1235 dip_dump_internal(GENERAL_TABLE);
1236
1237}
1238
1239void dip_add(int argc, char *argv[])
1240{
1241 unsigned int value = 0;
developerbe40a9e2024-03-07 21:44:26 +08001242 unsigned int i = 0, j = 0;
developerfd40db22021-04-29 10:08:25 +08001243
1244 value = 0;
1245
1246 str_to_ip(&value, argv[3]);
1247
1248 reg_write(REG_ATA1_ADDR, value);
1249 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1250
1251#if 0
1252 reg_write(REG_ATA2_ADDR, value);
1253 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1254#endif
1255 if (!argv[4] || strlen(argv[4]) != 8) {
1256 printf("portmap format error, should be of length 7\n");
1257 return;
1258 }
1259 j = 0;
1260 for (i = 0; i < 7; i++) {
1261 if (argv[4][i] != '0' && argv[4][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001262 printf
1263 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001264 return;
1265 }
1266 j += (argv[4][i] - '0') * (1 << i);
1267 }
developerbe40a9e2024-03-07 21:44:26 +08001268 value = j << 4; //w_port_map
1269 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001270
1271 reg_write(REG_ATWD_ADDR, value);
1272
1273 usleep(5000);
1274 reg_read(REG_ATWD_ADDR, &value);
1275 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1276
developerbe40a9e2024-03-07 21:44:26 +08001277 value = 0x8011; //single w_dip_cmd
developerfd40db22021-04-29 10:08:25 +08001278 reg_write(REG_ATC_ADDR, value);
1279
1280 usleep(1000);
1281
1282 for (i = 0; i < 20; i++) {
1283 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001284 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001285 printf("done.\n");
1286 return;
1287 }
1288 usleep(1000);
1289 }
1290 if (i == 20)
1291 printf("timeout.\n");
1292}
1293
1294void dip_del(int argc, char *argv[])
1295{
1296 unsigned int i, value;
1297
1298 value = 0;
1299 str_to_ip(&value, argv[3]);
1300
1301 reg_write(REG_ATA1_ADDR, value);
1302
1303 value = 0;
1304 reg_write(REG_ATA2_ADDR, value);
1305
developerbe40a9e2024-03-07 21:44:26 +08001306 value = 0; //STATUS=0, delete dip
developerfd40db22021-04-29 10:08:25 +08001307 reg_write(REG_ATWD_ADDR, value);
1308
developerbe40a9e2024-03-07 21:44:26 +08001309 value = 0x8011; //w_dip_cmd
developerfd40db22021-04-29 10:08:25 +08001310 reg_write(REG_ATC_ADDR, value);
1311
1312 for (i = 0; i < 20; i++) {
1313 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001314 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001315 if (argv[1] != NULL)
1316 printf("done.\n");
1317 return;
1318 }
1319 usleep(1000);
1320 }
1321 if (i == 20)
1322 printf("timeout.\n");
1323}
1324
developerbe40a9e2024-03-07 21:44:26 +08001325void dip_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001326{
1327
developerbe40a9e2024-03-07 21:44:26 +08001328 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001329
developerbe40a9e2024-03-07 21:44:26 +08001330 reg_write(REG_ATC_ADDR, 0x8102); //clear all dip
developerfd40db22021-04-29 10:08:25 +08001331 usleep(5000);
1332 reg_read(REG_ATC_ADDR, &value);
1333 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1334}
1335
1336static void sip_dump_internal(int type)
1337{
developerbe40a9e2024-03-07 21:44:26 +08001338 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001339 int table_size = 0;
1340 int hit_value1 = 0;
1341 int hit_value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08001342 char tmpstr[16] = { 0 };
developerfd40db22021-04-29 10:08:25 +08001343
1344 if (type == GENERAL_TABLE) {
1345 table_size = 0x800;
developerbe40a9e2024-03-07 21:44:26 +08001346 reg_write(REG_ATC_ADDR, 0x8204); //sip search command
1347 } else {
developerfd40db22021-04-29 10:08:25 +08001348 table_size = 0x40;
developerbe40a9e2024-03-07 21:44:26 +08001349 reg_write(REG_ATC_ADDR, 0x822c); //sip search command
developerfd40db22021-04-29 10:08:25 +08001350 }
1351 printf("hash port(0:6) dip-address sip-address ATRD\n");
1352 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001353 while (1) {
developerfd40db22021-04-29 10:08:25 +08001354 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001355 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001356 hit_value1 = value & (0x1 << 13);
1357 hit_value2 = 1;
1358 } else {
1359 hit_value1 = value & (0x1 << 13);
1360 hit_value2 = value & (0x1 << 28);
1361 }
1362
developerbe40a9e2024-03-07 21:44:26 +08001363 if (hit_value1 && hit_value2) { //search_rdy
developerfd40db22021-04-29 10:08:25 +08001364 reg_read(REG_ATRD_ADDR, &value2);
1365 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1366
developerbe40a9e2024-03-07 21:44:26 +08001367 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1368 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001369 printf("%c", (j & 0x01) ? '1' : '-');
1370 printf("%c", (j & 0x02) ? '1' : '-');
1371 printf("%c", (j & 0x04) ? '1' : '-');
1372 printf("%c", (j & 0x08) ? '1' : '-');
1373 printf(" %c", (j & 0x10) ? '1' : '-');
1374 printf("%c", (j & 0x20) ? '1' : '-');
1375 printf("%c", (j & 0x40) ? '1' : '-');
1376
1377 reg_read(REG_TSRA2_ADDR, &mac2);
1378
developer546b2792024-06-15 20:31:38 +08001379 ip_to_str(tmpstr, sizeof(tmpstr), mac2);
developerfd40db22021-04-29 10:08:25 +08001380 printf(" %s", tmpstr);
1381
1382 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
1383 reg_read(REG_TSRA1_ADDR, &mac);
developer546b2792024-06-15 20:31:38 +08001384 ip_to_str(tmpstr, sizeof(tmpstr), mac);
developerfd40db22021-04-29 10:08:25 +08001385 printf(" %s", tmpstr);
1386 printf(" 0x%x\n", value2);
1387 //printf("%04x", ((mac2 >> 16) & 0xffff));
1388 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
1389 if (value & 0x4000) {
1390 printf("end of table %d\n", i);
1391 return;
1392 }
1393 break;
developerbe40a9e2024-03-07 21:44:26 +08001394 } else if (value & 0x4000) { //at_table_end
1395 printf("found the last entry %d (not ready)\n",
1396 i);
developerfd40db22021-04-29 10:08:25 +08001397 return;
1398 }
1399 usleep(5000);
1400 }
1401
developerbe40a9e2024-03-07 21:44:26 +08001402 if (type == GENERAL_TABLE)
1403 reg_write(REG_ATC_ADDR, 0x8205); //search for next sip address
1404 else
1405 reg_write(REG_ATC_ADDR, 0x822d); //search for next sip address
1406 usleep(5000);
developerfd40db22021-04-29 10:08:25 +08001407 }
1408}
1409
developerbe40a9e2024-03-07 21:44:26 +08001410void sip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001411{
1412
1413 sip_dump_internal(GENERAL_TABLE);
1414
1415}
1416
developerfd40db22021-04-29 10:08:25 +08001417void sip_add(int argc, char *argv[])
1418{
developerbe40a9e2024-03-07 21:44:26 +08001419 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001420
1421 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08001422 str_to_ip(&value, argv[3]); //SIP
developerfd40db22021-04-29 10:08:25 +08001423
1424 reg_write(REG_ATA2_ADDR, value);
1425 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1426
1427 value = 0;
1428
developerbe40a9e2024-03-07 21:44:26 +08001429 str_to_ip(&value, argv[4]); //DIP
developerfd40db22021-04-29 10:08:25 +08001430 reg_write(REG_ATA1_ADDR, value);
1431 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1432
1433 if (!argv[5] || strlen(argv[5]) != 8) {
1434 printf("portmap format error, should be of length 7\n");
1435 return;
1436 }
1437 j = 0;
1438 for (i = 0; i < 7; i++) {
1439 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001440 printf
1441 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001442 return;
1443 }
1444 j += (argv[5][i] - '0') * (1 << i);
1445 }
developerbe40a9e2024-03-07 21:44:26 +08001446 value = j << 4; //w_port_map
1447 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001448
1449 reg_write(REG_ATWD_ADDR, value);
1450
1451 usleep(5000);
1452 reg_read(REG_ATWD_ADDR, &value);
1453 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1454
developerbe40a9e2024-03-07 21:44:26 +08001455 value = 0x8021; //single w_sip_cmd
developerfd40db22021-04-29 10:08:25 +08001456 reg_write(REG_ATC_ADDR, value);
1457
1458 usleep(1000);
1459
1460 for (i = 0; i < 20; i++) {
1461 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001462 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001463 printf("done.\n");
1464 return;
1465 }
1466 usleep(1000);
1467 }
1468 if (i == 20)
1469 printf("timeout.\n");
1470}
1471
1472void sip_del(int argc, char *argv[])
1473{
developerbe40a9e2024-03-07 21:44:26 +08001474 unsigned int i = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001475
1476 value = 0;
1477 str_to_ip(&value, argv[3]);
1478
developerbe40a9e2024-03-07 21:44:26 +08001479 reg_write(REG_ATA2_ADDR, value); //SIP
developerfd40db22021-04-29 10:08:25 +08001480
1481 str_to_ip(&value, argv[4]);
developerbe40a9e2024-03-07 21:44:26 +08001482 reg_write(REG_ATA1_ADDR, value); //DIP
developerfd40db22021-04-29 10:08:25 +08001483
developerbe40a9e2024-03-07 21:44:26 +08001484 value = 0; //STATUS=0, delete sip
developerfd40db22021-04-29 10:08:25 +08001485 reg_write(REG_ATWD_ADDR, value);
1486
developerbe40a9e2024-03-07 21:44:26 +08001487 value = 0x8021; //w_sip_cmd
developerfd40db22021-04-29 10:08:25 +08001488 reg_write(REG_ATC_ADDR, value);
1489
1490 for (i = 0; i < 20; i++) {
1491 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001492 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001493 if (argv[1] != NULL)
1494 printf("done.\n");
1495 return;
1496 }
1497 usleep(1000);
1498 }
1499 if (i == 20)
1500 printf("timeout.\n");
1501}
1502
developerbe40a9e2024-03-07 21:44:26 +08001503void sip_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001504{
developerbe40a9e2024-03-07 21:44:26 +08001505 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001506
developerbe40a9e2024-03-07 21:44:26 +08001507 reg_write(REG_ATC_ADDR, 0x8202); //clear all sip
developerfd40db22021-04-29 10:08:25 +08001508 usleep(5000);
1509 reg_read(REG_ATC_ADDR, &value);
1510 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1511}
1512
1513static void table_dump_internal(int type)
1514{
developerbe40a9e2024-03-07 21:44:26 +08001515 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001516 int table_size = 0;
1517 int table_end = 0;
1518 int hit_value1 = 0;
1519 int hit_value2 = 0;
1520
developerbe40a9e2024-03-07 21:44:26 +08001521 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001522 table_size = 0x800;
1523 table_end = 0x7FF;
1524 reg_write(REG_ATC_ADDR, 0x8004);
1525 } else {
1526 table_size = 0x40;
1527 table_end = 0x3F;
1528 reg_write(REG_ATC_ADDR, 0x800C);
1529 }
developerbe40a9e2024-03-07 21:44:26 +08001530 printf
1531 ("hash port(0:6) fid vid age(s) mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001532 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001533 while (1) {
developerfd40db22021-04-29 10:08:25 +08001534 reg_read(REG_ATC_ADDR, &value);
1535 //printf("ATC = 0x%x\n", value);
developerbe40a9e2024-03-07 21:44:26 +08001536 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001537 hit_value1 = value & (0x1 << 13);
1538 hit_value2 = 1;
1539 } else {
1540 hit_value1 = value & (0x1 << 13);
1541 hit_value2 = value & (0x1 << 28);
1542 }
1543
developerbe40a9e2024-03-07 21:44:26 +08001544 if (hit_value1 && hit_value2
1545 && (((value >> 15) & 0x1) == 0)) {
developerfd40db22021-04-29 10:08:25 +08001546 printf("%03x: ", (value >> 16) & 0xfff);
1547 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001548 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001549 printf("%c", (j & 0x01) ? '1' : '-');
1550 printf("%c", (j & 0x02) ? '1' : '-');
1551 printf("%c", (j & 0x04) ? '1' : '-');
1552 printf("%c", (j & 0x08) ? '1' : '-');
1553 printf("%c", (j & 0x10) ? '1' : '-');
1554 printf("%c", (j & 0x20) ? '1' : '-');
1555 printf("%c", (j & 0x40) ? '1' : '-');
1556 printf("%c", (j & 0x80) ? '1' : '-');
1557
1558 reg_read(REG_TSRA2_ADDR, &mac2);
1559
developerbe40a9e2024-03-07 21:44:26 +08001560 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001561 printf(" %4d", (mac2 & 0xfff));
1562 if (((value2 >> 24) & 0xff) == 0xFF)
developerbe40a9e2024-03-07 21:44:26 +08001563 printf(" --- "); //r_age_field:static
developerfd40db22021-04-29 10:08:25 +08001564 else
developerbe40a9e2024-03-07 21:44:26 +08001565 printf(" %5d ", (((value2 >> 24) & 0xff) + 1) * 2); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001566 reg_read(REG_TSRA1_ADDR, &mac);
1567 printf(" %08x", mac);
1568 printf("%04x", ((mac2 >> 16) & 0xffff));
developerbe40a9e2024-03-07 21:44:26 +08001569 printf(" %c",
1570 (((value2 >> 20) & 0x03) ==
1571 0x03) ? 'y' : '-');
1572 printf(" %c\n",
1573 (((value2 >> 23) & 0x01) ==
1574 0x01) ? 'y' : '-');
1575 if ((value & 0x4000)
1576 && (((value >> 16) & 0xfff) == table_end)) {
developerfd40db22021-04-29 10:08:25 +08001577 printf("end of table %d\n", i);
1578 return;
1579 }
1580 break;
developerbe40a9e2024-03-07 21:44:26 +08001581 } else if ((value & 0x4000) && (((value >> 15) & 0x1) == 0) && (((value >> 16) & 0xfff) == table_end)) { //at_table_end
1582 printf("found the last entry %d (not ready)\n",
1583 i);
developerfd40db22021-04-29 10:08:25 +08001584 return;
developerbe40a9e2024-03-07 21:44:26 +08001585 } else
developerfd40db22021-04-29 10:08:25 +08001586 usleep(5);
1587 }
1588
developerbe40a9e2024-03-07 21:44:26 +08001589 if (type == GENERAL_TABLE)
1590 reg_write(REG_ATC_ADDR, 0x8005); //search for next address
1591 else
1592 reg_write(REG_ATC_ADDR, 0x800d); //search for next address
developerfd40db22021-04-29 10:08:25 +08001593 usleep(5);
1594 }
1595}
1596
developerbe40a9e2024-03-07 21:44:26 +08001597void table_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001598{
1599 table_dump_internal(GENERAL_TABLE);
1600
1601}
1602
developerfd40db22021-04-29 10:08:25 +08001603void table_add(int argc, char *argv[])
1604{
developerbe40a9e2024-03-07 21:44:26 +08001605 unsigned int i = 0, j = 0, value = 0, is_filter = 0, is_mymac = 0;
developerfd40db22021-04-29 10:08:25 +08001606 char tmpstr[9];
1607
1608 is_filter = (argv[1][0] == 'f') ? 1 : 0;
1609 is_mymac = (argv[1][0] == 'm') ? 1 : 0;
1610 if (!argv[2] || strlen(argv[2]) != 12) {
1611 printf("MAC address format error, should be of length 12\n");
1612 return;
1613 }
1614 strncpy(tmpstr, argv[2], 8);
1615 tmpstr[8] = '\0';
1616 value = strtoul(tmpstr, NULL, 16);
1617 reg_write(REG_ATA1_ADDR, value);
1618 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1619
1620 strncpy(tmpstr, argv[2] + 8, 4);
1621 tmpstr[4] = '\0';
1622
1623 value = strtoul(tmpstr, NULL, 16);
1624 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001625 value |= (1 << 15); //IVL=1
developerfd40db22021-04-29 10:08:25 +08001626
1627 if (argc > 4) {
1628 j = strtoul(argv[4], NULL, 0);
1629 if (4095 < j) {
1630 printf("wrong vid range, should be within 0~4095\n");
1631 return;
1632 }
developerbe40a9e2024-03-07 21:44:26 +08001633 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001634 }
1635
1636 reg_write(REG_ATA2_ADDR, value);
1637 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1638
1639 if (!argv[3] || strlen(argv[3]) != 8) {
1640 if (is_filter)
1641 argv[3] = "11111111";
1642 else {
1643 printf("portmap format error, should be of length 8\n");
1644 return;
1645 }
1646 }
1647 j = 0;
1648 for (i = 0; i < 7; i++) {
1649 if (argv[3][i] != '0' && argv[3][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001650 printf
1651 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001652 return;
1653 }
1654 j += (argv[3][i] - '0') * (1 << i);
1655 }
developerbe40a9e2024-03-07 21:44:26 +08001656 value = j << 4; //w_port_map
developerfd40db22021-04-29 10:08:25 +08001657
1658 if (argc > 5) {
1659 j = strtoul(argv[5], NULL, 0);
1660 if (j < 1 || 255 < j) {
1661 printf("wrong age range, should be within 1~255\n");
1662 return;
1663 }
developerbe40a9e2024-03-07 21:44:26 +08001664 value |= (j << 24); //w_age_field
1665 value |= (0x1 << 2); //dynamic
developerfd40db22021-04-29 10:08:25 +08001666 } else {
developerbe40a9e2024-03-07 21:44:26 +08001667 value |= (0xff << 24); //w_age_field
1668 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001669 }
1670
1671 if (argc > 6) {
1672 j = strtoul(argv[6], NULL, 0);
1673 if (7 < j) {
1674 printf("wrong eg-tag range, should be within 0~7\n");
1675 return;
1676 }
developerbe40a9e2024-03-07 21:44:26 +08001677 value |= (j << 13); //EG_TAG
developerfd40db22021-04-29 10:08:25 +08001678 }
1679
1680 if (is_filter)
developerbe40a9e2024-03-07 21:44:26 +08001681 value |= (7 << 20); //sa_filter
developerfd40db22021-04-29 10:08:25 +08001682
1683 if (is_mymac)
1684 value |= (1 << 23);
1685
1686 reg_write(REG_ATWD_ADDR, value);
1687
1688 usleep(5000);
1689 reg_read(REG_ATWD_ADDR, &value);
1690 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1691
developerbe40a9e2024-03-07 21:44:26 +08001692 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001693 reg_write(REG_ATC_ADDR, value);
1694
1695 usleep(1000);
1696
1697 for (i = 0; i < 20; i++) {
1698 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001699 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001700 printf("done.\n");
1701 return;
1702 }
1703 usleep(1000);
1704 }
1705 if (i == 20)
1706 printf("timeout.\n");
1707}
1708
1709void table_search_mac_vid(int argc, char *argv[])
1710{
developerbe40a9e2024-03-07 21:44:26 +08001711 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001712 char tmpstr[9];
1713
1714 if (!argv[3] || strlen(argv[3]) != 12) {
1715 printf("MAC address format error, should be of length 12\n");
1716 return;
1717 }
1718 strncpy(tmpstr, argv[3], 8);
1719 tmpstr[8] = '\0';
1720 value = strtoul(tmpstr, NULL, 16);
1721 reg_write(REG_ATA1_ADDR, value);
1722 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1723
1724 strncpy(tmpstr, argv[3] + 8, 4);
1725 tmpstr[4] = '\0';
1726
1727 value = strtoul(tmpstr, NULL, 16);
1728 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001729 value |= (1 << 15); //IVL=1
developerfd40db22021-04-29 10:08:25 +08001730
1731 j = strtoul(argv[5], NULL, 0);
1732 if (4095 < j) {
1733 printf("wrong vid range, should be within 0~4095\n");
1734 return;
1735 }
developerbe40a9e2024-03-07 21:44:26 +08001736 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001737
1738 reg_write(REG_ATA2_ADDR, value);
1739 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1740
developerbe40a9e2024-03-07 21:44:26 +08001741 value = 0x8000; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001742 reg_write(REG_ATC_ADDR, value);
1743
1744 usleep(1000);
1745
1746 for (i = 0; i < 20; i++) {
1747 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001748 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001749 break;
1750 }
1751 usleep(1000);
1752 }
1753 if (i == 20) {
1754 printf("search timeout.\n");
1755 return;
1756 }
1757
1758 if (value & 0x1000) {
1759 printf("search no entry.\n");
1760 return;
1761 }
1762
1763 printf("search done.\n");
developerbe40a9e2024-03-07 21:44:26 +08001764 printf
1765 ("hash port(0:6) fid vid age mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001766
developerbe40a9e2024-03-07 21:44:26 +08001767 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
developerfd40db22021-04-29 10:08:25 +08001768 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001769 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001770 printf("%c", (j & 0x01) ? '1' : '-');
1771 printf("%c", (j & 0x02) ? '1' : '-');
1772 printf("%c", (j & 0x04) ? '1' : '-');
1773 printf("%c ", (j & 0x08) ? '1' : '-');
1774 printf("%c", (j & 0x10) ? '1' : '-');
1775 printf("%c", (j & 0x20) ? '1' : '-');
1776 printf("%c", (j & 0x40) ? '1' : '-');
1777 printf("%c", (j & 0x80) ? '1' : '-');
1778
1779 reg_read(REG_TSRA2_ADDR, &mac2);
1780
developerbe40a9e2024-03-07 21:44:26 +08001781 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001782 printf(" %4d", (mac2 & 0xfff));
developerbe40a9e2024-03-07 21:44:26 +08001783 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001784 reg_read(REG_TSRA1_ADDR, &mac);
1785 printf(" %08x", mac);
1786 printf("%04x", ((mac2 >> 16) & 0xffff));
1787 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1788 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1789}
1790
1791void table_search_mac_fid(int argc, char *argv[])
1792{
developerbe40a9e2024-03-07 21:44:26 +08001793 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001794 char tmpstr[9];
1795
1796 if (!argv[3] || strlen(argv[3]) != 12) {
1797 printf("MAC address format error, should be of length 12\n");
1798 return;
1799 }
1800 strncpy(tmpstr, argv[3], 8);
1801 tmpstr[8] = '\0';
1802 value = strtoul(tmpstr, NULL, 16);
1803 reg_write(REG_ATA1_ADDR, value);
1804 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1805
1806 strncpy(tmpstr, argv[3] + 8, 4);
1807 tmpstr[4] = '\0';
1808
1809 value = strtoul(tmpstr, NULL, 16);
1810 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001811 value &= ~(1 << 15); //IVL=0
developerfd40db22021-04-29 10:08:25 +08001812
1813 j = strtoul(argv[5], NULL, 0);
1814 if (7 < j) {
1815 printf("wrong fid range, should be within 0~7\n");
1816 return;
1817 }
developerbe40a9e2024-03-07 21:44:26 +08001818 value |= (j << 12); //vid
developerfd40db22021-04-29 10:08:25 +08001819
1820 reg_write(REG_ATA2_ADDR, value);
1821 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1822
developerbe40a9e2024-03-07 21:44:26 +08001823 value = 0x8000; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001824 reg_write(REG_ATC_ADDR, value);
1825
1826 usleep(1000);
1827
1828 for (i = 0; i < 20; i++) {
1829 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001830 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001831 break;
1832 }
1833 usleep(1000);
1834 }
1835 if (i == 20) {
1836 printf("search timeout.\n");
1837 return;
1838 }
1839
1840 if (value & 0x1000) {
1841 printf("search no entry.\n");
1842 return;
1843 }
1844
1845 printf("search done.\n");
developerbe40a9e2024-03-07 21:44:26 +08001846 printf
1847 ("hash port(0:6) fid vid age mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001848
developerbe40a9e2024-03-07 21:44:26 +08001849 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
developerfd40db22021-04-29 10:08:25 +08001850 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001851 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001852 printf("%c", (j & 0x01) ? '1' : '-');
1853 printf("%c", (j & 0x02) ? '1' : '-');
1854 printf("%c", (j & 0x04) ? '1' : '-');
1855 printf("%c ", (j & 0x08) ? '1' : '-');
1856 printf("%c", (j & 0x10) ? '1' : '-');
1857 printf("%c", (j & 0x20) ? '1' : '-');
1858 printf("%c", (j & 0x40) ? '1' : '-');
1859 printf("%c", (j & 0x80) ? '1' : '-');
1860
1861 reg_read(REG_TSRA2_ADDR, &mac2);
1862
developerbe40a9e2024-03-07 21:44:26 +08001863 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001864 printf(" %4d", (mac2 & 0xfff));
developerbe40a9e2024-03-07 21:44:26 +08001865 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001866 reg_read(REG_TSRA1_ADDR, &mac);
1867 printf(" %08x", mac);
1868 printf("%04x", ((mac2 >> 16) & 0xffff));
1869 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1870 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1871}
1872
1873void table_del_fid(int argc, char *argv[])
1874{
developerbe40a9e2024-03-07 21:44:26 +08001875 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001876 char tmpstr[9];
1877
1878 if (!argv[3] || strlen(argv[3]) != 12) {
1879 printf("MAC address format error, should be of length 12\n");
1880 return;
1881 }
1882 strncpy(tmpstr, argv[3], 8);
1883 tmpstr[8] = '\0';
1884 value = strtoul(tmpstr, NULL, 16);
1885 reg_write(REG_ATA1_ADDR, value);
1886 strncpy(tmpstr, argv[3] + 8, 4);
1887 tmpstr[4] = '\0';
1888 value = strtoul(tmpstr, NULL, 16);
1889 value = (value << 16);
1890
1891 if (argc > 5) {
1892 j = strtoul(argv[5], NULL, 0);
1893 if (j > 7) {
1894 printf("wrong fid range, should be within 0~7\n");
1895 return;
1896 }
developerbe40a9e2024-03-07 21:44:26 +08001897 value |= (j << 12); /* fid */
developerfd40db22021-04-29 10:08:25 +08001898 }
1899
1900 reg_write(REG_ATA2_ADDR, value);
1901
developerbe40a9e2024-03-07 21:44:26 +08001902 value = 0; /* STATUS=0, delete mac */
developerfd40db22021-04-29 10:08:25 +08001903 reg_write(REG_ATWD_ADDR, value);
1904
developerbe40a9e2024-03-07 21:44:26 +08001905 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001906 reg_write(REG_ATC_ADDR, value);
1907
1908 for (i = 0; i < 20; i++) {
1909 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001910 if ((value & 0x8000) == 0) { /* mac address busy */
developerfd40db22021-04-29 10:08:25 +08001911 if (argv[1] != NULL)
1912 printf("done.\n");
1913 return;
1914 }
1915 usleep(1000);
1916 }
1917 if (i == 20)
1918 printf("timeout.\n");
1919}
1920
1921void table_del_vid(int argc, char *argv[])
1922{
developerbe40a9e2024-03-07 21:44:26 +08001923 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001924 char tmpstr[9];
1925
1926 if (!argv[3] || strlen(argv[3]) != 12) {
1927 printf("MAC address format error, should be of length 12\n");
1928 return;
1929 }
1930 strncpy(tmpstr, argv[3], 8);
1931 tmpstr[8] = '\0';
1932 value = strtoul(tmpstr, NULL, 16);
1933 reg_write(REG_ATA1_ADDR, value);
1934
1935 strncpy(tmpstr, argv[3] + 8, 4);
1936 tmpstr[4] = '\0';
1937 value = strtoul(tmpstr, NULL, 16);
1938 value = (value << 16);
1939
1940 j = strtoul(argv[5], NULL, 0);
1941 if (j > 4095) {
1942 printf("wrong fid range, should be within 0~4095\n");
1943 return;
1944 }
developerbe40a9e2024-03-07 21:44:26 +08001945 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001946 value |= 1 << 15;
1947 reg_write(REG_ATA2_ADDR, value);
1948
developerbe40a9e2024-03-07 21:44:26 +08001949 value = 0; //STATUS=0, delete mac
developerfd40db22021-04-29 10:08:25 +08001950 reg_write(REG_ATWD_ADDR, value);
1951
developerbe40a9e2024-03-07 21:44:26 +08001952 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001953 reg_write(REG_ATC_ADDR, value);
1954
1955 for (i = 0; i < 20; i++) {
1956 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001957 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001958 if (argv[1] != NULL)
1959 printf("done.\n");
1960 return;
1961 }
1962 usleep(1000);
1963 }
1964 if (i == 20)
1965 printf("timeout.\n");
1966}
1967
developerbe40a9e2024-03-07 21:44:26 +08001968void table_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001969{
developerbe40a9e2024-03-07 21:44:26 +08001970 unsigned int value = 0;
1971
developerfd40db22021-04-29 10:08:25 +08001972 reg_write(REG_ATC_ADDR, 0x8002);
1973 usleep(5000);
1974 reg_read(REG_ATC_ADDR, &value);
1975
1976 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1977}
1978
1979void set_mirror_to(int argc, char *argv[])
1980{
developerbe40a9e2024-03-07 21:44:26 +08001981 unsigned int value = 0;
1982 int idx = 0;
developerfd40db22021-04-29 10:08:25 +08001983
1984 idx = strtoul(argv[3], NULL, 0);
1985 if (idx < 0 || MAX_PORT < idx) {
1986 printf("wrong port member, should be within 0~%d\n", MAX_PORT);
1987 return;
1988 }
1989 if (chip_name == 0x7530) {
1990
1991 reg_read(REG_MFC_ADDR, &value);
1992 value |= 0x1 << 3;
1993 value &= 0xfffffff8;
1994 value |= idx << 0;
1995
1996 reg_write(REG_MFC_ADDR, value);
1997 } else {
1998
1999 reg_read(REG_CFC_ADDR, &value);
2000 value &= (~REG_CFC_MIRROR_EN_MASK);
2001 value |= (1 << REG_CFC_MIRROR_EN_OFFT);
2002 value &= (~REG_CFC_MIRROR_PORT_MASK);
2003 value |= (idx << REG_CFC_MIRROR_PORT_OFFT);
2004 reg_write(REG_CFC_ADDR, value);
2005 }
2006}
2007
2008void set_mirror_from(int argc, char *argv[])
2009{
developerbe40a9e2024-03-07 21:44:26 +08002010 unsigned int offset = 0, value = 0;
developer546b2792024-06-15 20:31:38 +08002011 unsigned int idx = 0, mirror = 0;
2012 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002013
developer546b2792024-06-15 20:31:38 +08002014 errno = 0;
2015 idx = strtoul(argv[3], &endptr, 0);
2016 if (errno != 0 || *endptr != '\0' || idx > MAX_PORT) {
2017 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
developerfd40db22021-04-29 10:08:25 +08002018 return;
2019 }
2020
developer546b2792024-06-15 20:31:38 +08002021 errno = 0;
2022 mirror = strtoul(argv[4], &endptr, 0);
2023
2024 if (errno != 0 || *endptr != '\0' || mirror > 3) {
developerfd40db22021-04-29 10:08:25 +08002025 printf("wrong mirror setting, should be within 0~3\n");
2026 return;
2027 }
2028
2029 offset = (0x2004 | (idx << 8));
2030 reg_read(offset, &value);
2031
2032 value &= 0xfffffcff;
2033 value |= mirror << 8;
2034
2035 reg_write(offset, value);
2036}
2037
2038void vlan_dump(int argc, char *argv[])
2039{
developerbe40a9e2024-03-07 21:44:26 +08002040 unsigned int i = 0, j = 0, value = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08002041 int eg_tag = 0;
2042
2043 if (argc == 4) {
2044 if (!strncmp(argv[3], "egtag", 6))
2045 eg_tag = 1;
2046 }
2047
2048 if (eg_tag)
developerbe40a9e2024-03-07 21:44:26 +08002049 printf
2050 (" vid fid portmap s-tag\teg_tag(0:untagged 2:tagged)\n");
developerfd40db22021-04-29 10:08:25 +08002051 else
2052 printf(" vid fid portmap s-tag\n");
2053
2054 for (i = 1; i < 4095; i++) {
developerbe40a9e2024-03-07 21:44:26 +08002055 value = (0x80000000 + i); //r_vid_cmd
developerfd40db22021-04-29 10:08:25 +08002056 reg_write(REG_VTCR_ADDR, value);
2057
2058 for (j = 0; j < 20; j++) {
2059 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002060 if ((value & 0x80000000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08002061 break;
2062 }
2063 usleep(1000);
2064 }
2065 if (j == 20)
2066 printf("timeout.\n");
2067
2068 reg_read(REG_VAWD1_ADDR, &value);
2069 reg_read(REG_VAWD2_ADDR, &value2);
2070 //printf("REG_VAWD1_ADDR value%d is 0x%x\n\r", i, value);
2071 //printf("REG_VAWD2_ADDR value%d is 0x%x\n\r", i, value2);
2072
2073 if ((value & 0x01) != 0) {
2074 printf(" %4d ", i);
2075 printf(" %2d ", ((value & 0xe) >> 1));
2076 printf(" %c", (value & 0x00010000) ? '1' : '-');
2077 printf("%c", (value & 0x00020000) ? '1' : '-');
2078 printf("%c", (value & 0x00040000) ? '1' : '-');
2079 printf("%c", (value & 0x00080000) ? '1' : '-');
2080 printf("%c", (value & 0x00100000) ? '1' : '-');
2081 printf("%c", (value & 0x00200000) ? '1' : '-');
2082 printf("%c", (value & 0x00400000) ? '1' : '-');
2083 printf("%c", (value & 0x00800000) ? '1' : '-');
2084 printf(" %4d", ((value & 0xfff0) >> 4));
2085 if (eg_tag) {
2086 printf("\t");
2087 if ((value & (0x3 << 28)) == (0x3 << 28)) {
2088 /* VTAG_EN=1 and EG_CON=1 */
2089 printf("CONSISTENT");
2090 } else if (value & (0x1 << 28)) {
2091 /* VTAG_EN=1 */
2092 printf("%d", (value2 & 0x0003) >> 0);
2093 printf("%d", (value2 & 0x000c) >> 2);
2094 printf("%d", (value2 & 0x0030) >> 4);
2095 printf("%d", (value2 & 0x00c0) >> 6);
2096 printf("%d", (value2 & 0x0300) >> 8);
2097 printf("%d", (value2 & 0x0c00) >> 10);
2098 printf("%d", (value2 & 0x3000) >> 12);
2099 printf("%d", (value2 & 0xc000) >> 14);
2100 } else {
2101 /* VTAG_EN=0 */
2102 printf("DISABLED");
2103 }
2104 }
2105 printf("\n");
2106 } else {
developerbe40a9e2024-03-07 21:44:26 +08002107 /*print 16 vid for reference information */
developerfd40db22021-04-29 10:08:25 +08002108 if (i <= 16) {
2109 printf(" %4d ", i);
2110 printf(" %2d ", ((value & 0xe) >> 1));
2111 printf(" invalid\n");
2112 }
2113 }
2114 }
2115}
2116
developerfd40db22021-04-29 10:08:25 +08002117static long timespec_diff_us(struct timespec start, struct timespec end)
2118{
2119 struct timespec temp;
2120 unsigned long duration = 0;
2121
2122 if ((end.tv_nsec - start.tv_nsec) < 0) {
2123 temp.tv_sec = end.tv_sec - start.tv_sec - 1;
2124 temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
2125 } else {
2126 temp.tv_sec = end.tv_sec - start.tv_sec;
2127 temp.tv_nsec = end.tv_nsec - start.tv_nsec;
2128 }
developerbe40a9e2024-03-07 21:44:26 +08002129 /* calculate second part */
developerfd40db22021-04-29 10:08:25 +08002130 duration += temp.tv_sec * 1000000;
developerbe40a9e2024-03-07 21:44:26 +08002131 /* calculate ns part */
developerfd40db22021-04-29 10:08:25 +08002132 duration += temp.tv_nsec >> 10;
2133
2134 return duration;
2135}
2136
developerfd40db22021-04-29 10:08:25 +08002137void vlan_clear(int argc, char *argv[])
2138{
developerbe40a9e2024-03-07 21:44:26 +08002139 unsigned int value = 0;
2140 int vid = 0;
developerfd40db22021-04-29 10:08:25 +08002141 unsigned long duration_us = 0;
2142 struct timespec start, end;
2143
2144 for (vid = 0; vid < 4096; vid++) {
2145 clock_gettime(CLOCK_REALTIME, &start);
developerbe40a9e2024-03-07 21:44:26 +08002146 value = 0; //invalid
developerfd40db22021-04-29 10:08:25 +08002147 reg_write(REG_VAWD1_ADDR, value);
2148
developerbe40a9e2024-03-07 21:44:26 +08002149 value = (0x80001000 + vid); //w_vid_cmd
developerfd40db22021-04-29 10:08:25 +08002150 reg_write(REG_VTCR_ADDR, value);
2151 while (duration_us <= 1000) {
2152 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002153 if ((value & 0x80000000) == 0) { //table busy
developerfd40db22021-04-29 10:08:25 +08002154 break;
2155 }
2156 clock_gettime(CLOCK_REALTIME, &end);
2157 duration_us = timespec_diff_us(start, end);
2158 }
2159 if (duration_us > 1000)
2160 printf("config vlan timeout: %ld.\n", duration_us);
2161 }
2162}
2163
2164void vlan_set(int argc, char *argv[])
2165{
2166 unsigned int vlan_mem = 0;
2167 unsigned int value = 0;
2168 unsigned int value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08002169 int i = 0, vid = 0, fid = 0;
developerfd40db22021-04-29 10:08:25 +08002170 int stag = 0;
2171 unsigned long eg_con = 0;
2172 unsigned int eg_tag = 0;
2173
2174 if (argc < 5) {
2175 printf("insufficient arguments!\n");
2176 return;
2177 }
2178
2179 fid = strtoul(argv[3], NULL, 0);
2180 if (fid < 0 || fid > 7) {
2181 printf("wrong filtering db id range, should be within 0~7\n");
2182 return;
2183 }
2184 value |= (fid << 1);
2185
2186 vid = strtoul(argv[4], NULL, 0);
2187 if (vid < 0 || 0xfff < vid) {
2188 printf("wrong vlan id range, should be within 0~4095\n");
2189 return;
2190 }
2191
2192 if (strlen(argv[5]) != 8) {
2193 printf("portmap format error, should be of length 7\n");
2194 return;
2195 }
2196
2197 vlan_mem = 0;
2198 for (i = 0; i < 8; i++) {
2199 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08002200 printf
2201 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08002202 return;
2203 }
2204 vlan_mem += (argv[5][i] - '0') * (1 << i);
2205 }
2206
2207 /* VLAN stag */
2208 if (argc > 6) {
2209 stag = strtoul(argv[6], NULL, 16);
2210 if (stag < 0 || 0xfff < stag) {
developerbe40a9e2024-03-07 21:44:26 +08002211 printf
2212 ("wrong stag id range, should be within 0~4095\n");
developerfd40db22021-04-29 10:08:25 +08002213 return;
2214 }
2215 //printf("STAG is 0x%x\n", stag);
2216 }
2217
2218 /* set vlan member */
2219 value |= (vlan_mem << 16);
developerbe40a9e2024-03-07 21:44:26 +08002220 value |= (1 << 30); //IVL=1
2221 value |= ((stag & 0xfff) << 4); //stag
2222 value |= 1; //valid
developerfd40db22021-04-29 10:08:25 +08002223
2224 if (argc > 7) {
2225 eg_con = strtoul(argv[7], NULL, 2);
2226 eg_con = !!eg_con;
developerbe40a9e2024-03-07 21:44:26 +08002227 value |= (eg_con << 29); //eg_con
2228 value |= (1 << 28); //eg tag control enable
developerfd40db22021-04-29 10:08:25 +08002229 }
2230
2231 if (argc > 8 && !eg_con) {
2232 if (strlen(argv[8]) != 8) {
developerbe40a9e2024-03-07 21:44:26 +08002233 printf
2234 ("egtag portmap format error, should be of length 7\n");
developerfd40db22021-04-29 10:08:25 +08002235 return;
2236 }
2237
2238 for (i = 0; i < 8; i++) {
2239 if (argv[8][i] < '0' || argv[8][i] > '3') {
developerbe40a9e2024-03-07 21:44:26 +08002240 printf
2241 ("egtag portmap format error, should be of combination of 0 or 3\n");
developerfd40db22021-04-29 10:08:25 +08002242 return;
2243 }
2244 //eg_tag += (argv[8][i] - '0') * (1 << i * 2);
2245 eg_tag |= (argv[8][i] - '0') << (i * 2);
2246 }
2247
developerbe40a9e2024-03-07 21:44:26 +08002248 value |= (1 << 28); //eg tag control enable
developerfd40db22021-04-29 10:08:25 +08002249 value2 &= ~(0xffff);
2250 value2 |= eg_tag;
2251 }
2252 reg_write(REG_VAWD1_ADDR, value);
2253 reg_write(REG_VAWD2_ADDR, value2);
2254 //printf("VAWD1=0x%08x VAWD2=0x%08x ", value, value2);
2255
developerbe40a9e2024-03-07 21:44:26 +08002256 value = (0x80001000 + vid); //w_vid_cmd
developerfd40db22021-04-29 10:08:25 +08002257 reg_write(REG_VTCR_ADDR, value);
2258 //printf("VTCR=0x%08x\n", value);
2259
2260 for (i = 0; i < 300; i++) {
2261 usleep(1000);
2262 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002263 if ((value & 0x80000000) == 0) //table busy
developerfd40db22021-04-29 10:08:25 +08002264 break;
2265 }
2266
2267 if (i == 300)
2268 printf("config vlan timeout.\n");
2269}
2270
2271void igmp_on(int argc, char *argv[])
2272{
2273 unsigned int leaky_en = 0;
2274 unsigned int wan_num = 4;
developerbe40a9e2024-03-07 21:44:26 +08002275 unsigned int port = 0, offset = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002276 char cmd[80];
2277 int ret;
2278
2279 if (argc > 3)
2280 leaky_en = strtoul(argv[3], NULL, 10);
2281 if (argc > 4)
2282 wan_num = strtoul(argv[4], NULL, 10);
2283
2284 if (leaky_en == 1) {
2285 if (wan_num == 4) {
2286 /* reg_write(0x2410, 0x810000c8); */
2287 reg_read(0x2410, &value);
2288 reg_write(0x2410, value | (1 << 3));
2289 /* reg_write(0x2010, 0x810000c0); */
2290 reg_read(0x2010, &value);
2291 reg_write(0x2010, value & (~(1 << 3)));
2292 reg_write(REG_ISC_ADDR, 0x10027d10);
2293 } else {
2294 /* reg_write(0x2010, 0x810000c8); */
2295 reg_read(0x2010, &value);
2296 reg_write(0x2010, value | (1 << 3));
2297 /* reg_write(0x2410, 0x810000c0); */
2298 reg_read(0x2410, &value);
2299 reg_write(0x2410, value & (~(1 << 3)));
2300 reg_write(REG_ISC_ADDR, 0x01027d01);
2301 }
developerbe40a9e2024-03-07 21:44:26 +08002302 } else
developerfd40db22021-04-29 10:08:25 +08002303 reg_write(REG_ISC_ADDR, 0x10027d60);
2304
2305 reg_write(0x1c, 0x08100810);
2306 reg_write(0x2008, 0xb3ff);
2307 reg_write(0x2108, 0xb3ff);
2308 reg_write(0x2208, 0xb3ff);
2309 reg_write(0x2308, 0xb3ff);
2310 reg_write(0x2408, 0xb3ff);
2311 reg_write(0x2608, 0xb3ff);
2312 /* Enable Port ACL
developerbe40a9e2024-03-07 21:44:26 +08002313 * reg_write(0x2P04, 0xff0403);
2314 */
developerfd40db22021-04-29 10:08:25 +08002315 for (port = 0; port <= 6; port++) {
2316 offset = 0x2004 + port * 0x100;
2317 reg_read(offset, &value);
2318 reg_write(offset, value | (1 << 10));
2319 }
2320
developerbe40a9e2024-03-07 21:44:26 +08002321 /*IGMP query only p4 -> p5 */
developerfd40db22021-04-29 10:08:25 +08002322 reg_write(0x94, 0x00ff0002);
2323 if (wan_num == 4)
2324 reg_write(0x98, 0x000a1008);
2325 else
2326 reg_write(0x98, 0x000a0108);
2327 reg_write(0x90, 0x80005000);
2328 reg_write(0x94, 0xff001100);
2329 if (wan_num == 4)
2330 reg_write(0x98, 0x000B1000);
2331 else
2332 reg_write(0x98, 0x000B0100);
2333 reg_write(0x90, 0x80005001);
2334 reg_write(0x94, 0x3);
2335 reg_write(0x98, 0x0);
2336 reg_write(0x90, 0x80009000);
2337 reg_write(0x94, 0x1a002080);
2338 reg_write(0x98, 0x0);
2339 reg_write(0x90, 0x8000b000);
2340
developerbe40a9e2024-03-07 21:44:26 +08002341 /*IGMP p5 -> p4 */
developerfd40db22021-04-29 10:08:25 +08002342 reg_write(0x94, 0x00ff0002);
2343 reg_write(0x98, 0x000a2008);
2344 reg_write(0x90, 0x80005002);
2345 reg_write(0x94, 0x4);
2346 reg_write(0x98, 0x0);
2347 reg_write(0x90, 0x80009001);
2348 if (wan_num == 4)
2349 reg_write(0x94, 0x1a001080);
2350 else
2351 reg_write(0x94, 0x1a000180);
2352 reg_write(0x98, 0x0);
2353 reg_write(0x90, 0x8000b001);
2354
developerbe40a9e2024-03-07 21:44:26 +08002355 /*IGMP p0~p3 -> p6 */
developerfd40db22021-04-29 10:08:25 +08002356 reg_write(0x94, 0x00ff0002);
2357 if (wan_num == 4)
2358 reg_write(0x98, 0x000a0f08);
2359 else
2360 reg_write(0x98, 0x000a1e08);
2361 reg_write(0x90, 0x80005003);
2362 reg_write(0x94, 0x8);
2363 reg_write(0x98, 0x0);
2364 reg_write(0x90, 0x80009002);
2365 reg_write(0x94, 0x1a004080);
2366 reg_write(0x98, 0x0);
2367 reg_write(0x90, 0x8000b002);
2368
developerbe40a9e2024-03-07 21:44:26 +08002369 /*IGMP query only p6 -> p0~p3 */
developerfd40db22021-04-29 10:08:25 +08002370 reg_write(0x94, 0x00ff0002);
2371 reg_write(0x98, 0x000a4008);
2372 reg_write(0x90, 0x80005004);
2373 reg_write(0x94, 0xff001100);
2374 reg_write(0x98, 0x000B4000);
2375 reg_write(0x90, 0x80005005);
2376 reg_write(0x94, 0x30);
2377 reg_write(0x98, 0x0);
2378 reg_write(0x90, 0x80009003);
2379 if (wan_num == 4)
2380 reg_write(0x94, 0x1a000f80);
2381 else
2382 reg_write(0x94, 0x1a001e80);
2383 reg_write(0x98, 0x0);
2384 reg_write(0x90, 0x8000b003);
2385
developerbe40a9e2024-03-07 21:44:26 +08002386 /*Force eth2 to receive all igmp packets */
2387 snprintf(cmd, sizeof(cmd),
2388 "echo 2 > /sys/devices/virtual/net/%s/brif/%s/multicast_router",
2389 BR_DEVNAME, ETH_DEVNAME);
developerfd40db22021-04-29 10:08:25 +08002390 ret = system(cmd);
2391 if (ret)
developerbe40a9e2024-03-07 21:44:26 +08002392 printf
2393 ("Failed to set /sys/devices/virtual/net/%s/brif/%s/multicast_router\n",
2394 BR_DEVNAME, ETH_DEVNAME);
developerfd40db22021-04-29 10:08:25 +08002395}
2396
2397void igmp_disable(int argc, char *argv[])
2398{
developerbe40a9e2024-03-07 21:44:26 +08002399 unsigned int reg_offset = 0, value = 0;
2400 int port_num = 0;
developerfd40db22021-04-29 10:08:25 +08002401
2402 if (argc < 4) {
2403 printf("insufficient arguments!\n");
2404 return;
2405 }
2406 port_num = strtoul(argv[3], NULL, 0);
2407 if (port_num < 0 || 6 < port_num) {
2408 printf("wrong port range, should be within 0~6\n");
2409 return;
2410 }
developerfd40db22021-04-29 10:08:25 +08002411 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2412 reg_offset = 0x2008;
2413 reg_offset |= (port_num << 8);
2414 value = 0x8000;
2415
2416 reg_write(reg_offset, value);
2417}
2418
2419void igmp_enable(int argc, char *argv[])
2420{
developerbe40a9e2024-03-07 21:44:26 +08002421 unsigned int reg_offset = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002422 int port_num;
2423
2424 if (argc < 4) {
2425 printf("insufficient arguments!\n");
2426 return;
2427 }
2428 port_num = strtoul(argv[3], NULL, 0);
2429 if (port_num < 0 || 6 < port_num) {
2430 printf("wrong port range, should be within 0~6\n");
2431 return;
2432 }
developerfd40db22021-04-29 10:08:25 +08002433 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2434 reg_offset = 0x2008;
2435 reg_offset |= (port_num << 8);
2436 value = 0x9755;
2437 reg_write(reg_offset, value);
2438}
2439
developerbe40a9e2024-03-07 21:44:26 +08002440void igmp_off(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002441{
developerbe40a9e2024-03-07 21:44:26 +08002442 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08002443 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2444 reg_read(REG_ISC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002445 value &= ~(1 << 18); //disable
developerfd40db22021-04-29 10:08:25 +08002446 reg_write(REG_ISC_ADDR, value);
2447
developerbe40a9e2024-03-07 21:44:26 +08002448 /*restore wan port multicast leaky vlan function: default disabled */
developerfd40db22021-04-29 10:08:25 +08002449 reg_read(0x2010, &value);
2450 reg_write(0x2010, value & (~(1 << 3)));
2451 reg_read(0x2410, &value);
2452 reg_write(0x2410, value & (~(1 << 3)));
2453
2454 printf("config igmpsnoop off.\n");
2455}
2456
developerbe40a9e2024-03-07 21:44:26 +08002457void switch_reset(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002458{
developer8c3871b2022-07-01 14:07:53 +08002459 if (chip_name == 0x7988)
developerbe40a9e2024-03-07 21:44:26 +08002460 return;
developer8c3871b2022-07-01 14:07:53 +08002461
developerfd40db22021-04-29 10:08:25 +08002462 unsigned int value = 0;
2463 /*Software Register Reset and Software System Reset */
2464 reg_write(0x7000, 0x3);
2465 reg_read(0x7000, &value);
2466 printf("SYS_CTRL(0x7000) register value =0x%x \n", value);
2467 if (chip_name == 0x7531) {
2468 reg_write(0x7c0c, 0x11111111);
2469 reg_read(0x7c0c, &value);
2470 printf("GPIO Mode (0x7c0c) select value =0x%x \n", value);
2471 }
2472 printf("Switch Software Reset !!! \n");
2473}
2474
developerbe40a9e2024-03-07 21:44:26 +08002475void phy_set_fc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002476{
developerbe40a9e2024-03-07 21:44:26 +08002477 unsigned int port = 0, pause_capable = 0;
2478 unsigned int phy_value = 0;
developer3a780bf2024-06-15 20:34:27 +08002479 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002480
developer3a780bf2024-06-15 20:34:27 +08002481 errno = 0;
2482 port = strtoul(argv[3], &endptr, 10);
2483 if (errno != 0 || *endptr != '\0' || port > MAX_PORT - 2) {
2484 printf("Error: wrong PHY port number, should be within 0~4\n");
2485 return;
2486 }
developerfd40db22021-04-29 10:08:25 +08002487
developer3a780bf2024-06-15 20:34:27 +08002488 errno = 0;
2489 pause_capable = strtoul(argv[4], &endptr, 10);
2490 if (errno != 0 || *endptr != '\0' || pause_capable > 1) {
2491 printf("Illegal parameter, full_duplex_pause_capable:0|1\n");
developerbe40a9e2024-03-07 21:44:26 +08002492 return;
developerfd40db22021-04-29 10:08:25 +08002493 }
developer3a780bf2024-06-15 20:34:27 +08002494
developerfd40db22021-04-29 10:08:25 +08002495 printf("port=%d, full_duplex_pause_capable:%d\n", port, pause_capable);
developerbe40a9e2024-03-07 21:44:26 +08002496
developerfd40db22021-04-29 10:08:25 +08002497 mii_mgr_read(port, 4, &phy_value);
2498 printf("read phy_value:0x%x\r\n", phy_value);
2499 phy_value &= (~(0x1 << 10));
2500 phy_value &= (~(0x1 << 11));
2501 if (pause_capable == 1) {
2502 phy_value |= (0x1 << 10);
2503 phy_value |= (0x1 << 11);
2504 }
2505 mii_mgr_write(port, 4, phy_value);
2506 printf("write phy_value:0x%x\r\n", phy_value);
developerbe40a9e2024-03-07 21:44:26 +08002507 return;
2508} /*end phy_set_fc */
developerfd40db22021-04-29 10:08:25 +08002509
developerbe40a9e2024-03-07 21:44:26 +08002510void phy_set_an(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002511{
developerbe40a9e2024-03-07 21:44:26 +08002512 unsigned int port = 0, auto_negotiation_en = 0;
2513 unsigned int phy_value = 0;
developer3a780bf2024-06-15 20:34:27 +08002514 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002515
developer3a780bf2024-06-15 20:34:27 +08002516 errno = 0;
2517 port = strtoul(argv[3], &endptr, 10);
2518 if (errno != 0 || *endptr != '\0' || port > MAX_PORT - 2) {
2519 printf("Error: wrong PHY port number, should be within 0~4\n");
2520 return;
2521 }
developerfd40db22021-04-29 10:08:25 +08002522
developer3a780bf2024-06-15 20:34:27 +08002523 errno = 0;
2524 auto_negotiation_en = strtoul(argv[4], &endptr, 10);
2525 if (errno != 0 || *endptr != '\0' || auto_negotiation_en > 1) {
2526 printf("Illegal parameter, auto_negotiation_en:0|1\n");
developerbe40a9e2024-03-07 21:44:26 +08002527 return;
developerfd40db22021-04-29 10:08:25 +08002528 }
developer3a780bf2024-06-15 20:34:27 +08002529
developerfd40db22021-04-29 10:08:25 +08002530 printf("port=%d, auto_negotiation_en:%d\n", port, auto_negotiation_en);
developerbe40a9e2024-03-07 21:44:26 +08002531
developerfd40db22021-04-29 10:08:25 +08002532 mii_mgr_read(port, 0, &phy_value);
2533 printf("read phy_value:0x%x\r\n", phy_value);
2534 phy_value &= (~(1 << 12));
2535 phy_value |= (auto_negotiation_en << 12);
2536 mii_mgr_write(port, 0, phy_value);
2537 printf("write phy_value:0x%x\r\n", phy_value);
developerbe40a9e2024-03-07 21:44:26 +08002538} /*end phy_set_an */
developerfd40db22021-04-29 10:08:25 +08002539
developerbe40a9e2024-03-07 21:44:26 +08002540void set_mac_pfc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002541{
developerbe40a9e2024-03-07 21:44:26 +08002542 unsigned int value = 0;
developer546b2792024-06-15 20:31:38 +08002543 unsigned int port, enable = 0;
2544 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002545
developer546b2792024-06-15 20:31:38 +08002546 errno = 0;
2547 port = strtoul(argv[3], &endptr, 10);
2548 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2549 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2550 return;
2551 }
2552
2553 errno = 0;
2554 enable = strtoul(argv[4], &endptr, 10);
2555 if (errno != 0 || *endptr != '\0' || enable > 1) {
2556 printf("Error: Illegal paramete, enable|diable:0|1\n");
developerbe40a9e2024-03-07 21:44:26 +08002557 return;
developerfd40db22021-04-29 10:08:25 +08002558 }
developer546b2792024-06-15 20:31:38 +08002559 printf("enable: %d\n", enable);
2560
developer8c3871b2022-07-01 14:07:53 +08002561 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002562 reg_read(REG_PFC_CTRL_ADDR, &value);
2563 value &= ~(1 << port);
2564 value |= (enable << port);
2565 printf("write reg: %x, value: %x\n", REG_PFC_CTRL_ADDR, value);
2566 reg_write(REG_PFC_CTRL_ADDR, value);
developerbe40a9e2024-03-07 21:44:26 +08002567 } else
developerfd40db22021-04-29 10:08:25 +08002568 printf("\nCommand not support by this chip.\n");
developerfd40db22021-04-29 10:08:25 +08002569}
2570
developerbe40a9e2024-03-07 21:44:26 +08002571void global_set_mac_fc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002572{
2573 unsigned char enable = 0;
developerbe40a9e2024-03-07 21:44:26 +08002574 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08002575
2576 if (chip_name == 0x7530) {
2577 enable = atoi(argv[3]);
2578 printf("enable: %d\n", enable);
2579
developerbe40a9e2024-03-07 21:44:26 +08002580 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002581 if (enable > 1) {
2582 printf(HELP_MACCTL_FC);
developerbe40a9e2024-03-07 21:44:26 +08002583 return;
developerfd40db22021-04-29 10:08:25 +08002584 }
2585 reg_write(0x7000, 0x3);
2586 reg = REG_GFCCR0_ADDR;
2587 reg_read(REG_GFCCR0_ADDR, &value);
2588 value &= (~REG_FC_EN_MASK);
2589 value |= (enable << REG_FC_EN_OFFT);
2590 printf("write reg: %x, value: %x\n", reg, value);
2591 reg_write(REG_GFCCR0_ADDR, value);
2592 } else
2593 printf("\r\nCommand not support by this chip.\n");
developerbe40a9e2024-03-07 21:44:26 +08002594} /*end mac_set_fc */
developerfd40db22021-04-29 10:08:25 +08002595
developerbe40a9e2024-03-07 21:44:26 +08002596void qos_sch_select(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002597{
developerbe40a9e2024-03-07 21:44:26 +08002598 unsigned char port = 0, queue = 0;
developerfd40db22021-04-29 10:08:25 +08002599 unsigned char type = 0;
developerbe40a9e2024-03-07 21:44:26 +08002600 unsigned int value = 0, reg = 0;
developer546b2792024-06-15 20:31:38 +08002601 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002602
2603 if (argc < 7)
developerbe40a9e2024-03-07 21:44:26 +08002604 return;
developerfd40db22021-04-29 10:08:25 +08002605
developer546b2792024-06-15 20:31:38 +08002606 errno = 0;
2607 port = strtoul(argv[3], &endptr, 10);
2608 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2609 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2610 return;
2611 }
developerfd40db22021-04-29 10:08:25 +08002612
developer546b2792024-06-15 20:31:38 +08002613 errno = 0;
2614 queue = strtoul(argv[4], &endptr, 10);
2615 if (errno != 0 || *endptr != '\0' || queue > 7) {
2616 printf("Error: wrong port queue member\n");
developerbe40a9e2024-03-07 21:44:26 +08002617 return;
developerfd40db22021-04-29 10:08:25 +08002618 }
2619
developer546b2792024-06-15 20:31:38 +08002620 errno = 0;
2621 type = strtoul(argv[6], &endptr, 10);
2622 if (errno != 0 || *endptr != '\0' || type > 2) {
developerfd40db22021-04-29 10:08:25 +08002623 printf(HELP_QOS_TYPE);
developerbe40a9e2024-03-07 21:44:26 +08002624 return;
developerfd40db22021-04-29 10:08:25 +08002625 }
2626
developerbe40a9e2024-03-07 21:44:26 +08002627 printf("\r\nswitch qos type: %d.\n", type);
developerfd40db22021-04-29 10:08:25 +08002628
2629 if (!strncmp(argv[5], "min", 4)) {
2630
2631 if (type == 0) {
developerbe40a9e2024-03-07 21:44:26 +08002632 /*min sharper-->round roubin, disable min sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002633 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2634 reg_read(reg, &value);
2635 value = 0x0;
2636 reg_write(reg, value);
2637 } else if (type == 1) {
developerbe40a9e2024-03-07 21:44:26 +08002638 /*min sharper-->sp, disable min sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002639 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2640 reg_read(reg, &value);
2641 value = 0x0;
2642 value |= (1 << 31);
2643 reg_write(reg, value);
2644 } else {
2645 printf("min sharper only support: rr or sp\n");
developerbe40a9e2024-03-07 21:44:26 +08002646 return;
developerfd40db22021-04-29 10:08:25 +08002647 }
2648 } else if (!strncmp(argv[5], "max", 4)) {
2649 if (type == 1) {
developerbe40a9e2024-03-07 21:44:26 +08002650 /*max sharper-->sp, disable max sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002651 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2652 reg_read(reg, &value);
2653 value = 0x0;
2654 value |= (1 << 31);
2655 reg_write(reg, value);
2656 } else if (type == 2) {
developerbe40a9e2024-03-07 21:44:26 +08002657 /*max sharper-->wfq, disable max sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002658 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2659 reg_read(reg, &value);
2660 value = 0x0;
2661 reg_write(reg, value);
2662 } else {
2663 printf("max sharper only support: wfq or sp\n");
developerbe40a9e2024-03-07 21:44:26 +08002664 return;
developerfd40db22021-04-29 10:08:25 +08002665 }
2666 } else {
developerbe40a9e2024-03-07 21:44:26 +08002667 printf("\r\nIllegal sharper:%s\n", argv[5]);
2668 return;
developerfd40db22021-04-29 10:08:25 +08002669 }
developerbe40a9e2024-03-07 21:44:26 +08002670 printf("reg:0x%x--value:0x%x\n", reg, value);
developerfd40db22021-04-29 10:08:25 +08002671}
2672
2673void get_upw(unsigned int *value, unsigned char base)
2674{
2675 *value &= (~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
2676 (0x7 << 16) | (0x7 << 20)));
developerbe40a9e2024-03-07 21:44:26 +08002677 switch (base) {
2678 case 0: /* port-based 0x2x40[18:16] */
2679 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2680 (0x2 << 12) | (0x7 << 16) | (0x2 << 20));
2681 break;
2682 case 1: /* tagged-based 0x2x40[10:8] */
2683 *value |= ((0x2 << 0) | (0x2 << 4) | (0x7 << 8) |
2684 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2685 break;
2686 case 2: /* DSCP-based 0x2x40[14:12] */
2687 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2688 (0x7 << 12) | (0x2 << 16) | (0x2 << 20));
2689 break;
2690 case 3: /* acl-based 0x2x40[2:0] */
2691 *value |= ((0x7 << 0) | (0x2 << 4) | (0x2 << 8) |
2692 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2693 break;
2694 case 4: /* arl-based 0x2x40[22:20] */
2695 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2696 (0x2 << 12) | (0x2 << 16) | (0x7 << 20));
2697 break;
2698 case 5: /* stag-based 0x2x40[6:4] */
2699 *value |= ((0x2 << 0) | (0x7 << 4) | (0x2 << 8) |
2700 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2701 break;
2702 default:
2703 break;
developerfd40db22021-04-29 10:08:25 +08002704 }
2705}
2706
2707void qos_set_base(int argc, char *argv[])
2708{
2709 unsigned char base = 0;
developerbe40a9e2024-03-07 21:44:26 +08002710 unsigned char port = 0;
2711 unsigned int value = 0;
developer546b2792024-06-15 20:31:38 +08002712 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002713
2714 if (argc < 5)
2715 return;
2716
developer546b2792024-06-15 20:31:38 +08002717 errno = 0;
2718 port = strtoul(argv[3], &endptr, 10);
2719 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2720 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
developerfd40db22021-04-29 10:08:25 +08002721 return;
2722 }
2723
developer546b2792024-06-15 20:31:38 +08002724 errno = 0;
2725 base = strtoul(argv[4], &endptr, 10);
2726 if (errno != 0 || *endptr != '\0' || base > 5) {
2727 printf(HELP_QOS_BASE);
developerfd40db22021-04-29 10:08:25 +08002728 return;
2729 }
2730
2731 printf("\r\nswitch qos base : %d. (port-based:0, tag-based:1,\
developerbe40a9e2024-03-07 21:44:26 +08002732 dscp-based:2, acl-based:3, arl-based:4, stag-based:5)\n", base);
developerfd40db22021-04-29 10:08:25 +08002733 if (chip_name == 0x7530) {
2734
2735 reg_read(0x44, &value);
2736 get_upw(&value, base);
2737 reg_write(0x44, value);
2738 printf("reg: 0x44, value: 0x%x\n", value);
2739
developer8c3871b2022-07-01 14:07:53 +08002740 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002741
2742 reg_read(GSW_UPW(port), &value);
2743 get_upw(&value, base);
2744 reg_write(GSW_UPW(port), value);
developerbe40a9e2024-03-07 21:44:26 +08002745 printf("reg:0x%x, value: 0x%x\n", GSW_UPW(port), value);
developerfd40db22021-04-29 10:08:25 +08002746
2747 } else {
2748 printf("unknown switch device");
2749 return;
2750 }
2751}
2752
2753void qos_wfq_set_weight(int argc, char *argv[])
2754{
developerbe40a9e2024-03-07 21:44:26 +08002755 int port = 0, weight[8], i = 0;
2756 unsigned char queue = 0;
2757 unsigned int reg = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002758
2759 port = atoi(argv[3]);
2760
2761 for (i = 0; i < 8; i++) {
2762 weight[i] = atoi(argv[i + 4]);
2763 }
2764
2765 /* MT7530 total 7 port */
2766 if (port < 0 || port > 6) {
2767 printf(HELP_QOS_PORT_WEIGHT);
2768 return;
2769 }
2770
2771 for (i = 0; i < 8; i++) {
2772 if (weight[i] < 1 || weight[i] > 16) {
2773 printf(HELP_QOS_PORT_WEIGHT);
2774 return;
2775 }
2776 }
2777 printf("port: %x, q0: %x, q1: %x, q2: %x, q3: %x, \
developerbe40a9e2024-03-07 21:44:26 +08002778 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 +08002779
2780 for (queue = 0; queue < 8; queue++) {
2781 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2782 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002783 value &= (~(0xf << 24)); //bit24~27
developerfd40db22021-04-29 10:08:25 +08002784 value |= (((weight[queue] - 1) & 0xf) << 24);
2785 printf("reg: %x, value: %x\n", reg, value);
2786 reg_write(reg, value);
2787 }
2788}
2789
2790void qos_set_portpri(int argc, char *argv[])
2791{
developerbe40a9e2024-03-07 21:44:26 +08002792 unsigned char port = 0, prio = 0;
2793 unsigned int value = 0;
developer546b2792024-06-15 20:31:38 +08002794 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002795
developer546b2792024-06-15 20:31:38 +08002796 errno = 0;
2797 port = strtoul(argv[3], &endptr, 10);
2798 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2799 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2800 return;
2801 }
developerfd40db22021-04-29 10:08:25 +08002802
developer546b2792024-06-15 20:31:38 +08002803 errno = 0;
2804 prio = strtoul(argv[4], &endptr, 10);
2805 if (errno != 0 || *endptr != '\0' || prio > 7) {
2806 printf("Error: wrong priority, should be within 0~7\n");
developerfd40db22021-04-29 10:08:25 +08002807 return;
2808 }
2809
2810 reg_read(GSW_PCR(port), &value);
2811 value &= (~(0x7 << 24));
2812 value |= (prio << 24);
2813 reg_write(GSW_PCR(port), value);
2814 printf("write reg: %x, value: %x\n", GSW_PCR(port), value);
2815}
2816
2817void qos_set_dscppri(int argc, char *argv[])
2818{
developerbe40a9e2024-03-07 21:44:26 +08002819 unsigned char prio = 0, dscp = 0, pim_n = 0, pim_offset = 0;
2820 unsigned int value = 0, reg = 0;
developer546b2792024-06-15 20:31:38 +08002821 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002822
developer546b2792024-06-15 20:31:38 +08002823 errno = 0;
2824 dscp = strtoul(argv[3], &endptr, 10);
2825 if (errno != 0 || *endptr != '\0' || dscp > 63) {
2826 printf(HELP_QOS_DSCP_PRIO);
2827 return;
2828 }
developerfd40db22021-04-29 10:08:25 +08002829
developer546b2792024-06-15 20:31:38 +08002830 errno = 0;
2831 prio = strtoul(argv[4], &endptr, 10);
2832 if (errno != 0 || *endptr != '\0' || prio > 7) {
developerfd40db22021-04-29 10:08:25 +08002833 printf(HELP_QOS_DSCP_PRIO);
2834 return;
2835 }
2836
2837 pim_n = dscp / 10;
2838 pim_offset = (dscp - pim_n * 10) * 3;
2839 reg = 0x0058 + pim_n * 4;
2840 reg_read(reg, &value);
2841 value &= (~(0x7 << pim_offset));
2842 value |= ((prio & 0x7) << pim_offset);
2843 reg_write(reg, value);
2844 printf("write reg: %x, value: %x\n", reg, value);
2845}
2846
2847void qos_pri_mapping_queue(int argc, char *argv[])
2848{
developerbe40a9e2024-03-07 21:44:26 +08002849 unsigned char prio = 0, queue = 0, pem_n = 0, port = 0;
2850 unsigned int value = 0, reg = 0;
developer546b2792024-06-15 20:31:38 +08002851 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002852
2853 if (argc < 6)
2854 return;
2855
developer546b2792024-06-15 20:31:38 +08002856 errno = 0;
2857 port = strtoul(argv[3], &endptr, 10);
2858 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2859 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2860 return;
2861 }
2862
2863 errno = 0;
2864 prio = strtoul(argv[4], &endptr, 10);
2865 if (errno != 0 || *endptr != '\0' || prio > 7) {
2866 printf(HELP_QOS_PRIO_QMAP);
2867 return;
2868 }
developerfd40db22021-04-29 10:08:25 +08002869
developer546b2792024-06-15 20:31:38 +08002870 errno = 0;
2871 queue = strtoul(argv[5], &endptr, 10);
2872 if (errno != 0 || *endptr != '\0' || queue > 7) {
developerfd40db22021-04-29 10:08:25 +08002873 printf(HELP_QOS_PRIO_QMAP);
2874 return;
2875 }
developerbe40a9e2024-03-07 21:44:26 +08002876
developerfd40db22021-04-29 10:08:25 +08002877 if (chip_name == 0x7530) {
2878 pem_n = prio / 2;
2879 reg = pem_n * 0x4 + 0x48;
2880 reg_read(reg, &value);
2881 if (prio % 2) {
2882 value &= (~(0x7 << 24));
2883 value |= ((queue & 0x7) << 24);
2884 } else {
2885 value &= (~(0x7 << 8));
2886 value |= ((queue & 0x7) << 8);
2887 }
2888 reg_write(reg, value);
2889 printf("write reg: %x, value: %x\n", reg, value);
developer8c3871b2022-07-01 14:07:53 +08002890 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002891 pem_n = prio / 2;
2892 reg = GSW_PEM(pem_n) + 0x100 * port;
2893 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002894 if (prio % 2) { // 1 1
developerfd40db22021-04-29 10:08:25 +08002895 value &= (~(0x7 << 25));
2896 value |= ((queue & 0x7) << 25);
developerbe40a9e2024-03-07 21:44:26 +08002897 } else { // 0 0
developerfd40db22021-04-29 10:08:25 +08002898 value &= (~(0x7 << 9));
2899 value |= ((queue & 0x7) << 9);
2900 }
2901 reg_write(reg, value);
2902 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +08002903 } else {
developerfd40db22021-04-29 10:08:25 +08002904 printf("unknown switch device");
2905 return;
2906 }
2907}
2908
2909static int macMT753xVlanSetVid(unsigned char index, unsigned char active,
developerbe40a9e2024-03-07 21:44:26 +08002910 unsigned short vid, unsigned char portMap,
2911 unsigned char tagPortMap, unsigned char ivl_en,
2912 unsigned char fid, unsigned short stag)
developerfd40db22021-04-29 10:08:25 +08002913{
2914 unsigned int value = 0;
2915 unsigned int value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08002916 unsigned int reg = 0;
2917 int i = 0;
developerfd40db22021-04-29 10:08:25 +08002918
2919 printf("index: %x, active: %x, vid: %x, portMap: %x, \
developerbe40a9e2024-03-07 21:44:26 +08002920 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 +08002921
2922 value = (portMap << 16);
2923 value |= (stag << 4);
2924 value |= (ivl_en << 30);
2925 value |= (fid << 1);
2926 value |= (active ? 1 : 0);
2927
2928 // total 7 ports
2929 for (i = 0; i < 7; i++) {
2930 if (tagPortMap & (1 << i))
2931 value2 |= 0x2 << (i * 2);
2932 }
2933
2934 if (value2)
developerbe40a9e2024-03-07 21:44:26 +08002935 value |= (1 << 28); // eg_tag
developerfd40db22021-04-29 10:08:25 +08002936
developerbe40a9e2024-03-07 21:44:26 +08002937 reg = 0x98; // VAWD2
developerfd40db22021-04-29 10:08:25 +08002938 reg_write(reg, value2);
2939
developerbe40a9e2024-03-07 21:44:26 +08002940 reg = 0x94; // VAWD1
developerfd40db22021-04-29 10:08:25 +08002941 reg_write(reg, value);
2942
developerbe40a9e2024-03-07 21:44:26 +08002943 reg = 0x90; // VTCR
developerfd40db22021-04-29 10:08:25 +08002944 value = (0x80001000 + vid);
2945 reg_write(reg, value);
2946
developerbe40a9e2024-03-07 21:44:26 +08002947 reg = 0x90; // VTCR
developerfd40db22021-04-29 10:08:25 +08002948 while (1) {
2949 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002950 if ((value & 0x80000000) == 0) //table busy
developerfd40db22021-04-29 10:08:25 +08002951 break;
2952 }
2953
2954 /* switch clear */
2955 reg = 0x80;
2956 reg_write(reg, 0x8002);
2957 usleep(5000);
2958 reg_read(reg, &value);
2959
2960 printf("SetVid: index:%d active:%d vid:%d portMap:%x tagPortMap:%x\r\n",
2961 index, active, vid, portMap, tagPortMap);
2962 return 0;
2963
developerbe40a9e2024-03-07 21:44:26 +08002964} /*end macMT753xVlanSetVid */
developerfd40db22021-04-29 10:08:25 +08002965
2966static int macMT753xVlanSetPvid(unsigned char port, unsigned short pvid)
2967{
developerbe40a9e2024-03-07 21:44:26 +08002968 unsigned int value = 0;
2969 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08002970
developerbe40a9e2024-03-07 21:44:26 +08002971 /*Parameters is error */
developerfd40db22021-04-29 10:08:25 +08002972 if (port > 6)
2973 return -1;
2974
2975 reg = 0x2014 + (port * 0x100);
2976 reg_read(reg, &value);
2977 value &= ~0xfff;
2978 value |= pvid;
2979 reg_write(reg, value);
2980
2981 /* switch clear */
2982 reg = 0x80;
2983 reg_write(reg, 0x8002);
2984 usleep(5000);
2985 reg_read(reg, &value);
2986
2987 printf("SetPVID: port:%d pvid:%d\r\n", port, pvid);
2988 return 0;
2989}
developerfd40db22021-04-29 10:08:25 +08002990
2991void doVlanSetPvid(int argc, char *argv[])
2992{
2993 unsigned char port = 0;
2994 unsigned short pvid = 0;
developer3a780bf2024-06-15 20:34:27 +08002995 char *endptr;
developerfd40db22021-04-29 10:08:25 +08002996
developer3a780bf2024-06-15 20:34:27 +08002997 errno = 0;
2998 port = strtoul(argv[3], &endptr, 10);
2999 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3000 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3001 return;
3002 }
3003
3004 errno = 0;
3005 pvid = strtoul(argv[4], &endptr, 10);
3006 if (errno != 0 || *endptr != '\0' || pvid > MAX_VID_VALUE) {
developerfd40db22021-04-29 10:08:25 +08003007 printf(HELP_VLAN_PVID);
3008 return;
3009 }
3010
3011 macMT753xVlanSetPvid(port, pvid);
3012
3013 printf("port:%d pvid:%d,vlancap: max_port:%d maxvid:%d\r\n",
3014 port, pvid, SWITCH_MAX_PORT, MAX_VID_VALUE);
developerbe40a9e2024-03-07 21:44:26 +08003015} /*end doVlanSetPvid */
developerfd40db22021-04-29 10:08:25 +08003016
3017void doVlanSetVid(int argc, char *argv[])
3018{
developer3a780bf2024-06-15 20:34:27 +08003019 unsigned char index = 0, active = 0;
3020 unsigned char portMap = 0, tagPortMap = 0;
3021 unsigned short vid = 0, stag = 0;
3022 unsigned char ivl_en = 0, fid = 0;
3023 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003024
developer3a780bf2024-06-15 20:34:27 +08003025 errno = 0;
3026 index = strtoul(argv[3], &endptr, 10);
3027 if (errno != 0 || *endptr != '\0' || index >= MAX_VLAN_RULE) {
3028 printf(HELP_VLAN_VID);
3029 return;
3030 }
developerfd40db22021-04-29 10:08:25 +08003031
developer3a780bf2024-06-15 20:34:27 +08003032 errno = 0;
3033 active = strtoul(argv[4], &endptr, 10);
3034 if (errno != 0 || *endptr != '\0' || active > ACTIVED) {
3035 printf(HELP_VLAN_VID);
3036 return;
3037 }
developerfd40db22021-04-29 10:08:25 +08003038
developer3a780bf2024-06-15 20:34:27 +08003039 errno = 0;
3040 vid = strtoul(argv[5], &endptr, 10);
3041 if (errno != 0 || *endptr != '\0' || vid >= 4096) {
3042 printf(HELP_VLAN_VID);
3043 return;
3044 }
3045
3046 errno = 0;
3047 portMap = strtoul(argv[6], &endptr, 10);
3048 if (errno != 0 || *endptr != '\0') {
developerfd40db22021-04-29 10:08:25 +08003049 printf(HELP_VLAN_VID);
3050 return;
3051 }
3052
developer3a780bf2024-06-15 20:34:27 +08003053 errno = 0;
3054 tagPortMap = strtoul(argv[7], &endptr, 10);
3055 if (errno != 0 || *endptr != '\0') {
3056 printf(HELP_VLAN_VID);
3057 return;
3058 }
developerfd40db22021-04-29 10:08:25 +08003059
3060 printf("subcmd parameter argc = %d\r\n", argc);
3061 if (argc >= 9) {
developer3a780bf2024-06-15 20:34:27 +08003062 errno = 0;
3063 ivl_en = strtoul(argv[8], &endptr, 10);
3064 if (errno != 0 || *endptr != '\0') {
3065 printf(HELP_VLAN_VID);
3066 return;
3067 }
developerfd40db22021-04-29 10:08:25 +08003068 if (argc >= 10) {
developer3a780bf2024-06-15 20:34:27 +08003069 errno = 0;
3070 fid = strtoul(argv[9], &endptr, 16);
3071 if (errno != 0 || *endptr != '\0') {
3072 printf(HELP_VLAN_VID);
3073 return;
3074 }
3075 if (argc >= 11) {
3076 errno = 0;
3077 stag = strtoul(argv[10], &endptr, 10);
3078 if (errno != 0 || *endptr != '\0') {
3079 printf(HELP_VLAN_VID);
3080 return;
3081 }
3082 }
developerfd40db22021-04-29 10:08:25 +08003083 }
3084 }
3085 macMT753xVlanSetVid(index, active, vid, portMap, tagPortMap,
3086 ivl_en, fid, stag);
3087 printf("index:%d active:%d vid:%d\r\n", index, active, vid);
developerbe40a9e2024-03-07 21:44:26 +08003088} /*end doVlanSetVid */
developerfd40db22021-04-29 10:08:25 +08003089
3090void doVlanSetAccFrm(int argc, char *argv[])
3091{
3092 unsigned char port = 0;
3093 unsigned char type = 0;
developerbe40a9e2024-03-07 21:44:26 +08003094 unsigned int value = 0;
3095 unsigned int reg = 0;
developer3a780bf2024-06-15 20:34:27 +08003096 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003097
developer3a780bf2024-06-15 20:34:27 +08003098 errno = 0;
3099 port = strtoul(argv[3], &endptr, 10);
3100 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3101 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3102 return;
3103 }
developerfd40db22021-04-29 10:08:25 +08003104
developer3a780bf2024-06-15 20:34:27 +08003105 errno = 0;
3106 type = strtoul(argv[4], &endptr, 10);
3107 if (errno != 0 || *endptr != '\0' || type > REG_PVC_ACC_FRM_RELMASK) {
developerfd40db22021-04-29 10:08:25 +08003108 printf(HELP_VLAN_ACC_FRM);
3109 return;
3110 }
3111
developer3a780bf2024-06-15 20:34:27 +08003112 printf("port: %d, type: %d\n", port, type);
3113
developerfd40db22021-04-29 10:08:25 +08003114 reg = REG_PVC_P0_ADDR + port * 0x100;
3115 reg_read(reg, &value);
3116 value &= (~REG_PVC_ACC_FRM_MASK);
3117 value |= ((unsigned int)type << REG_PVC_ACC_FRM_OFFT);
3118
3119 printf("write reg: %x, value: %x\n", reg, value);
3120 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003121} /*end doVlanSetAccFrm */
developerfd40db22021-04-29 10:08:25 +08003122
3123void doVlanSetPortAttr(int argc, char *argv[])
3124{
3125 unsigned char port = 0;
3126 unsigned char attr = 0;
developerbe40a9e2024-03-07 21:44:26 +08003127 unsigned int value = 0;
3128 unsigned int reg = 0;
developer3a780bf2024-06-15 20:34:27 +08003129 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003130
developer3a780bf2024-06-15 20:34:27 +08003131 errno = 0;
3132 port = strtoul(argv[3], &endptr, 10);
3133 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3134 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3135 return;
3136 }
developerfd40db22021-04-29 10:08:25 +08003137
developer3a780bf2024-06-15 20:34:27 +08003138 errno = 0;
3139 attr = strtoul(argv[4], &endptr, 10);
3140 if (errno != 0 || *endptr != '\0' || attr > 3) {
developerfd40db22021-04-29 10:08:25 +08003141 printf(HELP_VLAN_PORT_ATTR);
3142 return;
3143 }
3144
developer3a780bf2024-06-15 20:34:27 +08003145 printf("port: %x, attr: %x\n", port, attr);
3146
developerfd40db22021-04-29 10:08:25 +08003147 reg = 0x2010 + port * 0x100;
3148 reg_read(reg, &value);
3149 value &= (0xffffff3f);
3150 value |= (attr << 6);
3151
3152 printf("write reg: %x, value: %x\n", reg, value);
3153 reg_write(reg, value);
3154}
3155
3156void doVlanSetPortMode(int argc, char *argv[])
3157{
3158 unsigned char port = 0;
3159 unsigned char mode = 0;
developerbe40a9e2024-03-07 21:44:26 +08003160 unsigned int value = 0;
3161 unsigned int reg = 0;
developer3a780bf2024-06-15 20:34:27 +08003162 char *endptr;
developerbe40a9e2024-03-07 21:44:26 +08003163
developer3a780bf2024-06-15 20:34:27 +08003164 errno = 0;
3165 port = strtoul(argv[3], &endptr, 10);
3166 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3167 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3168 return;
3169 }
developerfd40db22021-04-29 10:08:25 +08003170
developer3a780bf2024-06-15 20:34:27 +08003171 errno = 0;
3172 mode = strtoul(argv[4], &endptr, 10);
3173 if (errno != 0 || *endptr != '\0' || mode > 3) {
developerfd40db22021-04-29 10:08:25 +08003174 printf(HELP_VLAN_PORT_MODE);
3175 return;
3176 }
3177
developer3a780bf2024-06-15 20:34:27 +08003178 printf("port: %x, mode: %x\n", port, mode);
3179
developerfd40db22021-04-29 10:08:25 +08003180 reg = 0x2004 + port * 0x100;
3181 reg_read(reg, &value);
3182 value &= (~((1 << 0) | (1 << 1)));
3183 value |= (mode & 0x3);
3184 printf("write reg: %x, value: %x\n", reg, value);
3185 reg_write(reg, value);
3186}
3187
3188void doVlanSetEgressTagPCR(int argc, char *argv[])
3189{
3190 unsigned char port = 0;
3191 unsigned char eg_tag = 0;
developerbe40a9e2024-03-07 21:44:26 +08003192 unsigned int value = 0;
3193 unsigned int reg = 0;
developer3a780bf2024-06-15 20:34:27 +08003194 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003195
developer3a780bf2024-06-15 20:34:27 +08003196 errno = 0;
3197 port = strtoul(argv[3], &endptr, 10);
3198 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3199 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3200 return;
3201 }
developerfd40db22021-04-29 10:08:25 +08003202
developer3a780bf2024-06-15 20:34:27 +08003203 errno = 0;
3204 eg_tag = strtoul(argv[4], &endptr, 10);
3205 if (errno != 0 || *endptr != '\0' || (eg_tag > REG_PCR_EG_TAG_RELMASK)) {
developerfd40db22021-04-29 10:08:25 +08003206 printf(HELP_VLAN_EGRESS_TAG_PCR);
3207 return;
3208 }
3209
developer3a780bf2024-06-15 20:34:27 +08003210 printf("port: %d, eg_tag: %d\n", port, eg_tag);
3211
developerfd40db22021-04-29 10:08:25 +08003212 reg = REG_PCR_P0_ADDR + port * 0x100;
3213 reg_read(reg, &value);
3214 value &= (~REG_PCR_EG_TAG_MASK);
3215 value |= ((unsigned int)eg_tag << REG_PCR_EG_TAG_OFFT);
3216
3217 printf("write reg: %x, value: %x\n", reg, value);
3218 reg_write(reg, value);
3219
developerbe40a9e2024-03-07 21:44:26 +08003220} /*end doVlanSetEgressTagPCR */
developerfd40db22021-04-29 10:08:25 +08003221
3222void doVlanSetEgressTagPVC(int argc, char *argv[])
3223{
3224 unsigned char port = 0;
3225 unsigned char eg_tag = 0;
developerbe40a9e2024-03-07 21:44:26 +08003226 unsigned int value = 0;
3227 unsigned int reg = 0;
developer3a780bf2024-06-15 20:34:27 +08003228 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003229
developer3a780bf2024-06-15 20:34:27 +08003230 errno = 0;
3231 port = strtoul(argv[3], &endptr, 10);
3232 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3233 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3234 return;
3235 }
developerfd40db22021-04-29 10:08:25 +08003236
developer3a780bf2024-06-15 20:34:27 +08003237 errno = 0;
3238 eg_tag = strtoul(argv[4], &endptr, 10);
3239 if (errno != 0 || *endptr != '\0' || (eg_tag > REG_PVC_EG_TAG_RELMASK)) {
developerfd40db22021-04-29 10:08:25 +08003240 printf(HELP_VLAN_EGRESS_TAG_PVC);
3241 return;
3242 }
3243
developer3a780bf2024-06-15 20:34:27 +08003244 printf("port: %d, eg_tag: %d\n", port, eg_tag);
3245
developerfd40db22021-04-29 10:08:25 +08003246 reg = REG_PVC_P0_ADDR + port * 0x100;
3247 reg_read(reg, &value);
3248 value &= (~REG_PVC_EG_TAG_MASK);
3249 value |= ((unsigned int)eg_tag << REG_PVC_EG_TAG_OFFT);
3250
3251 printf("write reg: %x, value: %x\n", reg, value);
3252 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003253} /*end doVlanSetEgressTagPVC */
developerfd40db22021-04-29 10:08:25 +08003254
3255void doArlAging(int argc, char *argv[])
3256{
3257 unsigned char aging_en = 0;
developerbe40a9e2024-03-07 21:44:26 +08003258 unsigned int time = 0, aging_cnt = 0, aging_unit = 0, value = 0, reg =
3259 0;
developerfd40db22021-04-29 10:08:25 +08003260
3261 aging_en = atoi(argv[3]);
3262 time = atoi(argv[4]);
3263 printf("aging_en: %x, aging time: %x\n", aging_en, time);
3264
developerbe40a9e2024-03-07 21:44:26 +08003265 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003266 if ((aging_en != 0 && aging_en != 1) || (time <= 0 || time > 65536)) {
3267 printf(HELP_ARL_AGING);
3268 return;
3269 }
3270
3271 reg = 0xa0;
3272 reg_read(reg, &value);
3273 value &= (~(1 << 20));
3274 if (!aging_en) {
3275 value |= (1 << 20);
3276 }
3277
3278 aging_unit = (time / 0x100) + 1;
3279 aging_cnt = (time / aging_unit);
3280 aging_unit--;
3281 aging_cnt--;
3282
3283 value &= (0xfff00000);
3284 value |= ((aging_cnt << 12) | aging_unit);
3285
3286 printf("aging_unit: %x, aging_cnt: %x\n", aging_unit, aging_cnt);
3287 printf("write reg: %x, value: %x\n", reg, value);
3288
3289 reg_write(reg, value);
3290}
3291
3292void doMirrorEn(int argc, char *argv[])
3293{
developerbe40a9e2024-03-07 21:44:26 +08003294 unsigned char mirror_en = 0;
3295 unsigned char mirror_port = 0;
3296 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003297
3298 mirror_en = atoi(argv[3]);
3299 mirror_port = atoi(argv[4]);
3300
3301 printf("mirror_en: %d, mirror_port: %d\n", mirror_en, mirror_port);
3302
developerbe40a9e2024-03-07 21:44:26 +08003303 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003304 if ((mirror_en > 1) || (mirror_port > REG_CFC_MIRROR_PORT_RELMASK)) {
3305 printf(HELP_MIRROR_EN);
3306 return;
3307 }
3308
3309 reg = REG_CFC_ADDR;
3310 reg_read(reg, &value);
3311 value &= (~REG_CFC_MIRROR_EN_MASK);
3312 value |= (mirror_en << REG_CFC_MIRROR_EN_OFFT);
3313 value &= (~REG_CFC_MIRROR_PORT_MASK);
3314 value |= (mirror_port << REG_CFC_MIRROR_PORT_OFFT);
3315
3316 printf("write reg: %x, value: %x\n", reg, value);
3317 reg_write(reg, value);
3318
developerbe40a9e2024-03-07 21:44:26 +08003319} /*end doMirrorEn */
developerfd40db22021-04-29 10:08:25 +08003320
3321void doMirrorPortBased(int argc, char *argv[])
3322{
developerbe40a9e2024-03-07 21:44:26 +08003323 unsigned char port = 0, port_tx_mir = 0, port_rx_mir = 0, vlan_mis =
3324 0, acl_mir = 0, igmp_mir = 0;
3325 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003326
3327 port = atoi(argv[3]);
3328 port_tx_mir = atoi(argv[4]);
3329 port_rx_mir = atoi(argv[5]);
3330 acl_mir = atoi(argv[6]);
3331 vlan_mis = atoi(argv[7]);
3332 igmp_mir = atoi(argv[8]);
3333
developerbe40a9e2024-03-07 21:44:26 +08003334 printf
3335 ("port:%d, port_tx_mir:%d, port_rx_mir:%d, acl_mir:%d, vlan_mis:%d, igmp_mir:%d\n",
3336 port, port_tx_mir, port_rx_mir, acl_mir, vlan_mis, igmp_mir);
developerfd40db22021-04-29 10:08:25 +08003337
developerbe40a9e2024-03-07 21:44:26 +08003338 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003339 //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 +08003340 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 +08003341 printf(HELP_MIRROR_PORTBASED);
3342 return;
3343 }
3344
3345 reg = REG_PCR_P0_ADDR + port * 0x100;
3346 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003347 value &=
3348 ~(REG_PORT_TX_MIR_MASK | REG_PORT_RX_MIR_MASK | REG_PCR_ACL_MIR_MASK
3349 | REG_PCR_VLAN_MIS_MASK);
3350 value |=
3351 (port_tx_mir << REG_PORT_TX_MIR_OFFT) +
3352 (port_rx_mir << REG_PORT_RX_MIR_OFFT);
3353 value |=
3354 (acl_mir << REG_PCR_ACL_MIR_OFFT) +
3355 (vlan_mis << REG_PCR_VLAN_MIS_OFFT);
developerfd40db22021-04-29 10:08:25 +08003356
3357 printf("write reg: %x, value: %x\n", reg, value);
3358 reg_write(reg, value);
3359
3360 reg = REG_PIC_P0_ADDR + port * 0x100;
3361 reg_read(reg, &value);
3362 value &= ~(REG_PIC_IGMP_MIR_MASK);
3363 value |= (igmp_mir << REG_PIC_IGMP_MIR_OFFT);
3364
3365 printf("write reg: %x, value: %x\n", reg, value);
3366 reg_write(reg, value);
3367
developerbe40a9e2024-03-07 21:44:26 +08003368} /*end doMirrorPortBased */
developerfd40db22021-04-29 10:08:25 +08003369
3370void doStp(int argc, char *argv[])
3371{
3372 unsigned char port = 0;
3373 unsigned char fid = 0;
3374 unsigned char state = 0;
developerbe40a9e2024-03-07 21:44:26 +08003375 unsigned int value = 0;
3376 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08003377
3378 port = atoi(argv[2]);
3379 fid = atoi(argv[3]);
3380 state = atoi(argv[4]);
3381
3382 printf("port: %d, fid: %d, state: %d\n", port, fid, state);
3383
developerbe40a9e2024-03-07 21:44:26 +08003384 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003385 if ((port > MAX_PORT + 1) || (fid > 7) || (state > 3)) {
3386 printf(HELP_STP);
3387 return;
3388 }
3389
3390 reg = REG_SSC_P0_ADDR + port * 0x100;
3391 reg_read(reg, &value);
3392 value &= (~(3 << (fid << 2)));
3393 value |= ((unsigned int)state << (fid << 2));
3394
3395 printf("write reg: %x, value: %x\n", reg, value);
3396 reg_write(reg, value);
3397}
3398
developerbe40a9e2024-03-07 21:44:26 +08003399void _ingress_rate_set(int on_off, int port, int bw)
developerfd40db22021-04-29 10:08:25 +08003400{
developerbe40a9e2024-03-07 21:44:26 +08003401 unsigned int reg = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08003402
3403 reg = 0x1800 + (0x100 * port);
3404 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08003405 /*token-bucket */
developerfd40db22021-04-29 10:08:25 +08003406 if (on_off == 1) {
3407 if (chip_name == 0x7530) {
3408 if (bw > 1000000) {
developerbe40a9e2024-03-07 21:44:26 +08003409 printf
3410 ("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",
3411 bw);
3412 return;
developerfd40db22021-04-29 10:08:25 +08003413 }
developerbe40a9e2024-03-07 21:44:26 +08003414 value =
3415 ((bw / 32) << 16) + (1 << 15) + (7 << 8) +
3416 (1 << 7) + 0x0f;
developer8c3871b2022-07-01 14:07:53 +08003417 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3418 if ((chip_name == 0x7531) && (bw > 2500000)) {
developerbe40a9e2024-03-07 21:44:26 +08003419 printf
3420 ("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",
3421 bw);
3422 return;
developerfd40db22021-04-29 10:08:25 +08003423 }
developer8c3871b2022-07-01 14:07:53 +08003424
3425 if ((chip_name == 0x7988) && (bw > 4000000)) {
developerbe40a9e2024-03-07 21:44:26 +08003426 printf
3427 ("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",
3428 bw);
3429 return;
developerfd40db22021-04-29 10:08:25 +08003430 }
developer8c3871b2022-07-01 14:07:53 +08003431
developerbe40a9e2024-03-07 21:44:26 +08003432 if (bw / 32 >= 65536) //supoort 2.5G case
3433 value =
3434 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3435 (1 << 12) + (7 << 8) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003436 else
developerbe40a9e2024-03-07 21:44:26 +08003437 value =
3438 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3439 (7 << 8) + 0xf;
3440 } else
developerfd40db22021-04-29 10:08:25 +08003441 printf("unknow chip\n");
3442 }
developerfd40db22021-04-29 10:08:25 +08003443#if leaky_bucket
3444 reg_read(reg, &value);
3445 value &= 0xffff0000;
developerbe40a9e2024-03-07 21:44:26 +08003446 if (on_off == 1) {
developerfd40db22021-04-29 10:08:25 +08003447 value |= on_off << 15;
3448 //7530 same as 7531
3449 if (bw < 100) {
3450 value |= (0x0 << 8);
3451 value |= bw;
3452 } else if (bw < 1000) {
3453 value |= (0x1 << 8);
3454 value |= bw / 10;
3455 } else if (bw < 10000) {
3456 value |= (0x2 << 8);
3457 value |= bw / 100;
3458 } else if (bw < 100000) {
3459 value |= (0x3 << 8);
3460 value |= bw / 1000;
3461 } else {
3462 value |= (0x4 << 8);
3463 value |= bw / 10000;
3464 }
3465 }
3466#endif
3467 reg_write(reg, value);
3468 reg = 0x1FFC;
3469 reg_read(reg, &value);
3470 value = 0x110104;
3471 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003472
3473 if (on_off)
3474 printf("switch port=%d, bw=%d\n", port, bw);
3475 else
3476 printf("switch port=%d ingress rate limit off\n", port);
developerfd40db22021-04-29 10:08:25 +08003477}
3478
developerbe40a9e2024-03-07 21:44:26 +08003479void ingress_rate_set(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003480{
developerbe40a9e2024-03-07 21:44:26 +08003481 int on_off = 0, port = 0, bw = 0;
developer997ed6b2024-03-26 14:03:42 +08003482 char *endptr;
developerbe40a9e2024-03-07 21:44:26 +08003483
developer997ed6b2024-03-26 14:03:42 +08003484 /* clear errno before conversion to detect overflow */
3485 errno = 0;
3486 port = strtoul(argv[3], &endptr, 0);
3487
3488 if (errno == ERANGE) {
3489 printf("Conversion error, value out of range\n");
3490 return;
3491 }
3492 if (*endptr != '\0') {
3493 printf("Conversion error, no digits were found\n");
3494 return;
3495 }
3496
3497 if (port < 0 || port > 6) {
3498 printf("Wrong port range, should be within 0-6\n");
3499 return;
3500 }
3501
developerbe40a9e2024-03-07 21:44:26 +08003502 if (argv[2][1] == 'n') {
developer997ed6b2024-03-26 14:03:42 +08003503 errno = 0;
3504 bw = strtoul(argv[4], &endptr, 0);
3505 if (errno == ERANGE) {
3506 printf("Conversion error, value out of range\n");
3507 return;
3508 }
3509 if (*endptr != '\0') {
3510 printf("Conversion error, no digits were found\n");
3511 return;
3512 }
developerbe40a9e2024-03-07 21:44:26 +08003513 on_off = 1;
3514 } else if (argv[2][1] == 'f') {
3515 if (argc != 4)
3516 return;
3517 on_off = 0;
3518 }
3519
3520 _ingress_rate_set(on_off, port, bw);
3521}
3522
3523void _egress_rate_set(int on_off, int port, int bw)
3524{
3525 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003526
3527 reg = 0x1040 + (0x100 * port);
3528 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08003529 /*token-bucket */
developerfd40db22021-04-29 10:08:25 +08003530 if (on_off == 1) {
3531 if (chip_name == 0x7530) {
3532 if (bw < 0 || bw > 1000000) {
developerbe40a9e2024-03-07 21:44:26 +08003533 printf
3534 ("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",
3535 bw);
3536 return;
developerfd40db22021-04-29 10:08:25 +08003537 }
developerbe40a9e2024-03-07 21:44:26 +08003538 value =
3539 ((bw / 32) << 16) + (1 << 15) + (7 << 8) +
3540 (1 << 7) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003541 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3542 if ((chip_name == 0x7531) && (bw < 0 || bw > 2500000)) {
developerbe40a9e2024-03-07 21:44:26 +08003543 printf
3544 ("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",
3545 bw);
3546 return;
developerfd40db22021-04-29 10:08:25 +08003547 }
developer8c3871b2022-07-01 14:07:53 +08003548 if ((chip_name == 0x7988) && (bw < 0 || bw > 4000000)) {
developerbe40a9e2024-03-07 21:44:26 +08003549 printf
3550 ("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",
3551 bw);
3552 return;
developer8c3871b2022-07-01 14:07:53 +08003553 }
3554
developerbe40a9e2024-03-07 21:44:26 +08003555 if (bw / 32 >= 65536) //support 2.5G cases
3556 value =
3557 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3558 (1 << 12) + (7 << 8) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003559 else
developerbe40a9e2024-03-07 21:44:26 +08003560 value =
3561 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3562 (7 << 8) + 0xf;
3563 } else
developerfd40db22021-04-29 10:08:25 +08003564 printf("unknow chip\n");
3565 }
3566 reg_write(reg, value);
3567 reg = 0x10E0;
3568 reg_read(reg, &value);
3569 value &= 0x18;
3570 reg_write(reg, value);
3571
developerbe40a9e2024-03-07 21:44:26 +08003572 if (on_off)
3573 printf("switch port=%d, bw=%d\n", port, bw);
3574 else
3575 printf("switch port=%d egress rate limit off\n", port);
3576}
3577
3578void egress_rate_set(int argc, char *argv[])
3579{
3580 unsigned int value = 0, reg = 0;
3581 int on_off = 0, port = 0, bw = 0;
developer997ed6b2024-03-26 14:03:42 +08003582 char *endptr;
developerbe40a9e2024-03-07 21:44:26 +08003583
developer997ed6b2024-03-26 14:03:42 +08003584 /* clear errno before conversion to detect overflow */
3585 errno = 0;
3586 port = strtoul(argv[3], &endptr, 0);
3587 if (errno == ERANGE) {
3588 printf("Conversion error, value out of range\n");
3589 return;
3590 }
3591 if (*endptr != '\0') {
3592 printf("Conversion error, no digits were found\n");
3593 return;
3594 }
3595 if (port < 0 || port > 6) {
3596 printf("Wrong port range, should be within 0-6\n");
3597 return;
3598 }
developerbe40a9e2024-03-07 21:44:26 +08003599 if (argv[2][1] == 'n') {
developer997ed6b2024-03-26 14:03:42 +08003600 errno = 0;
3601 bw = strtoul(argv[4], &endptr, 0);
3602 if (errno == ERANGE) {
3603 printf("Conversion error, value out of range\n");
3604 return;
3605 }
3606 if (*endptr != '\0') {
3607 printf("Conversion error, no digits were found\n");
3608 return;
3609 }
developerbe40a9e2024-03-07 21:44:26 +08003610 on_off = 1;
3611 } else if (argv[2][1] == 'f') {
3612 if (argc != 4)
3613 return;
3614 on_off = 0;
3615 }
3616
3617 _egress_rate_set(on_off, port, bw);
developerfd40db22021-04-29 10:08:25 +08003618}
3619
3620void rate_control(int argc, char *argv[])
3621{
3622 unsigned char dir = 0;
3623 unsigned char port = 0;
3624 unsigned int rate = 0;
developer3a780bf2024-06-15 20:34:27 +08003625 char *endptr;
developerfd40db22021-04-29 10:08:25 +08003626
developer3a780bf2024-06-15 20:34:27 +08003627 errno = 0;
3628 dir = strtoul(argv[2], &endptr, 10);
3629 if (errno != 0 || *endptr != '\0' || dir > 1) {
3630 printf("Error: wrong port member, should be 0:egress, 1:ingress\n");
3631 return;
3632 }
developerfd40db22021-04-29 10:08:25 +08003633
developer3a780bf2024-06-15 20:34:27 +08003634 errno = 0;
3635 port = strtoul(argv[3], &endptr, 10);
3636 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3637 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3638 return;
3639 }
3640
3641 errno = 0;
3642 rate = strtoul(argv[4], &endptr, 10);
3643 if (errno != 0 || *endptr != '\0') {
3644 printf("Error: wrong traffic rate, unit is kbps\n");
developerfd40db22021-04-29 10:08:25 +08003645 return;
developer3a780bf2024-06-15 20:34:27 +08003646 }
developerfd40db22021-04-29 10:08:25 +08003647
developerbe40a9e2024-03-07 21:44:26 +08003648 if (dir == 1) //ingress
3649 _ingress_rate_set(1, port, rate);
3650 else if (dir == 0) //egress
3651 _egress_rate_set(1, port, rate);
developerfd40db22021-04-29 10:08:25 +08003652}
3653
developerbe40a9e2024-03-07 21:44:26 +08003654void collision_pool_enable(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003655{
3656
developerbe40a9e2024-03-07 21:44:26 +08003657 unsigned char enable = 0;
3658 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003659
3660 enable = atoi(argv[3]);
3661
developerfd40db22021-04-29 10:08:25 +08003662 printf("collision pool enable: %d \n", enable);
3663
developerbe40a9e2024-03-07 21:44:26 +08003664 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003665 if (enable > 1) {
3666 printf(HELP_COLLISION_POOL_EN);
developerbe40a9e2024-03-07 21:44:26 +08003667 return;
developerfd40db22021-04-29 10:08:25 +08003668 }
3669
developer8c3871b2022-07-01 14:07:53 +08003670 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003671 reg = REG_CPGC_ADDR;
developerbe40a9e2024-03-07 21:44:26 +08003672 if (enable == 1) {
developerfd40db22021-04-29 10:08:25 +08003673 /* active reset */
3674 reg_read(reg, &value);
3675 value &= (~REG_CPCG_COL_RST_N_MASK);
3676 reg_write(reg, value);
3677
3678 /* enanble clock */
3679 reg_read(reg, &value);
3680 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3681 value |= (1 << REG_CPCG_COL_CLK_EN_OFFT);
3682 reg_write(reg, value);
3683
3684 /* inactive reset */
3685 reg_read(reg, &value);
3686 value &= (~REG_CPCG_COL_RST_N_MASK);
3687 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3688 reg_write(reg, value);
3689
3690 /* enable collision pool */
3691 reg_read(reg, &value);
3692 value &= (~REG_CPCG_COL_EN_MASK);
3693 value |= (1 << REG_CPCG_COL_EN_OFFT);
3694 reg_write(reg, value);
3695
3696 reg_read(reg, &value);
3697 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003698 } else {
developerfd40db22021-04-29 10:08:25 +08003699
3700 /* disable collision pool */
3701 reg_read(reg, &value);
3702 value &= (~REG_CPCG_COL_EN_MASK);
3703 reg_write(reg, value);
3704
3705 /* active reset */
3706 reg_read(reg, &value);
3707 value &= (~REG_CPCG_COL_RST_N_MASK);
3708 reg_write(reg, value);
3709
3710 /* inactive reset */
3711 reg_read(reg, &value);
3712 value &= (~REG_CPCG_COL_RST_N_MASK);
3713 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3714 reg_write(reg, value);
3715
3716 /* disable clock */
3717 reg_read(reg, &value);
3718 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3719 reg_write(reg, value);
3720
3721 reg_read(reg, &value);
3722 printf("write reg: %x, value: %x\n", reg, value);
3723
3724 }
developerbe40a9e2024-03-07 21:44:26 +08003725 } else {
developerfd40db22021-04-29 10:08:25 +08003726 printf("\nCommand not support by this chip.\n");
developerbe40a9e2024-03-07 21:44:26 +08003727 }
developerfd40db22021-04-29 10:08:25 +08003728}
3729
developerbe40a9e2024-03-07 21:44:26 +08003730void collision_pool_mac_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003731{
developerbe40a9e2024-03-07 21:44:26 +08003732 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003733
developer8c3871b2022-07-01 14:07:53 +08003734 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003735 reg = REG_CPGC_ADDR;
3736 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003737 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003738 table_dump_internal(COLLISION_TABLE);
3739 else
developerbe40a9e2024-03-07 21:44:26 +08003740 printf
3741 ("\ncollision pool is disabled, please enable it before use this command.\n");
3742 } else {
developerfd40db22021-04-29 10:08:25 +08003743 printf("\nCommand not support by this chip.\n");
3744 }
3745}
3746
developerbe40a9e2024-03-07 21:44:26 +08003747void collision_pool_dip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003748{
developerbe40a9e2024-03-07 21:44:26 +08003749 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003750
developer8c3871b2022-07-01 14:07:53 +08003751 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003752 reg = REG_CPGC_ADDR;
3753 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003754 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003755 dip_dump_internal(COLLISION_TABLE);
3756 else
developerbe40a9e2024-03-07 21:44:26 +08003757 printf
3758 ("\ncollision pool is disabled, please enable it before use this command.\n");
3759 } else {
developerfd40db22021-04-29 10:08:25 +08003760 printf("\nCommand not support by this chip.\n");
3761 }
developerfd40db22021-04-29 10:08:25 +08003762}
3763
developerbe40a9e2024-03-07 21:44:26 +08003764void collision_pool_sip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003765{
developerbe40a9e2024-03-07 21:44:26 +08003766 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003767
developerbe40a9e2024-03-07 21:44:26 +08003768 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003769 reg = REG_CPGC_ADDR;
3770 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003771 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003772 sip_dump_internal(COLLISION_TABLE);
3773 else
developerbe40a9e2024-03-07 21:44:26 +08003774 printf
3775 ("\ncollision pool is disabled, please enable it before use this command.\n");
3776 } else {
developerfd40db22021-04-29 10:08:25 +08003777 printf("\nCommand not support by this chip.\n");
3778 }
developerfd40db22021-04-29 10:08:25 +08003779}
3780
3781void pfc_get_rx_counter(int argc, char *argv[])
3782{
developerbe40a9e2024-03-07 21:44:26 +08003783 int port = 0;
3784 unsigned int value = 0, reg = 0;
3785 unsigned int user_pri = 0;
developerfd40db22021-04-29 10:08:25 +08003786
3787 port = strtoul(argv[3], NULL, 0);
3788 if (port < 0 || 6 < port) {
3789 printf("wrong port range, should be within 0~6\n");
3790 return;
3791 }
3792
developerbe40a9e2024-03-07 21:44:26 +08003793 if (chip_name == 0x7531 || chip_name == 0x7988) {
3794 reg = PFC_RX_COUNTER_L(port);
developerfd40db22021-04-29 10:08:25 +08003795 reg_read(reg, &value);
3796 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003797 printf("\n port %d rx pfc (up=0)pause on counter is %d.\n",
3798 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003799 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003800 printf("\n port %d rx pfc (up=1)pause on counter is %d.\n",
3801 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003802 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003803 printf("\n port %d rx pfc (up=2)pause on counter is %d.\n",
3804 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003805 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003806 printf("\n port %d rx pfc (up=3)pause on counter is %d.\n",
3807 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003808
developerbe40a9e2024-03-07 21:44:26 +08003809 reg = PFC_RX_COUNTER_H(port);
developerfd40db22021-04-29 10:08:25 +08003810 reg_read(reg, &value);
3811 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003812 printf("\n port %d rx pfc (up=4)pause on counter is %d.\n",
3813 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003814 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003815 printf("\n port %d rx pfc (up=5)pause on counter is %d.\n",
3816 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003817 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003818 printf("\n port %d rx pfc (up=6)pause on counter is %d.\n",
3819 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003820 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003821 printf("\n port %d rx pfc (up=7)pause on counter is %d.\n",
3822 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003823
3824 /* for rx counter could be updated successfully */
3825 reg_read(PMSR_P(port), &value);
3826 reg_read(PMSR_P(port), &value);
developerbe40a9e2024-03-07 21:44:26 +08003827 } else {
developerfd40db22021-04-29 10:08:25 +08003828 printf("\nCommand not support by this chip.\n");
3829 }
3830
3831}
3832
3833void pfc_get_tx_counter(int argc, char *argv[])
3834{
developerbe40a9e2024-03-07 21:44:26 +08003835 int port = 0;
3836 unsigned int value = 0, reg = 0;
3837 unsigned int user_pri = 0;
developerfd40db22021-04-29 10:08:25 +08003838
3839 port = strtoul(argv[3], NULL, 0);
3840 if (port < 0 || 6 < port) {
3841 printf("wrong port range, should be within 0~6\n");
3842 return;
3843 }
3844
developer8c3871b2022-07-01 14:07:53 +08003845 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerbe40a9e2024-03-07 21:44:26 +08003846 reg = PFC_TX_COUNTER_L(port);
developerfd40db22021-04-29 10:08:25 +08003847 reg_read(reg, &value);
3848 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003849 printf("\n port %d tx pfc (up=0)pause on counter is %d.\n",
3850 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003851 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003852 printf("\n port %d tx pfc (up=1)pause on counter is %d.\n",
3853 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003854 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003855 printf("\n port %d tx pfc (up=2)pause on counter is %d.\n",
3856 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003857 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003858 printf("\n port %d tx pfc (up=3)pause on counter is %d.\n",
3859 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003860
developerbe40a9e2024-03-07 21:44:26 +08003861 reg = PFC_TX_COUNTER_H(port);
developerfd40db22021-04-29 10:08:25 +08003862 reg_read(reg, &value);
3863 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003864 printf("\n port %d tx pfc (up=4)pause on counter is %d.\n",
3865 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003866 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003867 printf("\n port %d tx pfc (up=5)pause on counter is %d.\n",
3868 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003869 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003870 printf("\n port %d tx pfc (up=6)pause on counter is %d.\n",
3871 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003872 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003873 printf("\n port %d tx pfc (up=7)pause on counter is %d.\n",
3874 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003875
3876 /* for tx counter could be updated successfully */
3877 reg_read(PMSR_P(port), &value);
3878 reg_read(PMSR_P(port), &value);
developerbe40a9e2024-03-07 21:44:26 +08003879 } else {
3880 printf("\nCommand not support by this chip.\n");
developerfd40db22021-04-29 10:08:25 +08003881 }
3882}
3883
developerbe40a9e2024-03-07 21:44:26 +08003884void read_output_queue_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003885{
developerbe40a9e2024-03-07 21:44:26 +08003886 unsigned int port = 0;
3887 unsigned int value = 0, output_queue = 0;
3888 unsigned int base = 0x220;
developerfd40db22021-04-29 10:08:25 +08003889
3890 for (port = 0; port < 7; port++) {
developerbe40a9e2024-03-07 21:44:26 +08003891 reg_write(0x7038, base + (port * 4));
developerfd40db22021-04-29 10:08:25 +08003892 reg_read(0x7034, &value);
3893 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003894 printf("\n port %d output queue 0 counter is %d.\n", port,
3895 output_queue);
developerfd40db22021-04-29 10:08:25 +08003896 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003897 printf("\n port %d output queue 1 counter is %d.\n", port,
3898 output_queue);
developerfd40db22021-04-29 10:08:25 +08003899
developerbe40a9e2024-03-07 21:44:26 +08003900 reg_write(0x7038, base + (port * 4) + 1);
developerfd40db22021-04-29 10:08:25 +08003901 reg_read(0x7034, &value);
3902 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003903 printf("\n port %d output queue 2 counter is %d.\n", port,
3904 output_queue);
developerfd40db22021-04-29 10:08:25 +08003905 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003906 printf("\n port %d output queue 3 counter is %d.\n", port,
3907 output_queue);
developerfd40db22021-04-29 10:08:25 +08003908
developerbe40a9e2024-03-07 21:44:26 +08003909 reg_write(0x7038, base + (port * 4) + 2);
developerfd40db22021-04-29 10:08:25 +08003910 reg_read(0x7034, &value);
3911 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003912 printf("\n port %d output queue 4 counter is %d.\n", port,
3913 output_queue);
developerfd40db22021-04-29 10:08:25 +08003914 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003915 printf("\n port %d output queue 5 counter is %d.\n", port,
3916 output_queue);
developerfd40db22021-04-29 10:08:25 +08003917
developerbe40a9e2024-03-07 21:44:26 +08003918 reg_write(0x7038, base + (port * 4) + 3);
developerfd40db22021-04-29 10:08:25 +08003919 reg_read(0x7034, &value);
3920 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003921 printf("\n port %d output queue 6 counter is %d.\n", port,
3922 output_queue);
developerfd40db22021-04-29 10:08:25 +08003923 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003924 printf("\n port %d output queue 7 counter is %d.\n", port,
3925 output_queue);
developerfd40db22021-04-29 10:08:25 +08003926 }
3927}
3928
developerbe40a9e2024-03-07 21:44:26 +08003929void read_free_page_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003930{
developerbe40a9e2024-03-07 21:44:26 +08003931 unsigned int value = 0;
3932 unsigned int free_page = 0, free_page_last_read = 0;
3933 unsigned int fc_free_blk_lothd = 0, fc_free_blk_hithd = 0;
3934 unsigned int fc_port_blk_thd = 0, fc_port_blk_hi_thd = 0;
3935 unsigned int queue[8] = { 0 };
developerfd40db22021-04-29 10:08:25 +08003936
developer8c3871b2022-07-01 14:07:53 +08003937 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerbe40a9e2024-03-07 21:44:26 +08003938 /* get system free page link counter */
developerfd40db22021-04-29 10:08:25 +08003939 reg_read(0x1fc0, &value);
3940 free_page = value & 0xFFF;
3941 free_page_last_read = (value & 0xFFF0000) >> 16;
3942
3943 /* get system flow control waterwark */
3944 reg_read(0x1fe0, &value);
3945 fc_free_blk_lothd = value & 0x3FF;
3946 fc_free_blk_hithd = (value & 0x3FF0000) >> 16;
3947
3948 /* get port flow control waterwark */
3949 reg_read(0x1fe4, &value);
3950 fc_port_blk_thd = value & 0x3FF;
3951 fc_port_blk_hi_thd = (value & 0x3FF0000) >> 16;
3952
3953 /* get queue flow control waterwark */
3954 reg_read(0x1fe8, &value);
developerbe40a9e2024-03-07 21:44:26 +08003955 queue[0] = value & 0x3F;
3956 queue[1] = (value & 0x3F00) >> 8;
3957 queue[2] = (value & 0x3F0000) >> 16;
3958 queue[3] = (value & 0x3F000000) >> 24;
developerfd40db22021-04-29 10:08:25 +08003959 reg_read(0x1fec, &value);
developerbe40a9e2024-03-07 21:44:26 +08003960 queue[4] = value & 0x3F;
3961 queue[5] = (value & 0x3F00) >> 8;
3962 queue[6] = (value & 0x3F0000) >> 16;
3963 queue[7] = (value & 0x3F000000) >> 24;
developerfd40db22021-04-29 10:08:25 +08003964 } else {
developerbe40a9e2024-03-07 21:44:26 +08003965 /* get system free page link counter */
developerfd40db22021-04-29 10:08:25 +08003966 reg_read(0x1fc0, &value);
3967 free_page = value & 0x3FF;
3968 free_page_last_read = (value & 0x3FF0000) >> 16;
3969
3970 /* get system flow control waterwark */
3971 reg_read(0x1fe0, &value);
3972 fc_free_blk_lothd = value & 0xFF;
3973 fc_free_blk_hithd = (value & 0xFF00) >> 8;
3974
3975 /* get port flow control waterwark */
3976 reg_read(0x1fe0, &value);
3977 fc_port_blk_thd = (value & 0xFF0000) >> 16;
3978 reg_read(0x1ff4, &value);
3979 fc_port_blk_hi_thd = (value & 0xFF00) >> 8;
3980
3981 /* get queue flow control waterwark */
3982 reg_read(0x1fe4, &value);
developerbe40a9e2024-03-07 21:44:26 +08003983 queue[0] = value & 0xF;
3984 queue[1] = (value & 0xF0) >> 4;
3985 queue[2] = (value & 0xF00) >> 8;
3986 queue[3] = (value & 0xF000) >> 12;
3987 queue[4] = (value & 0xF0000) >> 16;
3988 queue[5] = (value & 0xF00000) >> 20;
3989 queue[6] = (value & 0xF000000) >> 24;
3990 queue[7] = (value & 0xF0000000) >> 28;
developerfd40db22021-04-29 10:08:25 +08003991 }
3992
developerbe40a9e2024-03-07 21:44:26 +08003993 printf("<===Free Page=======Current=======Last Read access=====>\n");
3994 printf("\n");
3995 printf(" page counter %u %u\n ",
3996 free_page, free_page_last_read);
3997 printf("\n ");
3998 printf("=========================================================\n");
3999 printf("<===Type=======High threshold======Low threshold=========\n");
4000 printf("\n ");
4001 printf(" system: %u %u\n",
4002 fc_free_blk_hithd * 2, fc_free_blk_lothd * 2);
4003 printf(" port: %u %u\n",
4004 fc_port_blk_hi_thd * 2, fc_port_blk_thd * 2);
4005 printf(" queue 0: %u NA\n",
4006 queue[0]);
4007 printf(" queue 1: %u NA\n",
4008 queue[1]);
4009 printf(" queue 2: %u NA\n",
4010 queue[2]);
4011 printf(" queue 3: %u NA\n",
4012 queue[3]);
4013 printf(" queue 4: %u NA\n",
4014 queue[4]);
4015 printf(" queue 5: %u NA\n",
4016 queue[5]);
4017 printf(" queue 6: %u NA\n",
4018 queue[6]);
4019 printf(" queue 7: %u NA\n",
4020 queue[7]);
4021 printf("=========================================================\n");
developerfd40db22021-04-29 10:08:25 +08004022}
4023
4024void eee_enable(int argc, char *argv[])
4025{
developerbe40a9e2024-03-07 21:44:26 +08004026 unsigned long enable = 0;
4027 unsigned int value = 0;
4028 unsigned int eee_cap = 0;
developerfd40db22021-04-29 10:08:25 +08004029 unsigned int eee_en_bitmap = 0;
developerbe40a9e2024-03-07 21:44:26 +08004030 unsigned long port_map = 0;
developerfd40db22021-04-29 10:08:25 +08004031 long port_num = -1;
developerbe40a9e2024-03-07 21:44:26 +08004032 int p = 0;
developerfd40db22021-04-29 10:08:25 +08004033
4034 if (argc < 3)
4035 goto error;
4036
developerbe40a9e2024-03-07 21:44:26 +08004037 /* Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08004038 if (!strncmp(argv[2], "enable", 7))
4039 enable = 1;
4040 else if (!strncmp(argv[2], "disable", 8))
4041 enable = 0;
4042 else
4043 goto error;
4044
4045 if (argc > 3) {
4046 if (strlen(argv[3]) == 1) {
4047 port_num = strtol(argv[3], (char **)NULL, 10);
4048 if (port_num < 0 || port_num > MAX_PHY_PORT - 1) {
4049 printf("Illegal port index and port:0~4\n");
4050 goto error;
4051 }
4052 port_map = 1 << port_num;
4053 } else if (strlen(argv[3]) == 5) {
4054 port_map = 0;
4055 for (p = 0; p < MAX_PHY_PORT; p++) {
4056 if (argv[3][p] != '0' && argv[3][p] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08004057 printf
4058 ("portmap format error, should be combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08004059 goto error;
4060 }
4061 port_map |= ((argv[3][p] - '0') << p);
4062 }
4063 } else {
developerbe40a9e2024-03-07 21:44:26 +08004064 printf
4065 ("port_no or portmap format error, should be length of 1 or 5\n");
developerfd40db22021-04-29 10:08:25 +08004066 goto error;
4067 }
4068 } else {
4069 port_map = 0x1f;
4070 }
4071
developerbe40a9e2024-03-07 21:44:26 +08004072 eee_cap = (enable) ? 6 : 0;
developerfd40db22021-04-29 10:08:25 +08004073 for (p = 0; p < MAX_PHY_PORT; p++) {
4074 /* port_map describe p0p1p2p3p4 from left to rignt */
developerbe40a9e2024-03-07 21:44:26 +08004075 if (!!(port_map & (1 << p)))
developerfd40db22021-04-29 10:08:25 +08004076 mii_mgr_c45_write(p, 0x7, 0x3c, eee_cap);
4077
4078 mii_mgr_c45_read(p, 0x7, 0x3c, &value);
4079 /* mt7531: Always readback eee_cap = 0 when global EEE switch
4080 * is turned off.
4081 */
4082 if (value | eee_cap)
4083 eee_en_bitmap |= (1 << (MAX_PHY_PORT - 1 - p));
4084 }
4085
4086 /* Turn on/off global EEE switch */
developer8c3871b2022-07-01 14:07:53 +08004087 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08004088 mii_mgr_c45_read(0, 0x1f, 0x403, &value);
4089 if (eee_en_bitmap)
4090 value |= (1 << 6);
4091 else
4092 value &= ~(1 << 6);
4093 mii_mgr_c45_write(0, 0x1f, 0x403, value);
4094 } else {
4095 printf("\nCommand not support by this chip.\n");
4096 }
4097
developerbe40a9e2024-03-07 21:44:26 +08004098 printf("EEE(802.3az) %s", (enable) ? "enable" : "disable");
developerfd40db22021-04-29 10:08:25 +08004099 if (argc == 4) {
4100 if (port_num >= 0)
4101 printf(" port%ld", port_num);
4102 else
4103 printf(" port_map: %s", argv[3]);
4104 } else {
4105 printf(" all ports");
4106 }
4107 printf("\n");
4108
4109 return;
4110error:
4111 printf(HELP_EEE_EN);
4112 return;
4113}
4114
4115void eee_dump(int argc, char *argv[])
4116{
developerbe40a9e2024-03-07 21:44:26 +08004117 unsigned int cap = 0, lp_cap = 0;
developerfd40db22021-04-29 10:08:25 +08004118 long port = -1;
developerbe40a9e2024-03-07 21:44:26 +08004119 int p = 0;
developerfd40db22021-04-29 10:08:25 +08004120
4121 if (argc > 3) {
4122 if (strlen(argv[3]) > 1) {
4123 printf("port# format error, should be of length 1\n");
4124 return;
4125 }
4126
4127 port = strtol(argv[3], (char **)NULL, 0);
4128 if (port < 0 || port > MAX_PHY_PORT) {
4129 printf("port# format error, should be 0 to %d\n",
developerbe40a9e2024-03-07 21:44:26 +08004130 MAX_PHY_PORT);
developerfd40db22021-04-29 10:08:25 +08004131 return;
4132 }
4133 }
4134
4135 for (p = 0; p < MAX_PHY_PORT; p++) {
4136 if (port >= 0 && p != port)
4137 continue;
4138
4139 mii_mgr_c45_read(p, 0x7, 0x3c, &cap);
4140 mii_mgr_c45_read(p, 0x7, 0x3d, &lp_cap);
4141 printf("port%d EEE cap=0x%02x, link partner EEE cap=0x%02x",
4142 p, cap, lp_cap);
4143
4144 if (port >= 0 && p == port) {
4145 mii_mgr_c45_read(p, 0x3, 0x1, &cap);
4146 printf(", st=0x%03x", cap);
4147 }
4148 printf("\n");
4149 }
4150}
4151
4152void dump_each_port(unsigned int base)
4153{
4154 unsigned int pkt_cnt = 0;
4155 int i = 0;
4156
4157 for (i = 0; i < 7; i++) {
developer0dea3402022-10-14 13:41:11 +08004158 if (chip_name == 0x7988) {
4159 if ((base == 0x402C) && (i == 6))
4160 base = 0x408C;
4161 else if ((base == 0x408C) && (i == 6))
4162 base = 0x402C;
4163 else
4164 ;
4165 }
developerfd40db22021-04-29 10:08:25 +08004166 reg_read((base) + (i * 0x100), &pkt_cnt);
4167 printf("%8u ", pkt_cnt);
4168 }
4169 printf("\n");
4170}
4171
developerbe40a9e2024-03-07 21:44:26 +08004172void read_mib_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08004173{
4174 printf("===================== %8s %8s %8s %8s %8s %8s %8s\n",
4175 "Port0", "Port1", "Port2", "Port3", "Port4", "Port5", "Port6");
4176 printf("Tx Drop Packet :");
4177 dump_each_port(0x4000);
4178 printf("Tx CRC Error :");
4179 dump_each_port(0x4004);
4180 printf("Tx Unicast Packet :");
4181 dump_each_port(0x4008);
4182 printf("Tx Multicast Packet :");
4183 dump_each_port(0x400C);
4184 printf("Tx Broadcast Packet :");
4185 dump_each_port(0x4010);
4186 printf("Tx Collision Event :");
4187 dump_each_port(0x4014);
4188 printf("Tx Pause Packet :");
4189 dump_each_port(0x402C);
4190 printf("Rx Drop Packet :");
4191 dump_each_port(0x4060);
4192 printf("Rx Filtering Packet :");
4193 dump_each_port(0x4064);
4194 printf("Rx Unicast Packet :");
4195 dump_each_port(0x4068);
4196 printf("Rx Multicast Packet :");
4197 dump_each_port(0x406C);
4198 printf("Rx Broadcast Packet :");
4199 dump_each_port(0x4070);
4200 printf("Rx Alignment Error :");
4201 dump_each_port(0x4074);
4202 printf("Rx CRC Error :");
4203 dump_each_port(0x4078);
4204 printf("Rx Undersize Error :");
4205 dump_each_port(0x407C);
4206 printf("Rx Fragment Error :");
4207 dump_each_port(0x4080);
4208 printf("Rx Oversize Error :");
4209 dump_each_port(0x4084);
4210 printf("Rx Jabber Error :");
4211 dump_each_port(0x4088);
4212 printf("Rx Pause Packet :");
4213 dump_each_port(0x408C);
4214}
4215
developerbe40a9e2024-03-07 21:44:26 +08004216void clear_mib_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08004217{
4218 reg_write(0x4fe0, 0xf0);
developerbe40a9e2024-03-07 21:44:26 +08004219 read_mib_counters(argc, argv);
developerfd40db22021-04-29 10:08:25 +08004220 reg_write(0x4fe0, 0x800000f0);
4221}
4222
developerfd40db22021-04-29 10:08:25 +08004223void exit_free()
4224{
4225 free(attres);
4226 attres = NULL;
4227 switch_ioctl_fini();
4228 mt753x_netlink_free();
4229}