blob: e439ee8534c7ce280191b3c028a3178c092c8d00 [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 */
137static void ip_to_str(char *str, unsigned int ip)
138{
139 unsigned char *ptr = (unsigned char *)&ip;
140 unsigned char c[4];
141
142 c[0] = *(ptr);
143 c[1] = *(ptr + 1);
144 c[2] = *(ptr + 2);
145 c[3] = *(ptr + 3);
developerbe40a9e2024-03-07 21:44:26 +0800146 /*sprintf(str, "%d.%d.%d.%d", c[0], c[1], c[2], c[3]); */
developerfd40db22021-04-29 10:08:25 +0800147 sprintf(str, "%d.%d.%d.%d", c[3], c[2], c[1], c[0]);
148}
149
150int reg_read(unsigned int offset, unsigned int *value)
151{
152 int ret = -1;
153
154 if (nl_init_flag == true) {
155 ret = reg_read_netlink(attres, offset, value);
156 } else {
157 if (attres->dev_id == -1)
158 ret = reg_read_ioctl(offset, value);
159 }
160 if (ret < 0) {
161 printf("Read fail\n");
162 *value = 0;
163 return ret;
164 }
165
166 return 0;
167}
168
169int reg_write(unsigned int offset, unsigned int value)
170{
171 int ret = -1;
172
173 if (nl_init_flag == true) {
174 ret = reg_write_netlink(attres, offset, value);
175 } else {
176 if (attres->dev_id == -1)
177 ret = reg_write_ioctl(offset, value);
178 }
179 if (ret < 0) {
180 printf("Write fail\n");
181 exit_free();
182 exit(0);
183 }
184 return 0;
185}
186
187int mii_mgr_read(unsigned int port_num, unsigned int reg, unsigned int *value)
188{
189 int ret;
190
191 if (port_num > 31) {
192 printf("Invalid Port or PHY addr \n");
193 return -1;
194 }
195
196 if (nl_init_flag == true)
197 ret = phy_cl22_read_netlink(attres, port_num, reg, value);
198 else
199 ret = mii_mgr_cl22_read_ioctl(port_num, reg, value);
200
201 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800202 printf("Phy cl22 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800203 exit_free();
204 exit(0);
205 }
206
207 return 0;
208}
209
210int mii_mgr_write(unsigned int port_num, unsigned int reg, unsigned int value)
211{
212 int ret;
213
214 if (port_num > 31) {
215 printf("Invalid Port or PHY addr \n");
216 return -1;
217 }
218
219 if (nl_init_flag == true)
220 ret = phy_cl22_write_netlink(attres, port_num, reg, value);
221 else
222 ret = mii_mgr_cl22_write_ioctl(port_num, reg, value);
223
224 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800225 printf("Phy cl22 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800226 exit_free();
227 exit(0);
228 }
229
230 return 0;
231}
232
developerbe40a9e2024-03-07 21:44:26 +0800233int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg,
234 unsigned int *value)
developerfd40db22021-04-29 10:08:25 +0800235{
236 int ret;
237
238 if (port_num > 31) {
239 printf("Invalid Port or PHY addr \n");
240 return -1;
241 }
242
243 if (nl_init_flag == true)
244 ret = phy_cl45_read_netlink(attres, port_num, dev, reg, value);
245 else
246 ret = mii_mgr_cl45_read_ioctl(port_num, dev, reg, value);
247
248 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800249 printf("Phy cl45 read fail\n");
developerfd40db22021-04-29 10:08:25 +0800250 exit_free();
251 exit(0);
252 }
253
254 return 0;
255}
256
developerbe40a9e2024-03-07 21:44:26 +0800257int mii_mgr_c45_write(unsigned int port_num, unsigned int dev, unsigned int reg,
258 unsigned int value)
developerfd40db22021-04-29 10:08:25 +0800259{
260 int ret;
261
262 if (port_num > 31) {
263 printf("Invalid Port or PHY addr \n");
264 return -1;
265 }
266
267 if (nl_init_flag == true)
268 ret = phy_cl45_write_netlink(attres, port_num, dev, reg, value);
269 else
270 ret = mii_mgr_cl45_write_ioctl(port_num, dev, reg, value);
271
272 if (ret < 0) {
developer06979e42021-05-28 16:48:10 +0800273 printf("Phy cl45 write fail\n");
developerfd40db22021-04-29 10:08:25 +0800274 exit_free();
275 exit(0);
276 }
277
278 return 0;
279}
280
developerfd40db22021-04-29 10:08:25 +0800281int phy_dump(int phy_addr)
282{
283 int ret;
284
285 if (nl_init_flag == true)
286 ret = phy_dump_netlink(attres, phy_addr);
287 else
288 ret = phy_dump_ioctl(phy_addr);
289
290 if (ret < 0) {
291 printf("Phy dump fail\n");
292 exit_free();
293 exit(0);
294 }
295
296 return 0;
297}
298
299void phy_crossover(int argc, char *argv[])
300{
301 unsigned int port_num = strtoul(argv[2], NULL, 10);
developerbe40a9e2024-03-07 21:44:26 +0800302 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +0800303 int ret;
304
305 if (port_num > 4) {
306 printf("invaild value, port_name:0~4\n");
307 return;
308 }
309
310 if (nl_init_flag == true)
developerbe40a9e2024-03-07 21:44:26 +0800311 ret =
312 phy_cl45_read_netlink(attres, port_num, 0x1E,
313 MT7530_T10_TEST_CONTROL, &value);
developerfd40db22021-04-29 10:08:25 +0800314 else
developerbe40a9e2024-03-07 21:44:26 +0800315 ret =
316 mii_mgr_cl45_read_ioctl(port_num, 0x1E,
317 MT7530_T10_TEST_CONTROL, &value);
developerfd40db22021-04-29 10:08:25 +0800318 if (ret < 0) {
319 printf("phy_cl45 read fail\n");
320 exit_free();
321 exit(0);
322 }
323
324 printf("mii_mgr_cl45:");
developerbe40a9e2024-03-07 21:44:26 +0800325 printf("Read: port#=%d, device=0x%x, reg=0x%x, value=0x%x\n", port_num,
326 0x1E, MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800327
developerbe40a9e2024-03-07 21:44:26 +0800328 if (!strncmp(argv[3], "auto", 5)) {
developerfd40db22021-04-29 10:08:25 +0800329 value &= (~(0x3 << 3));
330 } else if (!strncmp(argv[3], "mdi", 4)) {
331 value &= (~(0x3 << 3));
332 value |= (0x2 << 3);
333 } else if (!strncmp(argv[3], "mdix", 5)) {
334 value |= (0x3 << 3);
335 } else {
336 printf("invaild parameter\n");
337 return;
338 }
developerbe40a9e2024-03-07 21:44:26 +0800339 printf("Write: port#=%d, device=0x%x, reg=0x%x. value=0x%x\n", port_num,
340 0x1E, MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800341
342 if (nl_init_flag == true)
developerbe40a9e2024-03-07 21:44:26 +0800343 ret =
344 phy_cl45_write_netlink(attres, port_num, 0x1E,
345 MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800346 else
developerbe40a9e2024-03-07 21:44:26 +0800347 ret =
348 mii_mgr_cl45_write_ioctl(port_num, 0x1E,
349 MT7530_T10_TEST_CONTROL, value);
developerfd40db22021-04-29 10:08:25 +0800350
351 if (ret < 0) {
352 printf("phy_cl45 write fail\n");
353 exit_free();
354 exit(0);
355 }
356}
357
358int rw_phy_token_ring(int argc, char *argv[])
359{
360 int ch_addr, node_addr, data_addr;
361 unsigned int tr_reg_control;
362 unsigned int val_l = 0;
363 unsigned int val_h = 0;
364 unsigned int port_num;
365
366 if (argc < 4)
367 return -1;
368
369 if (argv[2][0] == 'r') {
370 if (argc != 7)
371 return -1;
developerbe40a9e2024-03-07 21:44:26 +0800372 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
developerfd40db22021-04-29 10:08:25 +0800373 port_num = strtoul(argv[3], NULL, 0);
374 if (port_num > MAX_PORT) {
375 printf("Illegal port index and port:0~6\n");
376 return -1;
377 }
378 ch_addr = strtoul(argv[4], NULL, 0);
379 node_addr = strtoul(argv[5], NULL, 0);
380 data_addr = strtoul(argv[6], NULL, 0);
developerbe40a9e2024-03-07 21:44:26 +0800381 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n",
382 port_num, ch_addr, node_addr, data_addr);
383 tr_reg_control =
384 (1 << 15) | (1 << 13) | (ch_addr << 11) | (node_addr << 7) |
385 (data_addr << 1);
386 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
developerfd40db22021-04-29 10:08:25 +0800387 mii_mgr_read(port_num, 17, &val_l);
388 mii_mgr_read(port_num, 18, &val_h);
developerbe40a9e2024-03-07 21:44:26 +0800389 printf
390 ("switch trreg read tr_reg_control=%x, value_H=%x, value_L=%x\n",
391 tr_reg_control, val_h, val_l);
developerfd40db22021-04-29 10:08:25 +0800392 } else if (argv[2][0] == 'w') {
393 if (argc != 9)
394 return -1;
developerbe40a9e2024-03-07 21:44:26 +0800395 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
developerfd40db22021-04-29 10:08:25 +0800396 port_num = strtoul(argv[3], NULL, 0);
397 if (port_num > MAX_PORT) {
398 printf("\n**Illegal port index and port:0~6\n");
399 return -1;
400 }
401 ch_addr = strtoul(argv[4], NULL, 0);
402 node_addr = strtoul(argv[5], NULL, 0);
403 data_addr = strtoul(argv[6], NULL, 0);
404 val_h = strtoul(argv[7], NULL, 0);
405 val_l = strtoul(argv[8], NULL, 0);
developerbe40a9e2024-03-07 21:44:26 +0800406 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n",
407 port_num, ch_addr, node_addr, data_addr);
408 tr_reg_control =
409 (1 << 15) | (0 << 13) | (ch_addr << 11) | (node_addr << 7) |
410 (data_addr << 1);
developerfd40db22021-04-29 10:08:25 +0800411 mii_mgr_write(port_num, 17, val_l);
412 mii_mgr_write(port_num, 18, val_h);
developerbe40a9e2024-03-07 21:44:26 +0800413 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
414 printf
415 ("switch trreg Write tr_reg_control=%x, value_H=%x, value_L=%x\n",
416 tr_reg_control, val_h, val_l);
developerfd40db22021-04-29 10:08:25 +0800417 } else
418 return -1;
419 return 0;
420}
421
developerbe40a9e2024-03-07 21:44:26 +0800422void write_acl_table(unsigned char tbl_idx, unsigned int vawd1,
423 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800424{
developerbe40a9e2024-03-07 21:44:26 +0800425 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800426 unsigned int max_index;
427
developer8c3871b2022-07-01 14:07:53 +0800428 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800429 max_index = 256;
430 else
431 max_index = 64;
432
433 printf("Pattern_acl_tbl_idx:%d\n", tbl_idx);
434
435 if (tbl_idx >= max_index) {
436 printf(HELP_ACL_ACL_TBL_ADD);
437 return;
438 }
439
440 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800441 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800442 reg_read(reg, &value);
443 if ((value & REG_VTCR_BUSY_MASK) == 0) {
444 break;
445 }
446 }
447 reg_write(REG_VAWD1_ADDR, vawd1);
448 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
449 reg_write(REG_VAWD2_ADDR, vawd2);
450 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
451 reg = REG_VTCR_ADDR;
452 value = REG_VTCR_BUSY_MASK | (0x05 << REG_VTCR_FUNC_OFFT) | tbl_idx;
453 reg_write(reg, value);
454 printf("write reg: %x, value: %x\n", reg, value);
455
developerbe40a9e2024-03-07 21:44:26 +0800456 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800457 reg_read(reg, &value);
458 if ((value & REG_VTCR_BUSY_MASK) == 0)
459 break;
460 }
461}
462
463void acl_table_add(int argc, char *argv[])
464{
developerbe40a9e2024-03-07 21:44:26 +0800465 unsigned int vawd1 = 0, vawd2 = 0;
466 unsigned char tbl_idx = 0;
developerfd40db22021-04-29 10:08:25 +0800467
468 tbl_idx = atoi(argv[3]);
469 vawd1 = strtoul(argv[4], (char **)NULL, 16);
470 vawd2 = strtoul(argv[5], (char **)NULL, 16);
471 write_acl_table(tbl_idx, vawd1, vawd2);
472}
473
developerbe40a9e2024-03-07 21:44:26 +0800474void write_acl_mask_table(unsigned char tbl_idx, unsigned int vawd1,
475 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800476{
developerbe40a9e2024-03-07 21:44:26 +0800477 unsigned int value = 0, reg = 0;
478 unsigned int max_index = 0;
developerfd40db22021-04-29 10:08:25 +0800479
developer8c3871b2022-07-01 14:07:53 +0800480 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800481 max_index = 128;
482 else
483 max_index = 32;
484
485 printf("Rule_mask_tbl_idx:%d\n", tbl_idx);
486
487 if (tbl_idx >= max_index) {
488 printf(HELP_ACL_MASK_TBL_ADD);
489 return;
490 }
491 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800492 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800493 reg_read(reg, &value);
494 if ((value & REG_VTCR_BUSY_MASK) == 0)
495 break;
496 }
497 reg_write(REG_VAWD1_ADDR, vawd1);
498 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
499 reg_write(REG_VAWD2_ADDR, vawd2);
500 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
501 reg = REG_VTCR_ADDR;
502 value = REG_VTCR_BUSY_MASK | (0x09 << REG_VTCR_FUNC_OFFT) | tbl_idx;
503 reg_write(reg, value);
504 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +0800505 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800506 reg_read(reg, &value);
507 if ((value & REG_VTCR_BUSY_MASK) == 0)
508 break;
509 }
510}
511
512void acl_mask_table_add(int argc, char *argv[])
513{
developerbe40a9e2024-03-07 21:44:26 +0800514 unsigned int vawd1 = 0, vawd2 = 0;
515 unsigned char tbl_idx = 0;
developerfd40db22021-04-29 10:08:25 +0800516
517 tbl_idx = atoi(argv[3]);
518 vawd1 = strtoul(argv[4], (char **)NULL, 16);
519 vawd2 = strtoul(argv[5], (char **)NULL, 16);
520 write_acl_mask_table(tbl_idx, vawd1, vawd2);
521}
522
developerbe40a9e2024-03-07 21:44:26 +0800523void write_acl_rule_table(unsigned char tbl_idx, unsigned int vawd1,
524 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800525{
developerbe40a9e2024-03-07 21:44:26 +0800526 unsigned int value = 0, reg = 0;
527 unsigned int max_index = 0;
developerfd40db22021-04-29 10:08:25 +0800528
developer8c3871b2022-07-01 14:07:53 +0800529 if (chip_name == 0x7531 || chip_name == 0x7988)
developerfd40db22021-04-29 10:08:25 +0800530 max_index = 128;
531 else
532 max_index = 32;
533
534 printf("Rule_control_tbl_idx:%d\n", tbl_idx);
535
developerbe40a9e2024-03-07 21:44:26 +0800536 if (tbl_idx >= max_index) { /* Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +0800537 printf(HELP_ACL_RULE_TBL_ADD);
538 return;
539 }
540 reg = REG_VTCR_ADDR;
541
developerbe40a9e2024-03-07 21:44:26 +0800542 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800543 reg_read(reg, &value);
544 if ((value & REG_VTCR_BUSY_MASK) == 0) {
545 break;
546 }
547 }
548 reg_write(REG_VAWD1_ADDR, vawd1);
549 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
550 reg_write(REG_VAWD2_ADDR, vawd2);
551 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
552 reg = REG_VTCR_ADDR;
553 value = REG_VTCR_BUSY_MASK | (0x0B << REG_VTCR_FUNC_OFFT) | tbl_idx;
554 reg_write(reg, value);
555 printf("write reg: %x, value: %x\n", reg, value);
556
developerbe40a9e2024-03-07 21:44:26 +0800557 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800558 reg_read(reg, &value);
559 if ((value & REG_VTCR_BUSY_MASK) == 0) {
560 break;
561 }
562 }
563}
564
565void acl_rule_table_add(int argc, char *argv[])
566{
developerbe40a9e2024-03-07 21:44:26 +0800567 unsigned int vawd1 = 0, vawd2 = 0;
568 unsigned char tbl_idx = 0;
developerfd40db22021-04-29 10:08:25 +0800569
570 tbl_idx = atoi(argv[3]);
571 vawd1 = strtoul(argv[4], (char **)NULL, 16);
572 vawd2 = strtoul(argv[5], (char **)NULL, 16);
573 write_acl_rule_table(tbl_idx, vawd1, vawd2);
574}
575
developerbe40a9e2024-03-07 21:44:26 +0800576void write_rate_table(unsigned char tbl_idx, unsigned int vawd1,
577 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800578{
developerbe40a9e2024-03-07 21:44:26 +0800579 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800580 unsigned int max_index = 32;
581
582 printf("Rule_action_tbl_idx:%d\n", tbl_idx);
583
584 if (tbl_idx >= max_index) {
585 printf(HELP_ACL_RATE_TBL_ADD);
586 return;
587 }
588
589 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800590 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800591 reg_read(reg, &value);
592 if ((value & REG_VTCR_BUSY_MASK) == 0)
593 break;
594 }
595
596 reg_write(REG_VAWD1_ADDR, vawd1);
597 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
598 reg_write(REG_VAWD2_ADDR, vawd2);
599 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
600 reg = REG_VTCR_ADDR;
601 value = REG_VTCR_BUSY_MASK | (0x0D << REG_VTCR_FUNC_OFFT) | tbl_idx;
602 reg_write(reg, value);
603 printf("write reg: %x, value: %x\n", reg, value);
604
developerbe40a9e2024-03-07 21:44:26 +0800605 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800606 reg_read(reg, &value);
607 if ((value & REG_VTCR_BUSY_MASK) == 0)
608 break;
609 }
610}
611
612void acl_rate_table_add(int argc, char *argv[])
613{
developerbe40a9e2024-03-07 21:44:26 +0800614 unsigned int vawd1 = 0, vawd2 = 0;
615 unsigned char tbl_idx = 0;
developerfd40db22021-04-29 10:08:25 +0800616
617 tbl_idx = atoi(argv[3]);
618 vawd1 = strtoul(argv[4], (char **)NULL, 16);
619 vawd2 = strtoul(argv[5], (char **)NULL, 16);
620
621 write_rate_table(tbl_idx, vawd1, vawd2);
622}
623
developerbe40a9e2024-03-07 21:44:26 +0800624void write_trTCM_table(unsigned char tbl_idx, unsigned int vawd1,
625 unsigned int vawd2)
developerfd40db22021-04-29 10:08:25 +0800626{
developerbe40a9e2024-03-07 21:44:26 +0800627 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +0800628 unsigned int max_index = 32;
629
630 printf("trTCM_tbl_idx:%d\n", tbl_idx);
631
632 if (tbl_idx >= max_index) {
633 printf(HELP_ACL_TRTCM_TBL_ADD);
634 return;
635 }
636
637 reg = REG_VTCR_ADDR;
developerbe40a9e2024-03-07 21:44:26 +0800638 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800639 reg_read(reg, &value);
640 if ((value & REG_VTCR_BUSY_MASK) == 0)
641 break;
642 }
643
644 reg_write(REG_VAWD1_ADDR, vawd1);
645 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
646 reg_write(REG_VAWD2_ADDR, vawd2);
647 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
648 reg = REG_VTCR_ADDR;
649 value = REG_VTCR_BUSY_MASK | (0x07 << REG_VTCR_FUNC_OFFT) | tbl_idx;
650 reg_write(reg, value);
651 printf("write reg: %x, value: %x\n", reg, value);
652
developerbe40a9e2024-03-07 21:44:26 +0800653 while (1) { // wait until not busy
developerfd40db22021-04-29 10:08:25 +0800654 reg_read(reg, &value);
655 if ((value & REG_VTCR_BUSY_MASK) == 0)
656 break;
657 }
658}
659
developerbe40a9e2024-03-07 21:44:26 +0800660int acl_parameters_pre_del(int len1, int len2, int argc, char *argv[],
661 int *port)
developerfd40db22021-04-29 10:08:25 +0800662{
developerbe40a9e2024-03-07 21:44:26 +0800663 int i = 0;
developerfd40db22021-04-29 10:08:25 +0800664
665 *port = 0;
666 if (argc < len1) {
667 printf("insufficient arguments!\n");
668 return -1;
669 }
670
developerbe40a9e2024-03-07 21:44:26 +0800671 if (len2 == 12) {
developerfd40db22021-04-29 10:08:25 +0800672 if (!argv[4] || strlen(argv[4]) != len2) {
developerbe40a9e2024-03-07 21:44:26 +0800673 printf
674 ("The [%s] format error, should be of length %d\n",
675 argv[4], len2);
developerfd40db22021-04-29 10:08:25 +0800676 return -1;
677 }
678 }
679
680 if (!argv[5] || strlen(argv[5]) != 8) {
681 printf("portsmap format error, should be of length 7\n");
682 return -1;
683 }
684
685 for (i = 0; i < 7; i++) {
686 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +0800687 printf
688 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +0800689 return -1;
690 }
691 *port += (argv[5][i] - '0') * (1 << i);
692 }
693 return 0;
694}
695
developerbe40a9e2024-03-07 21:44:26 +0800696void acl_compare_pattern(int ports, int comparion, int base, int word,
697 unsigned char table_index)
developerfd40db22021-04-29 10:08:25 +0800698{
developerbe40a9e2024-03-07 21:44:26 +0800699 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +0800700
developerbe40a9e2024-03-07 21:44:26 +0800701 comparion |= 0xffff0000; //compare mask
developerfd40db22021-04-29 10:08:25 +0800702
developerbe40a9e2024-03-07 21:44:26 +0800703 value = ports << 8; //w_port_map
704 value |= 0x1 << 19; //enable
705 value |= base << 16; //mac header
706 value |= word << 1; //word offset
developerfd40db22021-04-29 10:08:25 +0800707
708 write_acl_table(table_index, comparion, value);
709}
710
711void acl_mac_add(int argc, char *argv[])
712{
developerbe40a9e2024-03-07 21:44:26 +0800713 unsigned int value = 0;
714 int ports = 0;
developerfd40db22021-04-29 10:08:25 +0800715 char tmpstr[5];
716 int ret;
717
718 ret = acl_parameters_pre_del(6, 12, argc, argv, &ports);
719 if (ret < 0)
720 return;
developerbe40a9e2024-03-07 21:44:26 +0800721 /* Set pattern */
developerfd40db22021-04-29 10:08:25 +0800722 strncpy(tmpstr, argv[4], 4);
723 tmpstr[4] = '\0';
724 value = strtoul(tmpstr, NULL, 16);
725 acl_compare_pattern(ports, value, 0x0, 0, 0);
726
727 strncpy(tmpstr, argv[4] + 4, 4);
728 tmpstr[4] = '\0';
729 value = strtoul(tmpstr, NULL, 16);
730 acl_compare_pattern(ports, value, 0x0, 1, 1);
731
732 strncpy(tmpstr, argv[4] + 8, 4);
733 tmpstr[4] = '\0';
734 value = strtoul(tmpstr, NULL, 16);
735 acl_compare_pattern(ports, value, 0x0, 2, 2);
736
737 //set mask
developerbe40a9e2024-03-07 21:44:26 +0800738 write_acl_mask_table(0, 0x7, 0);
developerfd40db22021-04-29 10:08:25 +0800739
740 //set action
developerbe40a9e2024-03-07 21:44:26 +0800741 value = 0x7; //drop
742 value |= 1 << 28; //acl intterupt enable
743 value |= 1 << 27; //acl hit count
744 value |= 2 << 24; //acl hit count group index (0~3)
745 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +0800746}
747
748void acl_dip_meter(int argc, char *argv[])
749{
developerbe40a9e2024-03-07 21:44:26 +0800750 unsigned int value = 0, ip_value = 0, meter = 0;
751 int ports = 0;
developerfd40db22021-04-29 10:08:25 +0800752 int ret;
753
754 ip_value = 0;
755 ret = acl_parameters_pre_del(7, -1, argc, argv, &ports);
756 if (ret < 0)
757 return;
758
759 str_to_ip(&ip_value, argv[4]);
760 //set pattern
761 value = (ip_value >> 16);
762 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
763
764 //set pattern
765 value = (ip_value & 0xffff);
766 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
767
768 //set mask
developerbe40a9e2024-03-07 21:44:26 +0800769 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800770
771 //set action
772 meter = strtoul(argv[6], NULL, 0);
773 if (((chip_name == 0x7530) && (meter > 1000000)) ||
developerbe40a9e2024-03-07 21:44:26 +0800774 ((chip_name == 0x7531) && (meter > 2500000)) ||
775 ((chip_name == 0x7988) && (meter > 4000000))) {
developer8c3871b2022-07-01 14:07:53 +0800776 printf("\n**Illegal meter input, and 7530: 0~1000000Kpbs, 7531: 0~2500000Kpbs, 7988: 0~4000000Kpbs**\n");
developerfd40db22021-04-29 10:08:25 +0800777 return;
778 }
developer8c3871b2022-07-01 14:07:53 +0800779 if (((chip_name == 0x7531 || chip_name == 0x7988) && (meter > 1000000))) {
developerbe40a9e2024-03-07 21:44:26 +0800780 reg_read(0xc, &value);
developerfd40db22021-04-29 10:08:25 +0800781 value |= 0x1 << 30;
developerbe40a9e2024-03-07 21:44:26 +0800782 reg_write(0xC, value);
783 printf("AGC: 0x%x\n", value);
784 value = meter / 1000; //uint is 1Mbps
developerfd40db22021-04-29 10:08:25 +0800785 } else {
developerbe40a9e2024-03-07 21:44:26 +0800786 reg_read(0xc, &value);
developerfd40db22021-04-29 10:08:25 +0800787 value &= ~(0x1 << 30);
developerbe40a9e2024-03-07 21:44:26 +0800788 reg_write(0xC, value);
789 printf("AGC: 0x%x\n", value);
790 value = meter >> 6; //uint is 64Kbps
developerfd40db22021-04-29 10:08:25 +0800791 }
developerbe40a9e2024-03-07 21:44:26 +0800792 value |= 0x1 << 15; //enable rate control
793 printf("Acl rate control:0x%x\n", value);
developerfd40db22021-04-29 10:08:25 +0800794 write_rate_table(0, value, 0);
795}
796
797void acl_dip_trtcm(int argc, char *argv[])
798{
799 unsigned int value, value2, ip_value;
800 unsigned int CIR, CBS, PIR, PBS;
801 int ports;
802 int ret;
803
804 ip_value = 0;
805 ret = acl_parameters_pre_del(10, -1, argc, argv, &ports);
806 if (ret < 0)
807 return;
808
809 str_to_ip(&ip_value, argv[4]);
810 //set pattern
811 value = (ip_value >> 16);
812 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
813
814 //set pattern
815 value = (ip_value & 0xffff);
816 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
817
818 //set CBS PBS
819 CIR = strtoul(argv[6], NULL, 0);
820 CBS = strtoul(argv[7], NULL, 0);
821 PIR = strtoul(argv[8], NULL, 0);
822 PBS = strtoul(argv[9], NULL, 0);
823
developerbe40a9e2024-03-07 21:44:26 +0800824 if (CIR > 65535 * 64 || CBS > 65535 || PIR > 65535 * 64 || PBS > 65535) {
developerfd40db22021-04-29 10:08:25 +0800825 printf("\n**Illegal input parameters**\n");
826 return;
827 }
828
developerbe40a9e2024-03-07 21:44:26 +0800829 value = CBS << 16; //bit16~31
830 value |= PBS; //bit0~15
831 //value |= 1;//valid
developerfd40db22021-04-29 10:08:25 +0800832 CIR = CIR >> 6;
833 PIR = PIR >> 6;
834
developerbe40a9e2024-03-07 21:44:26 +0800835 value2 = CIR << 16; //bit16~31
836 value2 |= PIR; //bit0~15
837 write_trTCM_table(0, value, value2);
developerfd40db22021-04-29 10:08:25 +0800838
839 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800840 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800841
842 //set action
developerbe40a9e2024-03-07 21:44:26 +0800843 value = 0x1 << (11 + 1); //TrTCM green meter#0 Low drop
844 value |= 0x2 << (8 + 1); //TrTCM yellow meter#0 Med drop
845 value |= 0x3 << (5 + 1); //TrTCM red meter#0 Hig drop
846 value |= 0x1 << 0; //TrTCM drop pcd select
847 write_acl_rule_table(0, 0, value);
developerfd40db22021-04-29 10:08:25 +0800848}
849
850void acl_ethertype(int argc, char *argv[])
851{
852 unsigned int value, ethertype;
853 int ports;
854 int ret;
855
856 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
857 if (ret < 0)
858 return;
developerbe40a9e2024-03-07 21:44:26 +0800859 printf("ports:0x%x\n", ports);
developerfd40db22021-04-29 10:08:25 +0800860 ethertype = strtoul(argv[4], NULL, 16);
861 //set pattern
862 value = ethertype;
863 acl_compare_pattern(ports, value, 0x0, 0x6, 0);
864
865 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800866 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +0800867
868 //set action(drop)
developerbe40a9e2024-03-07 21:44:26 +0800869 value = 0x7; //default. Nodrop
870 value |= 1 << 28; //acl intterupt enable
871 value |= 1 << 27; //acl hit count
developerfd40db22021-04-29 10:08:25 +0800872
developerbe40a9e2024-03-07 21:44:26 +0800873 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +0800874}
875
876void acl_dip_modify(int argc, char *argv[])
877{
878 unsigned int value, ip_value;
879 int ports;
880 int priority;
881 int ret;
882
883 ip_value = 0;
884 priority = strtoul(argv[6], NULL, 16);
885 if (priority < 0 || priority > 7) {
886 printf("\n**Illegal priority value!**\n");
887 return;
888 }
889
890 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
891 if (ret < 0)
892 return;
893
894 str_to_ip(&ip_value, argv[4]);
895 //set pattern
896 value = (ip_value >> 16);
897 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
898
899 //set pattern
900 value = (ip_value & 0xffff);
901 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
902
903 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800904 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800905
906 //set action
developerbe40a9e2024-03-07 21:44:26 +0800907 value = 0x0; //default. Nodrop
908 value |= 1 << 28; //acl intterupt enable
909 value |= 1 << 27; //acl hit count
910 value |= priority << 4; //acl UP
911 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +0800912}
913
914void acl_dip_pppoe(int argc, char *argv[])
915{
916 unsigned int value, ip_value;
917 int ports;
918 int ret;
919
920 ip_value = 0;
921 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
922 if (ret < 0)
923 return;
924
925 str_to_ip(&ip_value, argv[4]);
926 //set pattern
927 value = (ip_value >> 16);
928 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
929
930 //set pattern
931 value = (ip_value & 0xffff);
932 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
933
934 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800935 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800936
937 //set action
developerbe40a9e2024-03-07 21:44:26 +0800938 value = 0x0; //default. Nodrop
939 value |= 1 << 28; //acl intterupt enable
940 value |= 1 << 27; //acl hit count
941 value |= 1 << 20; //pppoe header remove
942 value |= 1 << 21; //SA MAC SWAP
943 value |= 1 << 22; //DA MAC SWAP
944 write_acl_rule_table(0, value, 7);
developerfd40db22021-04-29 10:08:25 +0800945}
946
947void acl_dip_add(int argc, char *argv[])
948{
949 unsigned int value, ip_value;
950 int ports;
951 int ret;
952
953 ip_value = 0;
954 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
955 if (ret < 0)
956 return;
957
958 str_to_ip(&ip_value, argv[4]);
959 //set pattern
960 value = (ip_value >> 16);
961 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
962
963 //set pattern
964 value = (ip_value & 0xffff);
965 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
966
967 //set pattern
developerbe40a9e2024-03-07 21:44:26 +0800968 write_acl_mask_table(0, 0x3, 0);
developerfd40db22021-04-29 10:08:25 +0800969
970 //set action
971 //value = 0x0; //default
developerbe40a9e2024-03-07 21:44:26 +0800972 value = 0x7; //drop
973 value |= 1 << 28; //acl intterupt enable
974 value |= 1 << 27; //acl hit count
975 value |= 2 << 24; //acl hit count group index (0~3)
976 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +0800977}
978
979void acl_l4_add(int argc, char *argv[])
980{
developerbe40a9e2024-03-07 21:44:26 +0800981 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +0800982 int ports;
983 int ret;
984
985 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
986 if (ret < 0)
987 return;
988
989 //set pattern
990 value = strtoul(argv[4], NULL, 16);
991 acl_compare_pattern(ports, value, 0x5, 0x0, 0);
992
993 //set rue mask
developerbe40a9e2024-03-07 21:44:26 +0800994 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +0800995 //set action
developerbe40a9e2024-03-07 21:44:26 +0800996 value = 0x7; //drop
997 //value |= 1;//valid
998 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +0800999}
1000
1001void acl_sp_add(int argc, char *argv[])
1002{
developerbe40a9e2024-03-07 21:44:26 +08001003 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001004 int ports;
1005 int ret;
1006
1007 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1008 if (ret < 0)
1009 return;
1010 //set pattern
1011 value = strtoul(argv[4], NULL, 0);
1012 acl_compare_pattern(ports, value, 0x4, 0x0, 0);
1013
1014 //set rue mask
developerbe40a9e2024-03-07 21:44:26 +08001015 write_acl_mask_table(0, 0x1, 0);
developerfd40db22021-04-29 10:08:25 +08001016
1017 //set action
developerbe40a9e2024-03-07 21:44:26 +08001018 value = 0x7; //drop
1019 //value |= 1;//valid
1020 write_acl_rule_table(0, value, 0);
developerfd40db22021-04-29 10:08:25 +08001021}
1022
1023void acl_port_enable(int argc, char *argv[])
1024{
developerbe40a9e2024-03-07 21:44:26 +08001025 unsigned int value = 0, reg = 0;
1026 unsigned char acl_port = 0, acl_en = 0;
developerfd40db22021-04-29 10:08:25 +08001027
1028 acl_port = atoi(argv[3]);
1029 acl_en = atoi(argv[4]);
1030
1031 printf("acl_port:%d, acl_en:%d\n", acl_port, acl_en);
1032
developerbe40a9e2024-03-07 21:44:26 +08001033 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08001034 if ((acl_port > SWITCH_MAX_PORT) || (acl_en > 1)) {
1035 printf(HELP_ACL_SETPORTEN);
1036 return;
1037 }
1038
developerbe40a9e2024-03-07 21:44:26 +08001039 reg = REG_PCR_P0_ADDR + (0x100 * acl_port); // 0x2004[10]
developerfd40db22021-04-29 10:08:25 +08001040 reg_read(reg, &value);
1041 value &= (~REG_PORT_ACL_EN_MASK);
1042 value |= (acl_en << REG_PORT_ACL_EN_OFFT);
1043
1044 printf("write reg: %x, value: %x\n", reg, value);
1045 reg_write(reg, value);
1046}
1047
1048static void dip_dump_internal(int type)
1049{
1050 unsigned int i, j, value, mac, mac2, value2;
developerbe40a9e2024-03-07 21:44:26 +08001051 char tmpstr[16] = { 0 };
developerfd40db22021-04-29 10:08:25 +08001052 int table_size = 0;
1053 int hit_value1 = 0;
1054 int hit_value2 = 0;
1055
developerbe40a9e2024-03-07 21:44:26 +08001056 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001057 table_size = 0x800;
developerbe40a9e2024-03-07 21:44:26 +08001058 reg_write(REG_ATC_ADDR, 0x8104); //dip search command
1059 } else {
developerfd40db22021-04-29 10:08:25 +08001060 table_size = 0x40;
developerbe40a9e2024-03-07 21:44:26 +08001061 reg_write(REG_ATC_ADDR, 0x811c); //dip search command
developerfd40db22021-04-29 10:08:25 +08001062 }
developerbe40a9e2024-03-07 21:44:26 +08001063 printf
1064 ("hash port(0:6) rsp_cnt flag timer dip-address ATRD\n");
developerfd40db22021-04-29 10:08:25 +08001065 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001066 while (1) {
developerfd40db22021-04-29 10:08:25 +08001067 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001068 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001069 hit_value1 = value & (0x1 << 13);
1070 hit_value2 = 1;
developerbe40a9e2024-03-07 21:44:26 +08001071 } else {
developerfd40db22021-04-29 10:08:25 +08001072 hit_value1 = value & (0x1 << 13);
1073 hit_value2 = value & (0x1 << 28);
1074 }
1075
developerbe40a9e2024-03-07 21:44:26 +08001076 if (hit_value1 && hit_value2) { //search_rdy
developerfd40db22021-04-29 10:08:25 +08001077 reg_read(REG_ATRD_ADDR, &value2);
1078 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1079
developerbe40a9e2024-03-07 21:44:26 +08001080 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1081 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001082 printf("%c", (j & 0x01) ? '1' : '-');
1083 printf("%c", (j & 0x02) ? '1' : '-');
1084 printf("%c", (j & 0x04) ? '1' : '-');
1085 printf("%c ", (j & 0x08) ? '1' : '-');
1086 printf("%c", (j & 0x10) ? '1' : '-');
1087 printf("%c", (j & 0x20) ? '1' : '-');
1088 printf("%c", (j & 0x40) ? '1' : '-');
1089
1090 reg_read(REG_TSRA2_ADDR, &mac2);
1091
developerbe40a9e2024-03-07 21:44:26 +08001092 printf(" 0x%4x", (mac2 & 0xffff)); //RESP_CNT
1093 printf(" 0x%2x", ((mac2 >> 16) & 0xff)); //RESP_FLAG
1094 printf(" %3d", ((mac2 >> 24) & 0xff)); //RESP_TIMER
1095 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001096 reg_read(REG_TSRA1_ADDR, &mac);
1097 ip_to_str(tmpstr, mac);
1098 printf(" %s", tmpstr);
developerbe40a9e2024-03-07 21:44:26 +08001099 printf(" 0x%8x\n", value2); //ATRD
1100 //printf("%04x", ((mac2 >> 16) & 0xffff));
1101 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
developerfd40db22021-04-29 10:08:25 +08001102 if (value & 0x4000) {
1103 printf("end of table %d\n", i);
1104 return;
1105 }
1106 break;
developerbe40a9e2024-03-07 21:44:26 +08001107 } else if (value & 0x4000) { //at_table_end
1108 printf("found the last entry %d (not ready)\n",
1109 i);
developerfd40db22021-04-29 10:08:25 +08001110 return;
1111 }
1112 usleep(5000);
1113 }
1114
developerbe40a9e2024-03-07 21:44:26 +08001115 if (type == GENERAL_TABLE)
1116 reg_write(REG_ATC_ADDR, 0x8105); //search for next dip address
developerfd40db22021-04-29 10:08:25 +08001117 else
developerbe40a9e2024-03-07 21:44:26 +08001118 reg_write(REG_ATC_ADDR, 0x811d); //search for next dip address
developerfd40db22021-04-29 10:08:25 +08001119 usleep(5000);
1120 }
1121}
1122
developerbe40a9e2024-03-07 21:44:26 +08001123void dip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001124{
1125 dip_dump_internal(GENERAL_TABLE);
1126
1127}
1128
1129void dip_add(int argc, char *argv[])
1130{
1131 unsigned int value = 0;
developerbe40a9e2024-03-07 21:44:26 +08001132 unsigned int i = 0, j = 0;
developerfd40db22021-04-29 10:08:25 +08001133
1134 value = 0;
1135
1136 str_to_ip(&value, argv[3]);
1137
1138 reg_write(REG_ATA1_ADDR, value);
1139 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1140
1141#if 0
1142 reg_write(REG_ATA2_ADDR, value);
1143 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1144#endif
1145 if (!argv[4] || strlen(argv[4]) != 8) {
1146 printf("portmap format error, should be of length 7\n");
1147 return;
1148 }
1149 j = 0;
1150 for (i = 0; i < 7; i++) {
1151 if (argv[4][i] != '0' && argv[4][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001152 printf
1153 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001154 return;
1155 }
1156 j += (argv[4][i] - '0') * (1 << i);
1157 }
developerbe40a9e2024-03-07 21:44:26 +08001158 value = j << 4; //w_port_map
1159 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001160
1161 reg_write(REG_ATWD_ADDR, value);
1162
1163 usleep(5000);
1164 reg_read(REG_ATWD_ADDR, &value);
1165 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1166
developerbe40a9e2024-03-07 21:44:26 +08001167 value = 0x8011; //single w_dip_cmd
developerfd40db22021-04-29 10:08:25 +08001168 reg_write(REG_ATC_ADDR, value);
1169
1170 usleep(1000);
1171
1172 for (i = 0; i < 20; i++) {
1173 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001174 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001175 printf("done.\n");
1176 return;
1177 }
1178 usleep(1000);
1179 }
1180 if (i == 20)
1181 printf("timeout.\n");
1182}
1183
1184void dip_del(int argc, char *argv[])
1185{
1186 unsigned int i, value;
1187
1188 value = 0;
1189 str_to_ip(&value, argv[3]);
1190
1191 reg_write(REG_ATA1_ADDR, value);
1192
1193 value = 0;
1194 reg_write(REG_ATA2_ADDR, value);
1195
developerbe40a9e2024-03-07 21:44:26 +08001196 value = 0; //STATUS=0, delete dip
developerfd40db22021-04-29 10:08:25 +08001197 reg_write(REG_ATWD_ADDR, value);
1198
developerbe40a9e2024-03-07 21:44:26 +08001199 value = 0x8011; //w_dip_cmd
developerfd40db22021-04-29 10:08:25 +08001200 reg_write(REG_ATC_ADDR, value);
1201
1202 for (i = 0; i < 20; i++) {
1203 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001204 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001205 if (argv[1] != NULL)
1206 printf("done.\n");
1207 return;
1208 }
1209 usleep(1000);
1210 }
1211 if (i == 20)
1212 printf("timeout.\n");
1213}
1214
developerbe40a9e2024-03-07 21:44:26 +08001215void dip_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001216{
1217
developerbe40a9e2024-03-07 21:44:26 +08001218 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001219
developerbe40a9e2024-03-07 21:44:26 +08001220 reg_write(REG_ATC_ADDR, 0x8102); //clear all dip
developerfd40db22021-04-29 10:08:25 +08001221 usleep(5000);
1222 reg_read(REG_ATC_ADDR, &value);
1223 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1224}
1225
1226static void sip_dump_internal(int type)
1227{
developerbe40a9e2024-03-07 21:44:26 +08001228 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001229 int table_size = 0;
1230 int hit_value1 = 0;
1231 int hit_value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08001232 char tmpstr[16] = { 0 };
developerfd40db22021-04-29 10:08:25 +08001233
1234 if (type == GENERAL_TABLE) {
1235 table_size = 0x800;
developerbe40a9e2024-03-07 21:44:26 +08001236 reg_write(REG_ATC_ADDR, 0x8204); //sip search command
1237 } else {
developerfd40db22021-04-29 10:08:25 +08001238 table_size = 0x40;
developerbe40a9e2024-03-07 21:44:26 +08001239 reg_write(REG_ATC_ADDR, 0x822c); //sip search command
developerfd40db22021-04-29 10:08:25 +08001240 }
1241 printf("hash port(0:6) dip-address sip-address ATRD\n");
1242 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001243 while (1) {
developerfd40db22021-04-29 10:08:25 +08001244 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001245 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001246 hit_value1 = value & (0x1 << 13);
1247 hit_value2 = 1;
1248 } else {
1249 hit_value1 = value & (0x1 << 13);
1250 hit_value2 = value & (0x1 << 28);
1251 }
1252
developerbe40a9e2024-03-07 21:44:26 +08001253 if (hit_value1 && hit_value2) { //search_rdy
developerfd40db22021-04-29 10:08:25 +08001254 reg_read(REG_ATRD_ADDR, &value2);
1255 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1256
developerbe40a9e2024-03-07 21:44:26 +08001257 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1258 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001259 printf("%c", (j & 0x01) ? '1' : '-');
1260 printf("%c", (j & 0x02) ? '1' : '-');
1261 printf("%c", (j & 0x04) ? '1' : '-');
1262 printf("%c", (j & 0x08) ? '1' : '-');
1263 printf(" %c", (j & 0x10) ? '1' : '-');
1264 printf("%c", (j & 0x20) ? '1' : '-');
1265 printf("%c", (j & 0x40) ? '1' : '-');
1266
1267 reg_read(REG_TSRA2_ADDR, &mac2);
1268
1269 ip_to_str(tmpstr, mac2);
1270 printf(" %s", tmpstr);
1271
1272 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
1273 reg_read(REG_TSRA1_ADDR, &mac);
1274 ip_to_str(tmpstr, mac);
1275 printf(" %s", tmpstr);
1276 printf(" 0x%x\n", value2);
1277 //printf("%04x", ((mac2 >> 16) & 0xffff));
1278 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
1279 if (value & 0x4000) {
1280 printf("end of table %d\n", i);
1281 return;
1282 }
1283 break;
developerbe40a9e2024-03-07 21:44:26 +08001284 } else if (value & 0x4000) { //at_table_end
1285 printf("found the last entry %d (not ready)\n",
1286 i);
developerfd40db22021-04-29 10:08:25 +08001287 return;
1288 }
1289 usleep(5000);
1290 }
1291
developerbe40a9e2024-03-07 21:44:26 +08001292 if (type == GENERAL_TABLE)
1293 reg_write(REG_ATC_ADDR, 0x8205); //search for next sip address
1294 else
1295 reg_write(REG_ATC_ADDR, 0x822d); //search for next sip address
1296 usleep(5000);
developerfd40db22021-04-29 10:08:25 +08001297 }
1298}
1299
developerbe40a9e2024-03-07 21:44:26 +08001300void sip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001301{
1302
1303 sip_dump_internal(GENERAL_TABLE);
1304
1305}
1306
developerfd40db22021-04-29 10:08:25 +08001307void sip_add(int argc, char *argv[])
1308{
developerbe40a9e2024-03-07 21:44:26 +08001309 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001310
1311 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08001312 str_to_ip(&value, argv[3]); //SIP
developerfd40db22021-04-29 10:08:25 +08001313
1314 reg_write(REG_ATA2_ADDR, value);
1315 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1316
1317 value = 0;
1318
developerbe40a9e2024-03-07 21:44:26 +08001319 str_to_ip(&value, argv[4]); //DIP
developerfd40db22021-04-29 10:08:25 +08001320 reg_write(REG_ATA1_ADDR, value);
1321 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1322
1323 if (!argv[5] || strlen(argv[5]) != 8) {
1324 printf("portmap format error, should be of length 7\n");
1325 return;
1326 }
1327 j = 0;
1328 for (i = 0; i < 7; i++) {
1329 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001330 printf
1331 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001332 return;
1333 }
1334 j += (argv[5][i] - '0') * (1 << i);
1335 }
developerbe40a9e2024-03-07 21:44:26 +08001336 value = j << 4; //w_port_map
1337 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001338
1339 reg_write(REG_ATWD_ADDR, value);
1340
1341 usleep(5000);
1342 reg_read(REG_ATWD_ADDR, &value);
1343 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1344
developerbe40a9e2024-03-07 21:44:26 +08001345 value = 0x8021; //single w_sip_cmd
developerfd40db22021-04-29 10:08:25 +08001346 reg_write(REG_ATC_ADDR, value);
1347
1348 usleep(1000);
1349
1350 for (i = 0; i < 20; i++) {
1351 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001352 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001353 printf("done.\n");
1354 return;
1355 }
1356 usleep(1000);
1357 }
1358 if (i == 20)
1359 printf("timeout.\n");
1360}
1361
1362void sip_del(int argc, char *argv[])
1363{
developerbe40a9e2024-03-07 21:44:26 +08001364 unsigned int i = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001365
1366 value = 0;
1367 str_to_ip(&value, argv[3]);
1368
developerbe40a9e2024-03-07 21:44:26 +08001369 reg_write(REG_ATA2_ADDR, value); //SIP
developerfd40db22021-04-29 10:08:25 +08001370
1371 str_to_ip(&value, argv[4]);
developerbe40a9e2024-03-07 21:44:26 +08001372 reg_write(REG_ATA1_ADDR, value); //DIP
developerfd40db22021-04-29 10:08:25 +08001373
developerbe40a9e2024-03-07 21:44:26 +08001374 value = 0; //STATUS=0, delete sip
developerfd40db22021-04-29 10:08:25 +08001375 reg_write(REG_ATWD_ADDR, value);
1376
developerbe40a9e2024-03-07 21:44:26 +08001377 value = 0x8021; //w_sip_cmd
developerfd40db22021-04-29 10:08:25 +08001378 reg_write(REG_ATC_ADDR, value);
1379
1380 for (i = 0; i < 20; i++) {
1381 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001382 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001383 if (argv[1] != NULL)
1384 printf("done.\n");
1385 return;
1386 }
1387 usleep(1000);
1388 }
1389 if (i == 20)
1390 printf("timeout.\n");
1391}
1392
developerbe40a9e2024-03-07 21:44:26 +08001393void sip_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001394{
developerbe40a9e2024-03-07 21:44:26 +08001395 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08001396
developerbe40a9e2024-03-07 21:44:26 +08001397 reg_write(REG_ATC_ADDR, 0x8202); //clear all sip
developerfd40db22021-04-29 10:08:25 +08001398 usleep(5000);
1399 reg_read(REG_ATC_ADDR, &value);
1400 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1401}
1402
1403static void table_dump_internal(int type)
1404{
developerbe40a9e2024-03-07 21:44:26 +08001405 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001406 int table_size = 0;
1407 int table_end = 0;
1408 int hit_value1 = 0;
1409 int hit_value2 = 0;
1410
developerbe40a9e2024-03-07 21:44:26 +08001411 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001412 table_size = 0x800;
1413 table_end = 0x7FF;
1414 reg_write(REG_ATC_ADDR, 0x8004);
1415 } else {
1416 table_size = 0x40;
1417 table_end = 0x3F;
1418 reg_write(REG_ATC_ADDR, 0x800C);
1419 }
developerbe40a9e2024-03-07 21:44:26 +08001420 printf
1421 ("hash port(0:6) fid vid age(s) mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001422 for (i = 0; i < table_size; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001423 while (1) {
developerfd40db22021-04-29 10:08:25 +08001424 reg_read(REG_ATC_ADDR, &value);
1425 //printf("ATC = 0x%x\n", value);
developerbe40a9e2024-03-07 21:44:26 +08001426 if (type == GENERAL_TABLE) {
developerfd40db22021-04-29 10:08:25 +08001427 hit_value1 = value & (0x1 << 13);
1428 hit_value2 = 1;
1429 } else {
1430 hit_value1 = value & (0x1 << 13);
1431 hit_value2 = value & (0x1 << 28);
1432 }
1433
developerbe40a9e2024-03-07 21:44:26 +08001434 if (hit_value1 && hit_value2
1435 && (((value >> 15) & 0x1) == 0)) {
developerfd40db22021-04-29 10:08:25 +08001436 printf("%03x: ", (value >> 16) & 0xfff);
1437 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001438 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001439 printf("%c", (j & 0x01) ? '1' : '-');
1440 printf("%c", (j & 0x02) ? '1' : '-');
1441 printf("%c", (j & 0x04) ? '1' : '-');
1442 printf("%c", (j & 0x08) ? '1' : '-');
1443 printf("%c", (j & 0x10) ? '1' : '-');
1444 printf("%c", (j & 0x20) ? '1' : '-');
1445 printf("%c", (j & 0x40) ? '1' : '-');
1446 printf("%c", (j & 0x80) ? '1' : '-');
1447
1448 reg_read(REG_TSRA2_ADDR, &mac2);
1449
developerbe40a9e2024-03-07 21:44:26 +08001450 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001451 printf(" %4d", (mac2 & 0xfff));
1452 if (((value2 >> 24) & 0xff) == 0xFF)
developerbe40a9e2024-03-07 21:44:26 +08001453 printf(" --- "); //r_age_field:static
developerfd40db22021-04-29 10:08:25 +08001454 else
developerbe40a9e2024-03-07 21:44:26 +08001455 printf(" %5d ", (((value2 >> 24) & 0xff) + 1) * 2); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001456 reg_read(REG_TSRA1_ADDR, &mac);
1457 printf(" %08x", mac);
1458 printf("%04x", ((mac2 >> 16) & 0xffff));
developerbe40a9e2024-03-07 21:44:26 +08001459 printf(" %c",
1460 (((value2 >> 20) & 0x03) ==
1461 0x03) ? 'y' : '-');
1462 printf(" %c\n",
1463 (((value2 >> 23) & 0x01) ==
1464 0x01) ? 'y' : '-');
1465 if ((value & 0x4000)
1466 && (((value >> 16) & 0xfff) == table_end)) {
developerfd40db22021-04-29 10:08:25 +08001467 printf("end of table %d\n", i);
1468 return;
1469 }
1470 break;
developerbe40a9e2024-03-07 21:44:26 +08001471 } else if ((value & 0x4000) && (((value >> 15) & 0x1) == 0) && (((value >> 16) & 0xfff) == table_end)) { //at_table_end
1472 printf("found the last entry %d (not ready)\n",
1473 i);
developerfd40db22021-04-29 10:08:25 +08001474 return;
developerbe40a9e2024-03-07 21:44:26 +08001475 } else
developerfd40db22021-04-29 10:08:25 +08001476 usleep(5);
1477 }
1478
developerbe40a9e2024-03-07 21:44:26 +08001479 if (type == GENERAL_TABLE)
1480 reg_write(REG_ATC_ADDR, 0x8005); //search for next address
1481 else
1482 reg_write(REG_ATC_ADDR, 0x800d); //search for next address
developerfd40db22021-04-29 10:08:25 +08001483 usleep(5);
1484 }
1485}
1486
developerbe40a9e2024-03-07 21:44:26 +08001487void table_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001488{
1489 table_dump_internal(GENERAL_TABLE);
1490
1491}
1492
developerfd40db22021-04-29 10:08:25 +08001493void table_add(int argc, char *argv[])
1494{
developerbe40a9e2024-03-07 21:44:26 +08001495 unsigned int i = 0, j = 0, value = 0, is_filter = 0, is_mymac = 0;
developerfd40db22021-04-29 10:08:25 +08001496 char tmpstr[9];
1497
1498 is_filter = (argv[1][0] == 'f') ? 1 : 0;
1499 is_mymac = (argv[1][0] == 'm') ? 1 : 0;
1500 if (!argv[2] || strlen(argv[2]) != 12) {
1501 printf("MAC address format error, should be of length 12\n");
1502 return;
1503 }
1504 strncpy(tmpstr, argv[2], 8);
1505 tmpstr[8] = '\0';
1506 value = strtoul(tmpstr, NULL, 16);
1507 reg_write(REG_ATA1_ADDR, value);
1508 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1509
1510 strncpy(tmpstr, argv[2] + 8, 4);
1511 tmpstr[4] = '\0';
1512
1513 value = strtoul(tmpstr, NULL, 16);
1514 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001515 value |= (1 << 15); //IVL=1
developerfd40db22021-04-29 10:08:25 +08001516
1517 if (argc > 4) {
1518 j = strtoul(argv[4], NULL, 0);
1519 if (4095 < j) {
1520 printf("wrong vid range, should be within 0~4095\n");
1521 return;
1522 }
developerbe40a9e2024-03-07 21:44:26 +08001523 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001524 }
1525
1526 reg_write(REG_ATA2_ADDR, value);
1527 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1528
1529 if (!argv[3] || strlen(argv[3]) != 8) {
1530 if (is_filter)
1531 argv[3] = "11111111";
1532 else {
1533 printf("portmap format error, should be of length 8\n");
1534 return;
1535 }
1536 }
1537 j = 0;
1538 for (i = 0; i < 7; i++) {
1539 if (argv[3][i] != '0' && argv[3][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08001540 printf
1541 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08001542 return;
1543 }
1544 j += (argv[3][i] - '0') * (1 << i);
1545 }
developerbe40a9e2024-03-07 21:44:26 +08001546 value = j << 4; //w_port_map
developerfd40db22021-04-29 10:08:25 +08001547
1548 if (argc > 5) {
1549 j = strtoul(argv[5], NULL, 0);
1550 if (j < 1 || 255 < j) {
1551 printf("wrong age range, should be within 1~255\n");
1552 return;
1553 }
developerbe40a9e2024-03-07 21:44:26 +08001554 value |= (j << 24); //w_age_field
1555 value |= (0x1 << 2); //dynamic
developerfd40db22021-04-29 10:08:25 +08001556 } else {
developerbe40a9e2024-03-07 21:44:26 +08001557 value |= (0xff << 24); //w_age_field
1558 value |= (0x3 << 2); //static
developerfd40db22021-04-29 10:08:25 +08001559 }
1560
1561 if (argc > 6) {
1562 j = strtoul(argv[6], NULL, 0);
1563 if (7 < j) {
1564 printf("wrong eg-tag range, should be within 0~7\n");
1565 return;
1566 }
developerbe40a9e2024-03-07 21:44:26 +08001567 value |= (j << 13); //EG_TAG
developerfd40db22021-04-29 10:08:25 +08001568 }
1569
1570 if (is_filter)
developerbe40a9e2024-03-07 21:44:26 +08001571 value |= (7 << 20); //sa_filter
developerfd40db22021-04-29 10:08:25 +08001572
1573 if (is_mymac)
1574 value |= (1 << 23);
1575
1576 reg_write(REG_ATWD_ADDR, value);
1577
1578 usleep(5000);
1579 reg_read(REG_ATWD_ADDR, &value);
1580 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1581
developerbe40a9e2024-03-07 21:44:26 +08001582 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001583 reg_write(REG_ATC_ADDR, value);
1584
1585 usleep(1000);
1586
1587 for (i = 0; i < 20; i++) {
1588 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001589 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001590 printf("done.\n");
1591 return;
1592 }
1593 usleep(1000);
1594 }
1595 if (i == 20)
1596 printf("timeout.\n");
1597}
1598
1599void table_search_mac_vid(int argc, char *argv[])
1600{
developerbe40a9e2024-03-07 21:44:26 +08001601 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001602 char tmpstr[9];
1603
1604 if (!argv[3] || strlen(argv[3]) != 12) {
1605 printf("MAC address format error, should be of length 12\n");
1606 return;
1607 }
1608 strncpy(tmpstr, argv[3], 8);
1609 tmpstr[8] = '\0';
1610 value = strtoul(tmpstr, NULL, 16);
1611 reg_write(REG_ATA1_ADDR, value);
1612 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1613
1614 strncpy(tmpstr, argv[3] + 8, 4);
1615 tmpstr[4] = '\0';
1616
1617 value = strtoul(tmpstr, NULL, 16);
1618 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001619 value |= (1 << 15); //IVL=1
developerfd40db22021-04-29 10:08:25 +08001620
1621 j = strtoul(argv[5], NULL, 0);
1622 if (4095 < j) {
1623 printf("wrong vid range, should be within 0~4095\n");
1624 return;
1625 }
developerbe40a9e2024-03-07 21:44:26 +08001626 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001627
1628 reg_write(REG_ATA2_ADDR, value);
1629 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1630
developerbe40a9e2024-03-07 21:44:26 +08001631 value = 0x8000; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001632 reg_write(REG_ATC_ADDR, value);
1633
1634 usleep(1000);
1635
1636 for (i = 0; i < 20; i++) {
1637 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001638 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001639 break;
1640 }
1641 usleep(1000);
1642 }
1643 if (i == 20) {
1644 printf("search timeout.\n");
1645 return;
1646 }
1647
1648 if (value & 0x1000) {
1649 printf("search no entry.\n");
1650 return;
1651 }
1652
1653 printf("search done.\n");
developerbe40a9e2024-03-07 21:44:26 +08001654 printf
1655 ("hash port(0:6) fid vid age mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001656
developerbe40a9e2024-03-07 21:44:26 +08001657 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
developerfd40db22021-04-29 10:08:25 +08001658 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001659 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001660 printf("%c", (j & 0x01) ? '1' : '-');
1661 printf("%c", (j & 0x02) ? '1' : '-');
1662 printf("%c", (j & 0x04) ? '1' : '-');
1663 printf("%c ", (j & 0x08) ? '1' : '-');
1664 printf("%c", (j & 0x10) ? '1' : '-');
1665 printf("%c", (j & 0x20) ? '1' : '-');
1666 printf("%c", (j & 0x40) ? '1' : '-');
1667 printf("%c", (j & 0x80) ? '1' : '-');
1668
1669 reg_read(REG_TSRA2_ADDR, &mac2);
1670
developerbe40a9e2024-03-07 21:44:26 +08001671 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001672 printf(" %4d", (mac2 & 0xfff));
developerbe40a9e2024-03-07 21:44:26 +08001673 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001674 reg_read(REG_TSRA1_ADDR, &mac);
1675 printf(" %08x", mac);
1676 printf("%04x", ((mac2 >> 16) & 0xffff));
1677 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1678 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1679}
1680
1681void table_search_mac_fid(int argc, char *argv[])
1682{
developerbe40a9e2024-03-07 21:44:26 +08001683 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001684 char tmpstr[9];
1685
1686 if (!argv[3] || strlen(argv[3]) != 12) {
1687 printf("MAC address format error, should be of length 12\n");
1688 return;
1689 }
1690 strncpy(tmpstr, argv[3], 8);
1691 tmpstr[8] = '\0';
1692 value = strtoul(tmpstr, NULL, 16);
1693 reg_write(REG_ATA1_ADDR, value);
1694 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1695
1696 strncpy(tmpstr, argv[3] + 8, 4);
1697 tmpstr[4] = '\0';
1698
1699 value = strtoul(tmpstr, NULL, 16);
1700 value = (value << 16);
developerbe40a9e2024-03-07 21:44:26 +08001701 value &= ~(1 << 15); //IVL=0
developerfd40db22021-04-29 10:08:25 +08001702
1703 j = strtoul(argv[5], NULL, 0);
1704 if (7 < j) {
1705 printf("wrong fid range, should be within 0~7\n");
1706 return;
1707 }
developerbe40a9e2024-03-07 21:44:26 +08001708 value |= (j << 12); //vid
developerfd40db22021-04-29 10:08:25 +08001709
1710 reg_write(REG_ATA2_ADDR, value);
1711 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1712
developerbe40a9e2024-03-07 21:44:26 +08001713 value = 0x8000; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001714 reg_write(REG_ATC_ADDR, value);
1715
1716 usleep(1000);
1717
1718 for (i = 0; i < 20; i++) {
1719 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001720 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001721 break;
1722 }
1723 usleep(1000);
1724 }
1725 if (i == 20) {
1726 printf("search timeout.\n");
1727 return;
1728 }
1729
1730 if (value & 0x1000) {
1731 printf("search no entry.\n");
1732 return;
1733 }
1734
1735 printf("search done.\n");
developerbe40a9e2024-03-07 21:44:26 +08001736 printf
1737 ("hash port(0:6) fid vid age mac-address filter my_mac\n");
developerfd40db22021-04-29 10:08:25 +08001738
developerbe40a9e2024-03-07 21:44:26 +08001739 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
developerfd40db22021-04-29 10:08:25 +08001740 reg_read(REG_ATRD_ADDR, &value2);
developerbe40a9e2024-03-07 21:44:26 +08001741 j = (value2 >> 4) & 0xff; //r_port_map
developerfd40db22021-04-29 10:08:25 +08001742 printf("%c", (j & 0x01) ? '1' : '-');
1743 printf("%c", (j & 0x02) ? '1' : '-');
1744 printf("%c", (j & 0x04) ? '1' : '-');
1745 printf("%c ", (j & 0x08) ? '1' : '-');
1746 printf("%c", (j & 0x10) ? '1' : '-');
1747 printf("%c", (j & 0x20) ? '1' : '-');
1748 printf("%c", (j & 0x40) ? '1' : '-');
1749 printf("%c", (j & 0x80) ? '1' : '-');
1750
1751 reg_read(REG_TSRA2_ADDR, &mac2);
1752
developerbe40a9e2024-03-07 21:44:26 +08001753 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developerfd40db22021-04-29 10:08:25 +08001754 printf(" %4d", (mac2 & 0xfff));
developerbe40a9e2024-03-07 21:44:26 +08001755 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developerfd40db22021-04-29 10:08:25 +08001756 reg_read(REG_TSRA1_ADDR, &mac);
1757 printf(" %08x", mac);
1758 printf("%04x", ((mac2 >> 16) & 0xffff));
1759 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1760 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1761}
1762
1763void table_del_fid(int argc, char *argv[])
1764{
developerbe40a9e2024-03-07 21:44:26 +08001765 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001766 char tmpstr[9];
1767
1768 if (!argv[3] || strlen(argv[3]) != 12) {
1769 printf("MAC address format error, should be of length 12\n");
1770 return;
1771 }
1772 strncpy(tmpstr, argv[3], 8);
1773 tmpstr[8] = '\0';
1774 value = strtoul(tmpstr, NULL, 16);
1775 reg_write(REG_ATA1_ADDR, value);
1776 strncpy(tmpstr, argv[3] + 8, 4);
1777 tmpstr[4] = '\0';
1778 value = strtoul(tmpstr, NULL, 16);
1779 value = (value << 16);
1780
1781 if (argc > 5) {
1782 j = strtoul(argv[5], NULL, 0);
1783 if (j > 7) {
1784 printf("wrong fid range, should be within 0~7\n");
1785 return;
1786 }
developerbe40a9e2024-03-07 21:44:26 +08001787 value |= (j << 12); /* fid */
developerfd40db22021-04-29 10:08:25 +08001788 }
1789
1790 reg_write(REG_ATA2_ADDR, value);
1791
developerbe40a9e2024-03-07 21:44:26 +08001792 value = 0; /* STATUS=0, delete mac */
developerfd40db22021-04-29 10:08:25 +08001793 reg_write(REG_ATWD_ADDR, value);
1794
developerbe40a9e2024-03-07 21:44:26 +08001795 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001796 reg_write(REG_ATC_ADDR, value);
1797
1798 for (i = 0; i < 20; i++) {
1799 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001800 if ((value & 0x8000) == 0) { /* mac address busy */
developerfd40db22021-04-29 10:08:25 +08001801 if (argv[1] != NULL)
1802 printf("done.\n");
1803 return;
1804 }
1805 usleep(1000);
1806 }
1807 if (i == 20)
1808 printf("timeout.\n");
1809}
1810
1811void table_del_vid(int argc, char *argv[])
1812{
developerbe40a9e2024-03-07 21:44:26 +08001813 unsigned int i = 0, j = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08001814 char tmpstr[9];
1815
1816 if (!argv[3] || strlen(argv[3]) != 12) {
1817 printf("MAC address format error, should be of length 12\n");
1818 return;
1819 }
1820 strncpy(tmpstr, argv[3], 8);
1821 tmpstr[8] = '\0';
1822 value = strtoul(tmpstr, NULL, 16);
1823 reg_write(REG_ATA1_ADDR, value);
1824
1825 strncpy(tmpstr, argv[3] + 8, 4);
1826 tmpstr[4] = '\0';
1827 value = strtoul(tmpstr, NULL, 16);
1828 value = (value << 16);
1829
1830 j = strtoul(argv[5], NULL, 0);
1831 if (j > 4095) {
1832 printf("wrong fid range, should be within 0~4095\n");
1833 return;
1834 }
developerbe40a9e2024-03-07 21:44:26 +08001835 value |= j; //vid
developerfd40db22021-04-29 10:08:25 +08001836 value |= 1 << 15;
1837 reg_write(REG_ATA2_ADDR, value);
1838
developerbe40a9e2024-03-07 21:44:26 +08001839 value = 0; //STATUS=0, delete mac
developerfd40db22021-04-29 10:08:25 +08001840 reg_write(REG_ATWD_ADDR, value);
1841
developerbe40a9e2024-03-07 21:44:26 +08001842 value = 0x8001; //w_mac_cmd
developerfd40db22021-04-29 10:08:25 +08001843 reg_write(REG_ATC_ADDR, value);
1844
1845 for (i = 0; i < 20; i++) {
1846 reg_read(REG_ATC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001847 if ((value & 0x8000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001848 if (argv[1] != NULL)
1849 printf("done.\n");
1850 return;
1851 }
1852 usleep(1000);
1853 }
1854 if (i == 20)
1855 printf("timeout.\n");
1856}
1857
developerbe40a9e2024-03-07 21:44:26 +08001858void table_clear(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08001859{
developerbe40a9e2024-03-07 21:44:26 +08001860 unsigned int value = 0;
1861
developerfd40db22021-04-29 10:08:25 +08001862 reg_write(REG_ATC_ADDR, 0x8002);
1863 usleep(5000);
1864 reg_read(REG_ATC_ADDR, &value);
1865
1866 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1867}
1868
1869void set_mirror_to(int argc, char *argv[])
1870{
developerbe40a9e2024-03-07 21:44:26 +08001871 unsigned int value = 0;
1872 int idx = 0;
developerfd40db22021-04-29 10:08:25 +08001873
1874 idx = strtoul(argv[3], NULL, 0);
1875 if (idx < 0 || MAX_PORT < idx) {
1876 printf("wrong port member, should be within 0~%d\n", MAX_PORT);
1877 return;
1878 }
1879 if (chip_name == 0x7530) {
1880
1881 reg_read(REG_MFC_ADDR, &value);
1882 value |= 0x1 << 3;
1883 value &= 0xfffffff8;
1884 value |= idx << 0;
1885
1886 reg_write(REG_MFC_ADDR, value);
1887 } else {
1888
1889 reg_read(REG_CFC_ADDR, &value);
1890 value &= (~REG_CFC_MIRROR_EN_MASK);
1891 value |= (1 << REG_CFC_MIRROR_EN_OFFT);
1892 value &= (~REG_CFC_MIRROR_PORT_MASK);
1893 value |= (idx << REG_CFC_MIRROR_PORT_OFFT);
1894 reg_write(REG_CFC_ADDR, value);
1895 }
1896}
1897
1898void set_mirror_from(int argc, char *argv[])
1899{
developerbe40a9e2024-03-07 21:44:26 +08001900 unsigned int offset = 0, value = 0;
1901 int idx = 0, mirror = 0;
developerfd40db22021-04-29 10:08:25 +08001902
1903 idx = strtoul(argv[3], NULL, 0);
1904 mirror = strtoul(argv[4], NULL, 0);
1905
1906 if (idx < 0 || MAX_PORT < idx) {
1907 printf("wrong port member, should be within 0~%d\n", MAX_PORT);
1908 return;
1909 }
1910
1911 if (mirror < 0 || 3 < mirror) {
1912 printf("wrong mirror setting, should be within 0~3\n");
1913 return;
1914 }
1915
1916 offset = (0x2004 | (idx << 8));
1917 reg_read(offset, &value);
1918
1919 value &= 0xfffffcff;
1920 value |= mirror << 8;
1921
1922 reg_write(offset, value);
1923}
1924
1925void vlan_dump(int argc, char *argv[])
1926{
developerbe40a9e2024-03-07 21:44:26 +08001927 unsigned int i = 0, j = 0, value = 0, value2 = 0;
developerfd40db22021-04-29 10:08:25 +08001928 int eg_tag = 0;
1929
1930 if (argc == 4) {
1931 if (!strncmp(argv[3], "egtag", 6))
1932 eg_tag = 1;
1933 }
1934
1935 if (eg_tag)
developerbe40a9e2024-03-07 21:44:26 +08001936 printf
1937 (" vid fid portmap s-tag\teg_tag(0:untagged 2:tagged)\n");
developerfd40db22021-04-29 10:08:25 +08001938 else
1939 printf(" vid fid portmap s-tag\n");
1940
1941 for (i = 1; i < 4095; i++) {
developerbe40a9e2024-03-07 21:44:26 +08001942 value = (0x80000000 + i); //r_vid_cmd
developerfd40db22021-04-29 10:08:25 +08001943 reg_write(REG_VTCR_ADDR, value);
1944
1945 for (j = 0; j < 20; j++) {
1946 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08001947 if ((value & 0x80000000) == 0) { //mac address busy
developerfd40db22021-04-29 10:08:25 +08001948 break;
1949 }
1950 usleep(1000);
1951 }
1952 if (j == 20)
1953 printf("timeout.\n");
1954
1955 reg_read(REG_VAWD1_ADDR, &value);
1956 reg_read(REG_VAWD2_ADDR, &value2);
1957 //printf("REG_VAWD1_ADDR value%d is 0x%x\n\r", i, value);
1958 //printf("REG_VAWD2_ADDR value%d is 0x%x\n\r", i, value2);
1959
1960 if ((value & 0x01) != 0) {
1961 printf(" %4d ", i);
1962 printf(" %2d ", ((value & 0xe) >> 1));
1963 printf(" %c", (value & 0x00010000) ? '1' : '-');
1964 printf("%c", (value & 0x00020000) ? '1' : '-');
1965 printf("%c", (value & 0x00040000) ? '1' : '-');
1966 printf("%c", (value & 0x00080000) ? '1' : '-');
1967 printf("%c", (value & 0x00100000) ? '1' : '-');
1968 printf("%c", (value & 0x00200000) ? '1' : '-');
1969 printf("%c", (value & 0x00400000) ? '1' : '-');
1970 printf("%c", (value & 0x00800000) ? '1' : '-');
1971 printf(" %4d", ((value & 0xfff0) >> 4));
1972 if (eg_tag) {
1973 printf("\t");
1974 if ((value & (0x3 << 28)) == (0x3 << 28)) {
1975 /* VTAG_EN=1 and EG_CON=1 */
1976 printf("CONSISTENT");
1977 } else if (value & (0x1 << 28)) {
1978 /* VTAG_EN=1 */
1979 printf("%d", (value2 & 0x0003) >> 0);
1980 printf("%d", (value2 & 0x000c) >> 2);
1981 printf("%d", (value2 & 0x0030) >> 4);
1982 printf("%d", (value2 & 0x00c0) >> 6);
1983 printf("%d", (value2 & 0x0300) >> 8);
1984 printf("%d", (value2 & 0x0c00) >> 10);
1985 printf("%d", (value2 & 0x3000) >> 12);
1986 printf("%d", (value2 & 0xc000) >> 14);
1987 } else {
1988 /* VTAG_EN=0 */
1989 printf("DISABLED");
1990 }
1991 }
1992 printf("\n");
1993 } else {
developerbe40a9e2024-03-07 21:44:26 +08001994 /*print 16 vid for reference information */
developerfd40db22021-04-29 10:08:25 +08001995 if (i <= 16) {
1996 printf(" %4d ", i);
1997 printf(" %2d ", ((value & 0xe) >> 1));
1998 printf(" invalid\n");
1999 }
2000 }
2001 }
2002}
2003
developerfd40db22021-04-29 10:08:25 +08002004static long timespec_diff_us(struct timespec start, struct timespec end)
2005{
2006 struct timespec temp;
2007 unsigned long duration = 0;
2008
2009 if ((end.tv_nsec - start.tv_nsec) < 0) {
2010 temp.tv_sec = end.tv_sec - start.tv_sec - 1;
2011 temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
2012 } else {
2013 temp.tv_sec = end.tv_sec - start.tv_sec;
2014 temp.tv_nsec = end.tv_nsec - start.tv_nsec;
2015 }
developerbe40a9e2024-03-07 21:44:26 +08002016 /* calculate second part */
developerfd40db22021-04-29 10:08:25 +08002017 duration += temp.tv_sec * 1000000;
developerbe40a9e2024-03-07 21:44:26 +08002018 /* calculate ns part */
developerfd40db22021-04-29 10:08:25 +08002019 duration += temp.tv_nsec >> 10;
2020
2021 return duration;
2022}
2023
developerfd40db22021-04-29 10:08:25 +08002024void vlan_clear(int argc, char *argv[])
2025{
developerbe40a9e2024-03-07 21:44:26 +08002026 unsigned int value = 0;
2027 int vid = 0;
developerfd40db22021-04-29 10:08:25 +08002028 unsigned long duration_us = 0;
2029 struct timespec start, end;
2030
2031 for (vid = 0; vid < 4096; vid++) {
2032 clock_gettime(CLOCK_REALTIME, &start);
developerbe40a9e2024-03-07 21:44:26 +08002033 value = 0; //invalid
developerfd40db22021-04-29 10:08:25 +08002034 reg_write(REG_VAWD1_ADDR, value);
2035
developerbe40a9e2024-03-07 21:44:26 +08002036 value = (0x80001000 + vid); //w_vid_cmd
developerfd40db22021-04-29 10:08:25 +08002037 reg_write(REG_VTCR_ADDR, value);
2038 while (duration_us <= 1000) {
2039 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002040 if ((value & 0x80000000) == 0) { //table busy
developerfd40db22021-04-29 10:08:25 +08002041 break;
2042 }
2043 clock_gettime(CLOCK_REALTIME, &end);
2044 duration_us = timespec_diff_us(start, end);
2045 }
2046 if (duration_us > 1000)
2047 printf("config vlan timeout: %ld.\n", duration_us);
2048 }
2049}
2050
2051void vlan_set(int argc, char *argv[])
2052{
2053 unsigned int vlan_mem = 0;
2054 unsigned int value = 0;
2055 unsigned int value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08002056 int i = 0, vid = 0, fid = 0;
developerfd40db22021-04-29 10:08:25 +08002057 int stag = 0;
2058 unsigned long eg_con = 0;
2059 unsigned int eg_tag = 0;
2060
2061 if (argc < 5) {
2062 printf("insufficient arguments!\n");
2063 return;
2064 }
2065
2066 fid = strtoul(argv[3], NULL, 0);
2067 if (fid < 0 || fid > 7) {
2068 printf("wrong filtering db id range, should be within 0~7\n");
2069 return;
2070 }
2071 value |= (fid << 1);
2072
2073 vid = strtoul(argv[4], NULL, 0);
2074 if (vid < 0 || 0xfff < vid) {
2075 printf("wrong vlan id range, should be within 0~4095\n");
2076 return;
2077 }
2078
2079 if (strlen(argv[5]) != 8) {
2080 printf("portmap format error, should be of length 7\n");
2081 return;
2082 }
2083
2084 vlan_mem = 0;
2085 for (i = 0; i < 8; i++) {
2086 if (argv[5][i] != '0' && argv[5][i] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08002087 printf
2088 ("portmap format error, should be of combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08002089 return;
2090 }
2091 vlan_mem += (argv[5][i] - '0') * (1 << i);
2092 }
2093
2094 /* VLAN stag */
2095 if (argc > 6) {
2096 stag = strtoul(argv[6], NULL, 16);
2097 if (stag < 0 || 0xfff < stag) {
developerbe40a9e2024-03-07 21:44:26 +08002098 printf
2099 ("wrong stag id range, should be within 0~4095\n");
developerfd40db22021-04-29 10:08:25 +08002100 return;
2101 }
2102 //printf("STAG is 0x%x\n", stag);
2103 }
2104
2105 /* set vlan member */
2106 value |= (vlan_mem << 16);
developerbe40a9e2024-03-07 21:44:26 +08002107 value |= (1 << 30); //IVL=1
2108 value |= ((stag & 0xfff) << 4); //stag
2109 value |= 1; //valid
developerfd40db22021-04-29 10:08:25 +08002110
2111 if (argc > 7) {
2112 eg_con = strtoul(argv[7], NULL, 2);
2113 eg_con = !!eg_con;
developerbe40a9e2024-03-07 21:44:26 +08002114 value |= (eg_con << 29); //eg_con
2115 value |= (1 << 28); //eg tag control enable
developerfd40db22021-04-29 10:08:25 +08002116 }
2117
2118 if (argc > 8 && !eg_con) {
2119 if (strlen(argv[8]) != 8) {
developerbe40a9e2024-03-07 21:44:26 +08002120 printf
2121 ("egtag portmap format error, should be of length 7\n");
developerfd40db22021-04-29 10:08:25 +08002122 return;
2123 }
2124
2125 for (i = 0; i < 8; i++) {
2126 if (argv[8][i] < '0' || argv[8][i] > '3') {
developerbe40a9e2024-03-07 21:44:26 +08002127 printf
2128 ("egtag portmap format error, should be of combination of 0 or 3\n");
developerfd40db22021-04-29 10:08:25 +08002129 return;
2130 }
2131 //eg_tag += (argv[8][i] - '0') * (1 << i * 2);
2132 eg_tag |= (argv[8][i] - '0') << (i * 2);
2133 }
2134
developerbe40a9e2024-03-07 21:44:26 +08002135 value |= (1 << 28); //eg tag control enable
developerfd40db22021-04-29 10:08:25 +08002136 value2 &= ~(0xffff);
2137 value2 |= eg_tag;
2138 }
2139 reg_write(REG_VAWD1_ADDR, value);
2140 reg_write(REG_VAWD2_ADDR, value2);
2141 //printf("VAWD1=0x%08x VAWD2=0x%08x ", value, value2);
2142
developerbe40a9e2024-03-07 21:44:26 +08002143 value = (0x80001000 + vid); //w_vid_cmd
developerfd40db22021-04-29 10:08:25 +08002144 reg_write(REG_VTCR_ADDR, value);
2145 //printf("VTCR=0x%08x\n", value);
2146
2147 for (i = 0; i < 300; i++) {
2148 usleep(1000);
2149 reg_read(REG_VTCR_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002150 if ((value & 0x80000000) == 0) //table busy
developerfd40db22021-04-29 10:08:25 +08002151 break;
2152 }
2153
2154 if (i == 300)
2155 printf("config vlan timeout.\n");
2156}
2157
2158void igmp_on(int argc, char *argv[])
2159{
2160 unsigned int leaky_en = 0;
2161 unsigned int wan_num = 4;
developerbe40a9e2024-03-07 21:44:26 +08002162 unsigned int port = 0, offset = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002163 char cmd[80];
2164 int ret;
2165
2166 if (argc > 3)
2167 leaky_en = strtoul(argv[3], NULL, 10);
2168 if (argc > 4)
2169 wan_num = strtoul(argv[4], NULL, 10);
2170
2171 if (leaky_en == 1) {
2172 if (wan_num == 4) {
2173 /* reg_write(0x2410, 0x810000c8); */
2174 reg_read(0x2410, &value);
2175 reg_write(0x2410, value | (1 << 3));
2176 /* reg_write(0x2010, 0x810000c0); */
2177 reg_read(0x2010, &value);
2178 reg_write(0x2010, value & (~(1 << 3)));
2179 reg_write(REG_ISC_ADDR, 0x10027d10);
2180 } else {
2181 /* reg_write(0x2010, 0x810000c8); */
2182 reg_read(0x2010, &value);
2183 reg_write(0x2010, value | (1 << 3));
2184 /* reg_write(0x2410, 0x810000c0); */
2185 reg_read(0x2410, &value);
2186 reg_write(0x2410, value & (~(1 << 3)));
2187 reg_write(REG_ISC_ADDR, 0x01027d01);
2188 }
developerbe40a9e2024-03-07 21:44:26 +08002189 } else
developerfd40db22021-04-29 10:08:25 +08002190 reg_write(REG_ISC_ADDR, 0x10027d60);
2191
2192 reg_write(0x1c, 0x08100810);
2193 reg_write(0x2008, 0xb3ff);
2194 reg_write(0x2108, 0xb3ff);
2195 reg_write(0x2208, 0xb3ff);
2196 reg_write(0x2308, 0xb3ff);
2197 reg_write(0x2408, 0xb3ff);
2198 reg_write(0x2608, 0xb3ff);
2199 /* Enable Port ACL
developerbe40a9e2024-03-07 21:44:26 +08002200 * reg_write(0x2P04, 0xff0403);
2201 */
developerfd40db22021-04-29 10:08:25 +08002202 for (port = 0; port <= 6; port++) {
2203 offset = 0x2004 + port * 0x100;
2204 reg_read(offset, &value);
2205 reg_write(offset, value | (1 << 10));
2206 }
2207
developerbe40a9e2024-03-07 21:44:26 +08002208 /*IGMP query only p4 -> p5 */
developerfd40db22021-04-29 10:08:25 +08002209 reg_write(0x94, 0x00ff0002);
2210 if (wan_num == 4)
2211 reg_write(0x98, 0x000a1008);
2212 else
2213 reg_write(0x98, 0x000a0108);
2214 reg_write(0x90, 0x80005000);
2215 reg_write(0x94, 0xff001100);
2216 if (wan_num == 4)
2217 reg_write(0x98, 0x000B1000);
2218 else
2219 reg_write(0x98, 0x000B0100);
2220 reg_write(0x90, 0x80005001);
2221 reg_write(0x94, 0x3);
2222 reg_write(0x98, 0x0);
2223 reg_write(0x90, 0x80009000);
2224 reg_write(0x94, 0x1a002080);
2225 reg_write(0x98, 0x0);
2226 reg_write(0x90, 0x8000b000);
2227
developerbe40a9e2024-03-07 21:44:26 +08002228 /*IGMP p5 -> p4 */
developerfd40db22021-04-29 10:08:25 +08002229 reg_write(0x94, 0x00ff0002);
2230 reg_write(0x98, 0x000a2008);
2231 reg_write(0x90, 0x80005002);
2232 reg_write(0x94, 0x4);
2233 reg_write(0x98, 0x0);
2234 reg_write(0x90, 0x80009001);
2235 if (wan_num == 4)
2236 reg_write(0x94, 0x1a001080);
2237 else
2238 reg_write(0x94, 0x1a000180);
2239 reg_write(0x98, 0x0);
2240 reg_write(0x90, 0x8000b001);
2241
developerbe40a9e2024-03-07 21:44:26 +08002242 /*IGMP p0~p3 -> p6 */
developerfd40db22021-04-29 10:08:25 +08002243 reg_write(0x94, 0x00ff0002);
2244 if (wan_num == 4)
2245 reg_write(0x98, 0x000a0f08);
2246 else
2247 reg_write(0x98, 0x000a1e08);
2248 reg_write(0x90, 0x80005003);
2249 reg_write(0x94, 0x8);
2250 reg_write(0x98, 0x0);
2251 reg_write(0x90, 0x80009002);
2252 reg_write(0x94, 0x1a004080);
2253 reg_write(0x98, 0x0);
2254 reg_write(0x90, 0x8000b002);
2255
developerbe40a9e2024-03-07 21:44:26 +08002256 /*IGMP query only p6 -> p0~p3 */
developerfd40db22021-04-29 10:08:25 +08002257 reg_write(0x94, 0x00ff0002);
2258 reg_write(0x98, 0x000a4008);
2259 reg_write(0x90, 0x80005004);
2260 reg_write(0x94, 0xff001100);
2261 reg_write(0x98, 0x000B4000);
2262 reg_write(0x90, 0x80005005);
2263 reg_write(0x94, 0x30);
2264 reg_write(0x98, 0x0);
2265 reg_write(0x90, 0x80009003);
2266 if (wan_num == 4)
2267 reg_write(0x94, 0x1a000f80);
2268 else
2269 reg_write(0x94, 0x1a001e80);
2270 reg_write(0x98, 0x0);
2271 reg_write(0x90, 0x8000b003);
2272
developerbe40a9e2024-03-07 21:44:26 +08002273 /*Force eth2 to receive all igmp packets */
2274 snprintf(cmd, sizeof(cmd),
2275 "echo 2 > /sys/devices/virtual/net/%s/brif/%s/multicast_router",
2276 BR_DEVNAME, ETH_DEVNAME);
developerfd40db22021-04-29 10:08:25 +08002277 ret = system(cmd);
2278 if (ret)
developerbe40a9e2024-03-07 21:44:26 +08002279 printf
2280 ("Failed to set /sys/devices/virtual/net/%s/brif/%s/multicast_router\n",
2281 BR_DEVNAME, ETH_DEVNAME);
developerfd40db22021-04-29 10:08:25 +08002282}
2283
2284void igmp_disable(int argc, char *argv[])
2285{
developerbe40a9e2024-03-07 21:44:26 +08002286 unsigned int reg_offset = 0, value = 0;
2287 int port_num = 0;
developerfd40db22021-04-29 10:08:25 +08002288
2289 if (argc < 4) {
2290 printf("insufficient arguments!\n");
2291 return;
2292 }
2293 port_num = strtoul(argv[3], NULL, 0);
2294 if (port_num < 0 || 6 < port_num) {
2295 printf("wrong port range, should be within 0~6\n");
2296 return;
2297 }
developerfd40db22021-04-29 10:08:25 +08002298 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2299 reg_offset = 0x2008;
2300 reg_offset |= (port_num << 8);
2301 value = 0x8000;
2302
2303 reg_write(reg_offset, value);
2304}
2305
2306void igmp_enable(int argc, char *argv[])
2307{
developerbe40a9e2024-03-07 21:44:26 +08002308 unsigned int reg_offset = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002309 int port_num;
2310
2311 if (argc < 4) {
2312 printf("insufficient arguments!\n");
2313 return;
2314 }
2315 port_num = strtoul(argv[3], NULL, 0);
2316 if (port_num < 0 || 6 < port_num) {
2317 printf("wrong port range, should be within 0~6\n");
2318 return;
2319 }
developerfd40db22021-04-29 10:08:25 +08002320 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2321 reg_offset = 0x2008;
2322 reg_offset |= (port_num << 8);
2323 value = 0x9755;
2324 reg_write(reg_offset, value);
2325}
2326
developerbe40a9e2024-03-07 21:44:26 +08002327void igmp_off(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002328{
developerbe40a9e2024-03-07 21:44:26 +08002329 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08002330 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2331 reg_read(REG_ISC_ADDR, &value);
developerbe40a9e2024-03-07 21:44:26 +08002332 value &= ~(1 << 18); //disable
developerfd40db22021-04-29 10:08:25 +08002333 reg_write(REG_ISC_ADDR, value);
2334
developerbe40a9e2024-03-07 21:44:26 +08002335 /*restore wan port multicast leaky vlan function: default disabled */
developerfd40db22021-04-29 10:08:25 +08002336 reg_read(0x2010, &value);
2337 reg_write(0x2010, value & (~(1 << 3)));
2338 reg_read(0x2410, &value);
2339 reg_write(0x2410, value & (~(1 << 3)));
2340
2341 printf("config igmpsnoop off.\n");
2342}
2343
developerbe40a9e2024-03-07 21:44:26 +08002344void switch_reset(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002345{
developer8c3871b2022-07-01 14:07:53 +08002346 if (chip_name == 0x7988)
developerbe40a9e2024-03-07 21:44:26 +08002347 return;
developer8c3871b2022-07-01 14:07:53 +08002348
developerfd40db22021-04-29 10:08:25 +08002349 unsigned int value = 0;
2350 /*Software Register Reset and Software System Reset */
2351 reg_write(0x7000, 0x3);
2352 reg_read(0x7000, &value);
2353 printf("SYS_CTRL(0x7000) register value =0x%x \n", value);
2354 if (chip_name == 0x7531) {
2355 reg_write(0x7c0c, 0x11111111);
2356 reg_read(0x7c0c, &value);
2357 printf("GPIO Mode (0x7c0c) select value =0x%x \n", value);
2358 }
2359 printf("Switch Software Reset !!! \n");
2360}
2361
developerbe40a9e2024-03-07 21:44:26 +08002362void phy_set_fc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002363{
developerbe40a9e2024-03-07 21:44:26 +08002364 unsigned int port = 0, pause_capable = 0;
2365 unsigned int phy_value = 0;
developerfd40db22021-04-29 10:08:25 +08002366
2367 port = atoi(argv[3]);
2368 pause_capable = atoi(argv[4]);
2369
developerbe40a9e2024-03-07 21:44:26 +08002370 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002371 if (port > MAX_PORT - 2 || pause_capable > 1) {
developerbe40a9e2024-03-07 21:44:26 +08002372 printf
2373 ("Illegal parameter (port:0~4, full_duplex_pause_capable:0|1)\n");
2374 return;
developerfd40db22021-04-29 10:08:25 +08002375 }
2376 printf("port=%d, full_duplex_pause_capable:%d\n", port, pause_capable);
developerbe40a9e2024-03-07 21:44:26 +08002377
developerfd40db22021-04-29 10:08:25 +08002378 mii_mgr_read(port, 4, &phy_value);
2379 printf("read phy_value:0x%x\r\n", phy_value);
2380 phy_value &= (~(0x1 << 10));
2381 phy_value &= (~(0x1 << 11));
2382 if (pause_capable == 1) {
2383 phy_value |= (0x1 << 10);
2384 phy_value |= (0x1 << 11);
2385 }
2386 mii_mgr_write(port, 4, phy_value);
2387 printf("write phy_value:0x%x\r\n", phy_value);
developerbe40a9e2024-03-07 21:44:26 +08002388 return;
2389} /*end phy_set_fc */
developerfd40db22021-04-29 10:08:25 +08002390
developerbe40a9e2024-03-07 21:44:26 +08002391void phy_set_an(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002392{
developerbe40a9e2024-03-07 21:44:26 +08002393 unsigned int port = 0, auto_negotiation_en = 0;
2394 unsigned int phy_value = 0;
developerfd40db22021-04-29 10:08:25 +08002395
2396 port = atoi(argv[3]);
2397 auto_negotiation_en = atoi(argv[4]);
2398
developerbe40a9e2024-03-07 21:44:26 +08002399 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002400 if (port > MAX_PORT - 2 || auto_negotiation_en > 1) {
developerbe40a9e2024-03-07 21:44:26 +08002401 printf
2402 ("Illegal parameter (port:0~4, auto_negotiation_en:0|1)\n");
2403 return;
developerfd40db22021-04-29 10:08:25 +08002404 }
2405 printf("port=%d, auto_negotiation_en:%d\n", port, auto_negotiation_en);
developerbe40a9e2024-03-07 21:44:26 +08002406
developerfd40db22021-04-29 10:08:25 +08002407 mii_mgr_read(port, 0, &phy_value);
2408 printf("read phy_value:0x%x\r\n", phy_value);
2409 phy_value &= (~(1 << 12));
2410 phy_value |= (auto_negotiation_en << 12);
2411 mii_mgr_write(port, 0, phy_value);
2412 printf("write phy_value:0x%x\r\n", phy_value);
developerbe40a9e2024-03-07 21:44:26 +08002413} /*end phy_set_an */
developerfd40db22021-04-29 10:08:25 +08002414
developerbe40a9e2024-03-07 21:44:26 +08002415void set_mac_pfc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002416{
developerbe40a9e2024-03-07 21:44:26 +08002417 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08002418 int port, enable = 0;
2419
2420 port = atoi(argv[3]);
2421 enable = atoi(argv[4]);
2422 printf("enable: %d\n", enable);
2423 if (port < 0 || port > 6 || enable < 0 || enable > 1) {
2424 printf("Illegal parameter (port:0~6, enable|diable:0|1) \n");
developerbe40a9e2024-03-07 21:44:26 +08002425 return;
developerfd40db22021-04-29 10:08:25 +08002426 }
developer8c3871b2022-07-01 14:07:53 +08002427 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002428 reg_read(REG_PFC_CTRL_ADDR, &value);
2429 value &= ~(1 << port);
2430 value |= (enable << port);
2431 printf("write reg: %x, value: %x\n", REG_PFC_CTRL_ADDR, value);
2432 reg_write(REG_PFC_CTRL_ADDR, value);
developerbe40a9e2024-03-07 21:44:26 +08002433 } else
developerfd40db22021-04-29 10:08:25 +08002434 printf("\nCommand not support by this chip.\n");
developerfd40db22021-04-29 10:08:25 +08002435}
2436
developerbe40a9e2024-03-07 21:44:26 +08002437void global_set_mac_fc(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002438{
2439 unsigned char enable = 0;
developerbe40a9e2024-03-07 21:44:26 +08002440 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08002441
2442 if (chip_name == 0x7530) {
2443 enable = atoi(argv[3]);
2444 printf("enable: %d\n", enable);
2445
developerbe40a9e2024-03-07 21:44:26 +08002446 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002447 if (enable > 1) {
2448 printf(HELP_MACCTL_FC);
developerbe40a9e2024-03-07 21:44:26 +08002449 return;
developerfd40db22021-04-29 10:08:25 +08002450 }
2451 reg_write(0x7000, 0x3);
2452 reg = REG_GFCCR0_ADDR;
2453 reg_read(REG_GFCCR0_ADDR, &value);
2454 value &= (~REG_FC_EN_MASK);
2455 value |= (enable << REG_FC_EN_OFFT);
2456 printf("write reg: %x, value: %x\n", reg, value);
2457 reg_write(REG_GFCCR0_ADDR, value);
2458 } else
2459 printf("\r\nCommand not support by this chip.\n");
developerbe40a9e2024-03-07 21:44:26 +08002460} /*end mac_set_fc */
developerfd40db22021-04-29 10:08:25 +08002461
developerbe40a9e2024-03-07 21:44:26 +08002462void qos_sch_select(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08002463{
developerbe40a9e2024-03-07 21:44:26 +08002464 unsigned char port = 0, queue = 0;
developerfd40db22021-04-29 10:08:25 +08002465 unsigned char type = 0;
developerbe40a9e2024-03-07 21:44:26 +08002466 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08002467
2468 if (argc < 7)
developerbe40a9e2024-03-07 21:44:26 +08002469 return;
developerfd40db22021-04-29 10:08:25 +08002470
2471 port = atoi(argv[3]);
2472 queue = atoi(argv[4]);
2473 type = atoi(argv[6]);
2474
2475 if (port > 6 || queue > 7) {
2476 printf("\n Illegal input parameters\n");
developerbe40a9e2024-03-07 21:44:26 +08002477 return;
developerfd40db22021-04-29 10:08:25 +08002478 }
2479
2480 if ((type != 0 && type != 1 && type != 2)) {
2481 printf(HELP_QOS_TYPE);
developerbe40a9e2024-03-07 21:44:26 +08002482 return;
developerfd40db22021-04-29 10:08:25 +08002483 }
2484
developerbe40a9e2024-03-07 21:44:26 +08002485 printf("\r\nswitch qos type: %d.\n", type);
developerfd40db22021-04-29 10:08:25 +08002486
2487 if (!strncmp(argv[5], "min", 4)) {
2488
2489 if (type == 0) {
developerbe40a9e2024-03-07 21:44:26 +08002490 /*min sharper-->round roubin, disable min sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002491 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2492 reg_read(reg, &value);
2493 value = 0x0;
2494 reg_write(reg, value);
2495 } else if (type == 1) {
developerbe40a9e2024-03-07 21:44:26 +08002496 /*min sharper-->sp, disable min sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002497 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2498 reg_read(reg, &value);
2499 value = 0x0;
2500 value |= (1 << 31);
2501 reg_write(reg, value);
2502 } else {
2503 printf("min sharper only support: rr or sp\n");
developerbe40a9e2024-03-07 21:44:26 +08002504 return;
developerfd40db22021-04-29 10:08:25 +08002505 }
2506 } else if (!strncmp(argv[5], "max", 4)) {
2507 if (type == 1) {
developerbe40a9e2024-03-07 21:44:26 +08002508 /*max sharper-->sp, disable max sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002509 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2510 reg_read(reg, &value);
2511 value = 0x0;
2512 value |= (1 << 31);
2513 reg_write(reg, value);
2514 } else if (type == 2) {
developerbe40a9e2024-03-07 21:44:26 +08002515 /*max sharper-->wfq, disable max sharper rate limit */
developerfd40db22021-04-29 10:08:25 +08002516 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2517 reg_read(reg, &value);
2518 value = 0x0;
2519 reg_write(reg, value);
2520 } else {
2521 printf("max sharper only support: wfq or sp\n");
developerbe40a9e2024-03-07 21:44:26 +08002522 return;
developerfd40db22021-04-29 10:08:25 +08002523 }
2524 } else {
developerbe40a9e2024-03-07 21:44:26 +08002525 printf("\r\nIllegal sharper:%s\n", argv[5]);
2526 return;
developerfd40db22021-04-29 10:08:25 +08002527 }
developerbe40a9e2024-03-07 21:44:26 +08002528 printf("reg:0x%x--value:0x%x\n", reg, value);
developerfd40db22021-04-29 10:08:25 +08002529}
2530
2531void get_upw(unsigned int *value, unsigned char base)
2532{
2533 *value &= (~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
2534 (0x7 << 16) | (0x7 << 20)));
developerbe40a9e2024-03-07 21:44:26 +08002535 switch (base) {
2536 case 0: /* port-based 0x2x40[18:16] */
2537 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2538 (0x2 << 12) | (0x7 << 16) | (0x2 << 20));
2539 break;
2540 case 1: /* tagged-based 0x2x40[10:8] */
2541 *value |= ((0x2 << 0) | (0x2 << 4) | (0x7 << 8) |
2542 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2543 break;
2544 case 2: /* DSCP-based 0x2x40[14:12] */
2545 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2546 (0x7 << 12) | (0x2 << 16) | (0x2 << 20));
2547 break;
2548 case 3: /* acl-based 0x2x40[2:0] */
2549 *value |= ((0x7 << 0) | (0x2 << 4) | (0x2 << 8) |
2550 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2551 break;
2552 case 4: /* arl-based 0x2x40[22:20] */
2553 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2554 (0x2 << 12) | (0x2 << 16) | (0x7 << 20));
2555 break;
2556 case 5: /* stag-based 0x2x40[6:4] */
2557 *value |= ((0x2 << 0) | (0x7 << 4) | (0x2 << 8) |
2558 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2559 break;
2560 default:
2561 break;
developerfd40db22021-04-29 10:08:25 +08002562 }
2563}
2564
2565void qos_set_base(int argc, char *argv[])
2566{
2567 unsigned char base = 0;
developerbe40a9e2024-03-07 21:44:26 +08002568 unsigned char port = 0;
2569 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08002570
2571 if (argc < 5)
2572 return;
2573
2574 port = atoi(argv[3]);
2575 base = atoi(argv[4]);
2576
2577 if (base > 6) {
2578 printf(HELP_QOS_BASE);
2579 return;
2580 }
2581
2582 if (port > 6) {
developerbe40a9e2024-03-07 21:44:26 +08002583 printf("Illegal port index:%d\n", port);
developerfd40db22021-04-29 10:08:25 +08002584 return;
2585 }
2586
2587 printf("\r\nswitch qos base : %d. (port-based:0, tag-based:1,\
developerbe40a9e2024-03-07 21:44:26 +08002588 dscp-based:2, acl-based:3, arl-based:4, stag-based:5)\n", base);
developerfd40db22021-04-29 10:08:25 +08002589 if (chip_name == 0x7530) {
2590
2591 reg_read(0x44, &value);
2592 get_upw(&value, base);
2593 reg_write(0x44, value);
2594 printf("reg: 0x44, value: 0x%x\n", value);
2595
developer8c3871b2022-07-01 14:07:53 +08002596 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002597
2598 reg_read(GSW_UPW(port), &value);
2599 get_upw(&value, base);
2600 reg_write(GSW_UPW(port), value);
developerbe40a9e2024-03-07 21:44:26 +08002601 printf("reg:0x%x, value: 0x%x\n", GSW_UPW(port), value);
developerfd40db22021-04-29 10:08:25 +08002602
2603 } else {
2604 printf("unknown switch device");
2605 return;
2606 }
2607}
2608
2609void qos_wfq_set_weight(int argc, char *argv[])
2610{
developerbe40a9e2024-03-07 21:44:26 +08002611 int port = 0, weight[8], i = 0;
2612 unsigned char queue = 0;
2613 unsigned int reg = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08002614
2615 port = atoi(argv[3]);
2616
2617 for (i = 0; i < 8; i++) {
2618 weight[i] = atoi(argv[i + 4]);
2619 }
2620
2621 /* MT7530 total 7 port */
2622 if (port < 0 || port > 6) {
2623 printf(HELP_QOS_PORT_WEIGHT);
2624 return;
2625 }
2626
2627 for (i = 0; i < 8; i++) {
2628 if (weight[i] < 1 || weight[i] > 16) {
2629 printf(HELP_QOS_PORT_WEIGHT);
2630 return;
2631 }
2632 }
2633 printf("port: %x, q0: %x, q1: %x, q2: %x, q3: %x, \
developerbe40a9e2024-03-07 21:44:26 +08002634 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 +08002635
2636 for (queue = 0; queue < 8; queue++) {
2637 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2638 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002639 value &= (~(0xf << 24)); //bit24~27
developerfd40db22021-04-29 10:08:25 +08002640 value |= (((weight[queue] - 1) & 0xf) << 24);
2641 printf("reg: %x, value: %x\n", reg, value);
2642 reg_write(reg, value);
2643 }
2644}
2645
2646void qos_set_portpri(int argc, char *argv[])
2647{
developerbe40a9e2024-03-07 21:44:26 +08002648 unsigned char port = 0, prio = 0;
2649 unsigned int value = 0;
developerfd40db22021-04-29 10:08:25 +08002650
2651 port = atoi(argv[3]);
2652 prio = atoi(argv[4]);
2653
2654 if (port >= 7 || prio > 7) {
2655 printf(HELP_QOS_PORT_PRIO);
2656 return;
2657 }
2658
2659 reg_read(GSW_PCR(port), &value);
2660 value &= (~(0x7 << 24));
2661 value |= (prio << 24);
2662 reg_write(GSW_PCR(port), value);
2663 printf("write reg: %x, value: %x\n", GSW_PCR(port), value);
2664}
2665
2666void qos_set_dscppri(int argc, char *argv[])
2667{
developerbe40a9e2024-03-07 21:44:26 +08002668 unsigned char prio = 0, dscp = 0, pim_n = 0, pim_offset = 0;
2669 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08002670
2671 dscp = atoi(argv[3]);
2672 prio = atoi(argv[4]);
2673
2674 if (dscp > 63 || prio > 7) {
2675 printf(HELP_QOS_DSCP_PRIO);
2676 return;
2677 }
2678
2679 pim_n = dscp / 10;
2680 pim_offset = (dscp - pim_n * 10) * 3;
2681 reg = 0x0058 + pim_n * 4;
2682 reg_read(reg, &value);
2683 value &= (~(0x7 << pim_offset));
2684 value |= ((prio & 0x7) << pim_offset);
2685 reg_write(reg, value);
2686 printf("write reg: %x, value: %x\n", reg, value);
2687}
2688
2689void qos_pri_mapping_queue(int argc, char *argv[])
2690{
developerbe40a9e2024-03-07 21:44:26 +08002691 unsigned char prio = 0, queue = 0, pem_n = 0, port = 0;
2692 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08002693
2694 if (argc < 6)
2695 return;
2696
2697 port = atoi(argv[3]);
2698 prio = atoi(argv[4]);
2699 queue = atoi(argv[5]);
2700
2701 if (prio > 7 || queue > 7) {
2702 printf(HELP_QOS_PRIO_QMAP);
2703 return;
2704 }
developerbe40a9e2024-03-07 21:44:26 +08002705
developerfd40db22021-04-29 10:08:25 +08002706 if (chip_name == 0x7530) {
2707 pem_n = prio / 2;
2708 reg = pem_n * 0x4 + 0x48;
2709 reg_read(reg, &value);
2710 if (prio % 2) {
2711 value &= (~(0x7 << 24));
2712 value |= ((queue & 0x7) << 24);
2713 } else {
2714 value &= (~(0x7 << 8));
2715 value |= ((queue & 0x7) << 8);
2716 }
2717 reg_write(reg, value);
2718 printf("write reg: %x, value: %x\n", reg, value);
developer8c3871b2022-07-01 14:07:53 +08002719 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08002720 pem_n = prio / 2;
2721 reg = GSW_PEM(pem_n) + 0x100 * port;
2722 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002723 if (prio % 2) { // 1 1
developerfd40db22021-04-29 10:08:25 +08002724 value &= (~(0x7 << 25));
2725 value |= ((queue & 0x7) << 25);
developerbe40a9e2024-03-07 21:44:26 +08002726 } else { // 0 0
developerfd40db22021-04-29 10:08:25 +08002727 value &= (~(0x7 << 9));
2728 value |= ((queue & 0x7) << 9);
2729 }
2730 reg_write(reg, value);
2731 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +08002732 } else {
developerfd40db22021-04-29 10:08:25 +08002733 printf("unknown switch device");
2734 return;
2735 }
2736}
2737
2738static int macMT753xVlanSetVid(unsigned char index, unsigned char active,
developerbe40a9e2024-03-07 21:44:26 +08002739 unsigned short vid, unsigned char portMap,
2740 unsigned char tagPortMap, unsigned char ivl_en,
2741 unsigned char fid, unsigned short stag)
developerfd40db22021-04-29 10:08:25 +08002742{
2743 unsigned int value = 0;
2744 unsigned int value2 = 0;
developerbe40a9e2024-03-07 21:44:26 +08002745 unsigned int reg = 0;
2746 int i = 0;
developerfd40db22021-04-29 10:08:25 +08002747
2748 printf("index: %x, active: %x, vid: %x, portMap: %x, \
developerbe40a9e2024-03-07 21:44:26 +08002749 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 +08002750
2751 value = (portMap << 16);
2752 value |= (stag << 4);
2753 value |= (ivl_en << 30);
2754 value |= (fid << 1);
2755 value |= (active ? 1 : 0);
2756
2757 // total 7 ports
2758 for (i = 0; i < 7; i++) {
2759 if (tagPortMap & (1 << i))
2760 value2 |= 0x2 << (i * 2);
2761 }
2762
2763 if (value2)
developerbe40a9e2024-03-07 21:44:26 +08002764 value |= (1 << 28); // eg_tag
developerfd40db22021-04-29 10:08:25 +08002765
developerbe40a9e2024-03-07 21:44:26 +08002766 reg = 0x98; // VAWD2
developerfd40db22021-04-29 10:08:25 +08002767 reg_write(reg, value2);
2768
developerbe40a9e2024-03-07 21:44:26 +08002769 reg = 0x94; // VAWD1
developerfd40db22021-04-29 10:08:25 +08002770 reg_write(reg, value);
2771
developerbe40a9e2024-03-07 21:44:26 +08002772 reg = 0x90; // VTCR
developerfd40db22021-04-29 10:08:25 +08002773 value = (0x80001000 + vid);
2774 reg_write(reg, value);
2775
developerbe40a9e2024-03-07 21:44:26 +08002776 reg = 0x90; // VTCR
developerfd40db22021-04-29 10:08:25 +08002777 while (1) {
2778 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08002779 if ((value & 0x80000000) == 0) //table busy
developerfd40db22021-04-29 10:08:25 +08002780 break;
2781 }
2782
2783 /* switch clear */
2784 reg = 0x80;
2785 reg_write(reg, 0x8002);
2786 usleep(5000);
2787 reg_read(reg, &value);
2788
2789 printf("SetVid: index:%d active:%d vid:%d portMap:%x tagPortMap:%x\r\n",
2790 index, active, vid, portMap, tagPortMap);
2791 return 0;
2792
developerbe40a9e2024-03-07 21:44:26 +08002793} /*end macMT753xVlanSetVid */
developerfd40db22021-04-29 10:08:25 +08002794
2795static int macMT753xVlanSetPvid(unsigned char port, unsigned short pvid)
2796{
developerbe40a9e2024-03-07 21:44:26 +08002797 unsigned int value = 0;
2798 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08002799
developerbe40a9e2024-03-07 21:44:26 +08002800 /*Parameters is error */
developerfd40db22021-04-29 10:08:25 +08002801 if (port > 6)
2802 return -1;
2803
2804 reg = 0x2014 + (port * 0x100);
2805 reg_read(reg, &value);
2806 value &= ~0xfff;
2807 value |= pvid;
2808 reg_write(reg, value);
2809
2810 /* switch clear */
2811 reg = 0x80;
2812 reg_write(reg, 0x8002);
2813 usleep(5000);
2814 reg_read(reg, &value);
2815
2816 printf("SetPVID: port:%d pvid:%d\r\n", port, pvid);
2817 return 0;
2818}
developerfd40db22021-04-29 10:08:25 +08002819
2820void doVlanSetPvid(int argc, char *argv[])
2821{
2822 unsigned char port = 0;
2823 unsigned short pvid = 0;
2824
2825 port = atoi(argv[3]);
2826 pvid = atoi(argv[4]);
developerbe40a9e2024-03-07 21:44:26 +08002827 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002828 if ((port >= SWITCH_MAX_PORT) || (pvid > MAX_VID_VALUE)) {
2829 printf(HELP_VLAN_PVID);
2830 return;
2831 }
2832
2833 macMT753xVlanSetPvid(port, pvid);
2834
2835 printf("port:%d pvid:%d,vlancap: max_port:%d maxvid:%d\r\n",
2836 port, pvid, SWITCH_MAX_PORT, MAX_VID_VALUE);
developerbe40a9e2024-03-07 21:44:26 +08002837} /*end doVlanSetPvid */
developerfd40db22021-04-29 10:08:25 +08002838
2839void doVlanSetVid(int argc, char *argv[])
2840{
2841 unsigned char index = 0;
2842 unsigned char active = 0;
2843 unsigned char portMap = 0;
2844 unsigned char tagPortMap = 0;
2845 unsigned short vid = 0;
2846
2847 unsigned char ivl_en = 0;
2848 unsigned char fid = 0;
2849 unsigned short stag = 0;
2850
2851 index = atoi(argv[3]);
2852 active = atoi(argv[4]);
2853 vid = atoi(argv[5]);
2854
developerbe40a9e2024-03-07 21:44:26 +08002855 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002856 if ((index >= MAX_VLAN_RULE) || (vid >= 4096) || (active > ACTIVED)) {
2857 printf(HELP_VLAN_VID);
2858 return;
2859 }
2860
developerbe40a9e2024-03-07 21:44:26 +08002861 /*CPU Port is always the membership */
developerfd40db22021-04-29 10:08:25 +08002862 portMap = atoi(argv[6]);
2863 tagPortMap = atoi(argv[7]);
2864
2865 printf("subcmd parameter argc = %d\r\n", argc);
2866 if (argc >= 9) {
2867 ivl_en = atoi(argv[8]);
2868 if (argc >= 10) {
2869 fid = atoi(argv[9]);
2870 if (argc >= 11)
2871 stag = atoi(argv[10]);
2872 }
2873 }
2874 macMT753xVlanSetVid(index, active, vid, portMap, tagPortMap,
2875 ivl_en, fid, stag);
2876 printf("index:%d active:%d vid:%d\r\n", index, active, vid);
developerbe40a9e2024-03-07 21:44:26 +08002877} /*end doVlanSetVid */
developerfd40db22021-04-29 10:08:25 +08002878
2879void doVlanSetAccFrm(int argc, char *argv[])
2880{
2881 unsigned char port = 0;
2882 unsigned char type = 0;
developerbe40a9e2024-03-07 21:44:26 +08002883 unsigned int value = 0;
2884 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08002885
2886 port = atoi(argv[3]);
2887 type = atoi(argv[4]);
2888
2889 printf("port: %d, type: %d\n", port, type);
2890
developerbe40a9e2024-03-07 21:44:26 +08002891 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002892 if ((port > SWITCH_MAX_PORT) || (type > REG_PVC_ACC_FRM_RELMASK)) {
2893 printf(HELP_VLAN_ACC_FRM);
2894 return;
2895 }
2896
2897 reg = REG_PVC_P0_ADDR + port * 0x100;
2898 reg_read(reg, &value);
2899 value &= (~REG_PVC_ACC_FRM_MASK);
2900 value |= ((unsigned int)type << REG_PVC_ACC_FRM_OFFT);
2901
2902 printf("write reg: %x, value: %x\n", reg, value);
2903 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08002904} /*end doVlanSetAccFrm */
developerfd40db22021-04-29 10:08:25 +08002905
2906void doVlanSetPortAttr(int argc, char *argv[])
2907{
2908 unsigned char port = 0;
2909 unsigned char attr = 0;
developerbe40a9e2024-03-07 21:44:26 +08002910 unsigned int value = 0;
2911 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08002912
2913 port = atoi(argv[3]);
2914 attr = atoi(argv[4]);
2915
2916 printf("port: %x, attr: %x\n", port, attr);
2917
developerbe40a9e2024-03-07 21:44:26 +08002918 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002919 if (port > SWITCH_MAX_PORT || attr > 3) {
2920 printf(HELP_VLAN_PORT_ATTR);
2921 return;
2922 }
2923
2924 reg = 0x2010 + port * 0x100;
2925 reg_read(reg, &value);
2926 value &= (0xffffff3f);
2927 value |= (attr << 6);
2928
2929 printf("write reg: %x, value: %x\n", reg, value);
2930 reg_write(reg, value);
2931}
2932
2933void doVlanSetPortMode(int argc, char *argv[])
2934{
2935 unsigned char port = 0;
2936 unsigned char mode = 0;
developerbe40a9e2024-03-07 21:44:26 +08002937 unsigned int value = 0;
2938 unsigned int reg = 0;
2939
developerfd40db22021-04-29 10:08:25 +08002940 port = atoi(argv[3]);
2941 mode = atoi(argv[4]);
2942 printf("port: %x, mode: %x\n", port, mode);
2943
developerbe40a9e2024-03-07 21:44:26 +08002944 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002945 if (port > SWITCH_MAX_PORT || mode > 3) {
2946 printf(HELP_VLAN_PORT_MODE);
2947 return;
2948 }
2949
2950 reg = 0x2004 + port * 0x100;
2951 reg_read(reg, &value);
2952 value &= (~((1 << 0) | (1 << 1)));
2953 value |= (mode & 0x3);
2954 printf("write reg: %x, value: %x\n", reg, value);
2955 reg_write(reg, value);
2956}
2957
2958void doVlanSetEgressTagPCR(int argc, char *argv[])
2959{
2960 unsigned char port = 0;
2961 unsigned char eg_tag = 0;
developerbe40a9e2024-03-07 21:44:26 +08002962 unsigned int value = 0;
2963 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08002964
2965 port = atoi(argv[3]);
2966 eg_tag = atoi(argv[4]);
2967
2968 printf("port: %d, eg_tag: %d\n", port, eg_tag);
2969
developerbe40a9e2024-03-07 21:44:26 +08002970 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002971 if ((port > SWITCH_MAX_PORT) || (eg_tag > REG_PCR_EG_TAG_RELMASK)) {
2972 printf(HELP_VLAN_EGRESS_TAG_PCR);
2973 return;
2974 }
2975
2976 reg = REG_PCR_P0_ADDR + port * 0x100;
2977 reg_read(reg, &value);
2978 value &= (~REG_PCR_EG_TAG_MASK);
2979 value |= ((unsigned int)eg_tag << REG_PCR_EG_TAG_OFFT);
2980
2981 printf("write reg: %x, value: %x\n", reg, value);
2982 reg_write(reg, value);
2983
developerbe40a9e2024-03-07 21:44:26 +08002984} /*end doVlanSetEgressTagPCR */
developerfd40db22021-04-29 10:08:25 +08002985
2986void doVlanSetEgressTagPVC(int argc, char *argv[])
2987{
2988 unsigned char port = 0;
2989 unsigned char eg_tag = 0;
developerbe40a9e2024-03-07 21:44:26 +08002990 unsigned int value = 0;
2991 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08002992
2993 port = atoi(argv[3]);
2994 eg_tag = atoi(argv[4]);
2995
2996 printf("port: %d, eg_tag: %d\n", port, eg_tag);
2997
developerbe40a9e2024-03-07 21:44:26 +08002998 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08002999 if ((port > SWITCH_MAX_PORT) || (eg_tag > REG_PVC_EG_TAG_RELMASK)) {
3000 printf(HELP_VLAN_EGRESS_TAG_PVC);
3001 return;
3002 }
3003
3004 reg = REG_PVC_P0_ADDR + port * 0x100;
3005 reg_read(reg, &value);
3006 value &= (~REG_PVC_EG_TAG_MASK);
3007 value |= ((unsigned int)eg_tag << REG_PVC_EG_TAG_OFFT);
3008
3009 printf("write reg: %x, value: %x\n", reg, value);
3010 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003011} /*end doVlanSetEgressTagPVC */
developerfd40db22021-04-29 10:08:25 +08003012
3013void doArlAging(int argc, char *argv[])
3014{
3015 unsigned char aging_en = 0;
developerbe40a9e2024-03-07 21:44:26 +08003016 unsigned int time = 0, aging_cnt = 0, aging_unit = 0, value = 0, reg =
3017 0;
developerfd40db22021-04-29 10:08:25 +08003018
3019 aging_en = atoi(argv[3]);
3020 time = atoi(argv[4]);
3021 printf("aging_en: %x, aging time: %x\n", aging_en, time);
3022
developerbe40a9e2024-03-07 21:44:26 +08003023 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003024 if ((aging_en != 0 && aging_en != 1) || (time <= 0 || time > 65536)) {
3025 printf(HELP_ARL_AGING);
3026 return;
3027 }
3028
3029 reg = 0xa0;
3030 reg_read(reg, &value);
3031 value &= (~(1 << 20));
3032 if (!aging_en) {
3033 value |= (1 << 20);
3034 }
3035
3036 aging_unit = (time / 0x100) + 1;
3037 aging_cnt = (time / aging_unit);
3038 aging_unit--;
3039 aging_cnt--;
3040
3041 value &= (0xfff00000);
3042 value |= ((aging_cnt << 12) | aging_unit);
3043
3044 printf("aging_unit: %x, aging_cnt: %x\n", aging_unit, aging_cnt);
3045 printf("write reg: %x, value: %x\n", reg, value);
3046
3047 reg_write(reg, value);
3048}
3049
3050void doMirrorEn(int argc, char *argv[])
3051{
developerbe40a9e2024-03-07 21:44:26 +08003052 unsigned char mirror_en = 0;
3053 unsigned char mirror_port = 0;
3054 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003055
3056 mirror_en = atoi(argv[3]);
3057 mirror_port = atoi(argv[4]);
3058
3059 printf("mirror_en: %d, mirror_port: %d\n", mirror_en, mirror_port);
3060
developerbe40a9e2024-03-07 21:44:26 +08003061 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003062 if ((mirror_en > 1) || (mirror_port > REG_CFC_MIRROR_PORT_RELMASK)) {
3063 printf(HELP_MIRROR_EN);
3064 return;
3065 }
3066
3067 reg = REG_CFC_ADDR;
3068 reg_read(reg, &value);
3069 value &= (~REG_CFC_MIRROR_EN_MASK);
3070 value |= (mirror_en << REG_CFC_MIRROR_EN_OFFT);
3071 value &= (~REG_CFC_MIRROR_PORT_MASK);
3072 value |= (mirror_port << REG_CFC_MIRROR_PORT_OFFT);
3073
3074 printf("write reg: %x, value: %x\n", reg, value);
3075 reg_write(reg, value);
3076
developerbe40a9e2024-03-07 21:44:26 +08003077} /*end doMirrorEn */
developerfd40db22021-04-29 10:08:25 +08003078
3079void doMirrorPortBased(int argc, char *argv[])
3080{
developerbe40a9e2024-03-07 21:44:26 +08003081 unsigned char port = 0, port_tx_mir = 0, port_rx_mir = 0, vlan_mis =
3082 0, acl_mir = 0, igmp_mir = 0;
3083 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003084
3085 port = atoi(argv[3]);
3086 port_tx_mir = atoi(argv[4]);
3087 port_rx_mir = atoi(argv[5]);
3088 acl_mir = atoi(argv[6]);
3089 vlan_mis = atoi(argv[7]);
3090 igmp_mir = atoi(argv[8]);
3091
developerbe40a9e2024-03-07 21:44:26 +08003092 printf
3093 ("port:%d, port_tx_mir:%d, port_rx_mir:%d, acl_mir:%d, vlan_mis:%d, igmp_mir:%d\n",
3094 port, port_tx_mir, port_rx_mir, acl_mir, vlan_mis, igmp_mir);
developerfd40db22021-04-29 10:08:25 +08003095
developerbe40a9e2024-03-07 21:44:26 +08003096 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003097 //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 +08003098 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 +08003099 printf(HELP_MIRROR_PORTBASED);
3100 return;
3101 }
3102
3103 reg = REG_PCR_P0_ADDR + port * 0x100;
3104 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003105 value &=
3106 ~(REG_PORT_TX_MIR_MASK | REG_PORT_RX_MIR_MASK | REG_PCR_ACL_MIR_MASK
3107 | REG_PCR_VLAN_MIS_MASK);
3108 value |=
3109 (port_tx_mir << REG_PORT_TX_MIR_OFFT) +
3110 (port_rx_mir << REG_PORT_RX_MIR_OFFT);
3111 value |=
3112 (acl_mir << REG_PCR_ACL_MIR_OFFT) +
3113 (vlan_mis << REG_PCR_VLAN_MIS_OFFT);
developerfd40db22021-04-29 10:08:25 +08003114
3115 printf("write reg: %x, value: %x\n", reg, value);
3116 reg_write(reg, value);
3117
3118 reg = REG_PIC_P0_ADDR + port * 0x100;
3119 reg_read(reg, &value);
3120 value &= ~(REG_PIC_IGMP_MIR_MASK);
3121 value |= (igmp_mir << REG_PIC_IGMP_MIR_OFFT);
3122
3123 printf("write reg: %x, value: %x\n", reg, value);
3124 reg_write(reg, value);
3125
developerbe40a9e2024-03-07 21:44:26 +08003126} /*end doMirrorPortBased */
developerfd40db22021-04-29 10:08:25 +08003127
3128void doStp(int argc, char *argv[])
3129{
3130 unsigned char port = 0;
3131 unsigned char fid = 0;
3132 unsigned char state = 0;
developerbe40a9e2024-03-07 21:44:26 +08003133 unsigned int value = 0;
3134 unsigned int reg = 0;
developerfd40db22021-04-29 10:08:25 +08003135
3136 port = atoi(argv[2]);
3137 fid = atoi(argv[3]);
3138 state = atoi(argv[4]);
3139
3140 printf("port: %d, fid: %d, state: %d\n", port, fid, state);
3141
developerbe40a9e2024-03-07 21:44:26 +08003142 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003143 if ((port > MAX_PORT + 1) || (fid > 7) || (state > 3)) {
3144 printf(HELP_STP);
3145 return;
3146 }
3147
3148 reg = REG_SSC_P0_ADDR + port * 0x100;
3149 reg_read(reg, &value);
3150 value &= (~(3 << (fid << 2)));
3151 value |= ((unsigned int)state << (fid << 2));
3152
3153 printf("write reg: %x, value: %x\n", reg, value);
3154 reg_write(reg, value);
3155}
3156
developerbe40a9e2024-03-07 21:44:26 +08003157void _ingress_rate_set(int on_off, int port, int bw)
developerfd40db22021-04-29 10:08:25 +08003158{
developerbe40a9e2024-03-07 21:44:26 +08003159 unsigned int reg = 0, value = 0;
developerfd40db22021-04-29 10:08:25 +08003160
3161 reg = 0x1800 + (0x100 * port);
3162 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08003163 /*token-bucket */
developerfd40db22021-04-29 10:08:25 +08003164 if (on_off == 1) {
3165 if (chip_name == 0x7530) {
3166 if (bw > 1000000) {
developerbe40a9e2024-03-07 21:44:26 +08003167 printf
3168 ("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",
3169 bw);
3170 return;
developerfd40db22021-04-29 10:08:25 +08003171 }
developerbe40a9e2024-03-07 21:44:26 +08003172 value =
3173 ((bw / 32) << 16) + (1 << 15) + (7 << 8) +
3174 (1 << 7) + 0x0f;
developer8c3871b2022-07-01 14:07:53 +08003175 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3176 if ((chip_name == 0x7531) && (bw > 2500000)) {
developerbe40a9e2024-03-07 21:44:26 +08003177 printf
3178 ("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",
3179 bw);
3180 return;
developerfd40db22021-04-29 10:08:25 +08003181 }
developer8c3871b2022-07-01 14:07:53 +08003182
3183 if ((chip_name == 0x7988) && (bw > 4000000)) {
developerbe40a9e2024-03-07 21:44:26 +08003184 printf
3185 ("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",
3186 bw);
3187 return;
developerfd40db22021-04-29 10:08:25 +08003188 }
developer8c3871b2022-07-01 14:07:53 +08003189
developerbe40a9e2024-03-07 21:44:26 +08003190 if (bw / 32 >= 65536) //supoort 2.5G case
3191 value =
3192 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3193 (1 << 12) + (7 << 8) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003194 else
developerbe40a9e2024-03-07 21:44:26 +08003195 value =
3196 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3197 (7 << 8) + 0xf;
3198 } else
developerfd40db22021-04-29 10:08:25 +08003199 printf("unknow chip\n");
3200 }
developerfd40db22021-04-29 10:08:25 +08003201#if leaky_bucket
3202 reg_read(reg, &value);
3203 value &= 0xffff0000;
developerbe40a9e2024-03-07 21:44:26 +08003204 if (on_off == 1) {
developerfd40db22021-04-29 10:08:25 +08003205 value |= on_off << 15;
3206 //7530 same as 7531
3207 if (bw < 100) {
3208 value |= (0x0 << 8);
3209 value |= bw;
3210 } else if (bw < 1000) {
3211 value |= (0x1 << 8);
3212 value |= bw / 10;
3213 } else if (bw < 10000) {
3214 value |= (0x2 << 8);
3215 value |= bw / 100;
3216 } else if (bw < 100000) {
3217 value |= (0x3 << 8);
3218 value |= bw / 1000;
3219 } else {
3220 value |= (0x4 << 8);
3221 value |= bw / 10000;
3222 }
3223 }
3224#endif
3225 reg_write(reg, value);
3226 reg = 0x1FFC;
3227 reg_read(reg, &value);
3228 value = 0x110104;
3229 reg_write(reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003230
3231 if (on_off)
3232 printf("switch port=%d, bw=%d\n", port, bw);
3233 else
3234 printf("switch port=%d ingress rate limit off\n", port);
developerfd40db22021-04-29 10:08:25 +08003235}
3236
developerbe40a9e2024-03-07 21:44:26 +08003237void ingress_rate_set(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003238{
developerbe40a9e2024-03-07 21:44:26 +08003239 int on_off = 0, port = 0, bw = 0;
developer997ed6b2024-03-26 14:03:42 +08003240 char *endptr;
developerbe40a9e2024-03-07 21:44:26 +08003241
developer997ed6b2024-03-26 14:03:42 +08003242 /* clear errno before conversion to detect overflow */
3243 errno = 0;
3244 port = strtoul(argv[3], &endptr, 0);
3245
3246 if (errno == ERANGE) {
3247 printf("Conversion error, value out of range\n");
3248 return;
3249 }
3250 if (*endptr != '\0') {
3251 printf("Conversion error, no digits were found\n");
3252 return;
3253 }
3254
3255 if (port < 0 || port > 6) {
3256 printf("Wrong port range, should be within 0-6\n");
3257 return;
3258 }
3259
developerbe40a9e2024-03-07 21:44:26 +08003260 if (argv[2][1] == 'n') {
developer997ed6b2024-03-26 14:03:42 +08003261 errno = 0;
3262 bw = strtoul(argv[4], &endptr, 0);
3263 if (errno == ERANGE) {
3264 printf("Conversion error, value out of range\n");
3265 return;
3266 }
3267 if (*endptr != '\0') {
3268 printf("Conversion error, no digits were found\n");
3269 return;
3270 }
developerbe40a9e2024-03-07 21:44:26 +08003271 on_off = 1;
3272 } else if (argv[2][1] == 'f') {
3273 if (argc != 4)
3274 return;
3275 on_off = 0;
3276 }
3277
3278 _ingress_rate_set(on_off, port, bw);
3279}
3280
3281void _egress_rate_set(int on_off, int port, int bw)
3282{
3283 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003284
3285 reg = 0x1040 + (0x100 * port);
3286 value = 0;
developerbe40a9e2024-03-07 21:44:26 +08003287 /*token-bucket */
developerfd40db22021-04-29 10:08:25 +08003288 if (on_off == 1) {
3289 if (chip_name == 0x7530) {
3290 if (bw < 0 || bw > 1000000) {
developerbe40a9e2024-03-07 21:44:26 +08003291 printf
3292 ("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",
3293 bw);
3294 return;
developerfd40db22021-04-29 10:08:25 +08003295 }
developerbe40a9e2024-03-07 21:44:26 +08003296 value =
3297 ((bw / 32) << 16) + (1 << 15) + (7 << 8) +
3298 (1 << 7) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003299 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3300 if ((chip_name == 0x7531) && (bw < 0 || bw > 2500000)) {
developerbe40a9e2024-03-07 21:44:26 +08003301 printf
3302 ("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",
3303 bw);
3304 return;
developerfd40db22021-04-29 10:08:25 +08003305 }
developer8c3871b2022-07-01 14:07:53 +08003306 if ((chip_name == 0x7988) && (bw < 0 || bw > 4000000)) {
developerbe40a9e2024-03-07 21:44:26 +08003307 printf
3308 ("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",
3309 bw);
3310 return;
developer8c3871b2022-07-01 14:07:53 +08003311 }
3312
developerbe40a9e2024-03-07 21:44:26 +08003313 if (bw / 32 >= 65536) //support 2.5G cases
3314 value =
3315 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3316 (1 << 12) + (7 << 8) + 0xf;
developer8c3871b2022-07-01 14:07:53 +08003317 else
developerbe40a9e2024-03-07 21:44:26 +08003318 value =
3319 ((bw / 32) << 16) + (1 << 15) + (1 << 14) +
3320 (7 << 8) + 0xf;
3321 } else
developerfd40db22021-04-29 10:08:25 +08003322 printf("unknow chip\n");
3323 }
3324 reg_write(reg, value);
3325 reg = 0x10E0;
3326 reg_read(reg, &value);
3327 value &= 0x18;
3328 reg_write(reg, value);
3329
developerbe40a9e2024-03-07 21:44:26 +08003330 if (on_off)
3331 printf("switch port=%d, bw=%d\n", port, bw);
3332 else
3333 printf("switch port=%d egress rate limit off\n", port);
3334}
3335
3336void egress_rate_set(int argc, char *argv[])
3337{
3338 unsigned int value = 0, reg = 0;
3339 int on_off = 0, port = 0, bw = 0;
developer997ed6b2024-03-26 14:03:42 +08003340 char *endptr;
developerbe40a9e2024-03-07 21:44:26 +08003341
developer997ed6b2024-03-26 14:03:42 +08003342 /* clear errno before conversion to detect overflow */
3343 errno = 0;
3344 port = strtoul(argv[3], &endptr, 0);
3345 if (errno == ERANGE) {
3346 printf("Conversion error, value out of range\n");
3347 return;
3348 }
3349 if (*endptr != '\0') {
3350 printf("Conversion error, no digits were found\n");
3351 return;
3352 }
3353 if (port < 0 || port > 6) {
3354 printf("Wrong port range, should be within 0-6\n");
3355 return;
3356 }
developerbe40a9e2024-03-07 21:44:26 +08003357 if (argv[2][1] == 'n') {
developer997ed6b2024-03-26 14:03:42 +08003358 errno = 0;
3359 bw = strtoul(argv[4], &endptr, 0);
3360 if (errno == ERANGE) {
3361 printf("Conversion error, value out of range\n");
3362 return;
3363 }
3364 if (*endptr != '\0') {
3365 printf("Conversion error, no digits were found\n");
3366 return;
3367 }
developerbe40a9e2024-03-07 21:44:26 +08003368 on_off = 1;
3369 } else if (argv[2][1] == 'f') {
3370 if (argc != 4)
3371 return;
3372 on_off = 0;
3373 }
3374
3375 _egress_rate_set(on_off, port, bw);
developerfd40db22021-04-29 10:08:25 +08003376}
3377
3378void rate_control(int argc, char *argv[])
3379{
3380 unsigned char dir = 0;
3381 unsigned char port = 0;
3382 unsigned int rate = 0;
3383
3384 dir = atoi(argv[2]);
3385 port = atoi(argv[3]);
3386 rate = atoi(argv[4]);
3387
3388 if (port > 6)
3389 return;
3390
developerbe40a9e2024-03-07 21:44:26 +08003391 if (dir == 1) //ingress
3392 _ingress_rate_set(1, port, rate);
3393 else if (dir == 0) //egress
3394 _egress_rate_set(1, port, rate);
developerfd40db22021-04-29 10:08:25 +08003395 else
3396 return;
3397}
3398
developerbe40a9e2024-03-07 21:44:26 +08003399void collision_pool_enable(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003400{
3401
developerbe40a9e2024-03-07 21:44:26 +08003402 unsigned char enable = 0;
3403 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003404
3405 enable = atoi(argv[3]);
3406
developerfd40db22021-04-29 10:08:25 +08003407 printf("collision pool enable: %d \n", enable);
3408
developerbe40a9e2024-03-07 21:44:26 +08003409 /*Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003410 if (enable > 1) {
3411 printf(HELP_COLLISION_POOL_EN);
developerbe40a9e2024-03-07 21:44:26 +08003412 return;
developerfd40db22021-04-29 10:08:25 +08003413 }
3414
developer8c3871b2022-07-01 14:07:53 +08003415 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003416 reg = REG_CPGC_ADDR;
developerbe40a9e2024-03-07 21:44:26 +08003417 if (enable == 1) {
developerfd40db22021-04-29 10:08:25 +08003418 /* active reset */
3419 reg_read(reg, &value);
3420 value &= (~REG_CPCG_COL_RST_N_MASK);
3421 reg_write(reg, value);
3422
3423 /* enanble clock */
3424 reg_read(reg, &value);
3425 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3426 value |= (1 << REG_CPCG_COL_CLK_EN_OFFT);
3427 reg_write(reg, value);
3428
3429 /* inactive reset */
3430 reg_read(reg, &value);
3431 value &= (~REG_CPCG_COL_RST_N_MASK);
3432 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3433 reg_write(reg, value);
3434
3435 /* enable collision pool */
3436 reg_read(reg, &value);
3437 value &= (~REG_CPCG_COL_EN_MASK);
3438 value |= (1 << REG_CPCG_COL_EN_OFFT);
3439 reg_write(reg, value);
3440
3441 reg_read(reg, &value);
3442 printf("write reg: %x, value: %x\n", reg, value);
developerbe40a9e2024-03-07 21:44:26 +08003443 } else {
developerfd40db22021-04-29 10:08:25 +08003444
3445 /* disable collision pool */
3446 reg_read(reg, &value);
3447 value &= (~REG_CPCG_COL_EN_MASK);
3448 reg_write(reg, value);
3449
3450 /* active reset */
3451 reg_read(reg, &value);
3452 value &= (~REG_CPCG_COL_RST_N_MASK);
3453 reg_write(reg, value);
3454
3455 /* inactive reset */
3456 reg_read(reg, &value);
3457 value &= (~REG_CPCG_COL_RST_N_MASK);
3458 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3459 reg_write(reg, value);
3460
3461 /* disable clock */
3462 reg_read(reg, &value);
3463 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3464 reg_write(reg, value);
3465
3466 reg_read(reg, &value);
3467 printf("write reg: %x, value: %x\n", reg, value);
3468
3469 }
developerbe40a9e2024-03-07 21:44:26 +08003470 } else {
developerfd40db22021-04-29 10:08:25 +08003471 printf("\nCommand not support by this chip.\n");
developerbe40a9e2024-03-07 21:44:26 +08003472 }
developerfd40db22021-04-29 10:08:25 +08003473}
3474
developerbe40a9e2024-03-07 21:44:26 +08003475void collision_pool_mac_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003476{
developerbe40a9e2024-03-07 21:44:26 +08003477 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003478
developer8c3871b2022-07-01 14:07:53 +08003479 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003480 reg = REG_CPGC_ADDR;
3481 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003482 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003483 table_dump_internal(COLLISION_TABLE);
3484 else
developerbe40a9e2024-03-07 21:44:26 +08003485 printf
3486 ("\ncollision pool is disabled, please enable it before use this command.\n");
3487 } else {
developerfd40db22021-04-29 10:08:25 +08003488 printf("\nCommand not support by this chip.\n");
3489 }
3490}
3491
developerbe40a9e2024-03-07 21:44:26 +08003492void collision_pool_dip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003493{
developerbe40a9e2024-03-07 21:44:26 +08003494 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003495
developer8c3871b2022-07-01 14:07:53 +08003496 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003497 reg = REG_CPGC_ADDR;
3498 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003499 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003500 dip_dump_internal(COLLISION_TABLE);
3501 else
developerbe40a9e2024-03-07 21:44:26 +08003502 printf
3503 ("\ncollision pool is disabled, please enable it before use this command.\n");
3504 } else {
developerfd40db22021-04-29 10:08:25 +08003505 printf("\nCommand not support by this chip.\n");
3506 }
developerfd40db22021-04-29 10:08:25 +08003507}
3508
developerbe40a9e2024-03-07 21:44:26 +08003509void collision_pool_sip_dump(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003510{
developerbe40a9e2024-03-07 21:44:26 +08003511 unsigned int value = 0, reg = 0;
developerfd40db22021-04-29 10:08:25 +08003512
developerbe40a9e2024-03-07 21:44:26 +08003513 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003514 reg = REG_CPGC_ADDR;
3515 reg_read(reg, &value);
developerbe40a9e2024-03-07 21:44:26 +08003516 if (value & REG_CPCG_COL_EN_MASK)
developerfd40db22021-04-29 10:08:25 +08003517 sip_dump_internal(COLLISION_TABLE);
3518 else
developerbe40a9e2024-03-07 21:44:26 +08003519 printf
3520 ("\ncollision pool is disabled, please enable it before use this command.\n");
3521 } else {
developerfd40db22021-04-29 10:08:25 +08003522 printf("\nCommand not support by this chip.\n");
3523 }
developerfd40db22021-04-29 10:08:25 +08003524}
3525
3526void pfc_get_rx_counter(int argc, char *argv[])
3527{
developerbe40a9e2024-03-07 21:44:26 +08003528 int port = 0;
3529 unsigned int value = 0, reg = 0;
3530 unsigned int user_pri = 0;
developerfd40db22021-04-29 10:08:25 +08003531
3532 port = strtoul(argv[3], NULL, 0);
3533 if (port < 0 || 6 < port) {
3534 printf("wrong port range, should be within 0~6\n");
3535 return;
3536 }
3537
developerbe40a9e2024-03-07 21:44:26 +08003538 if (chip_name == 0x7531 || chip_name == 0x7988) {
3539 reg = PFC_RX_COUNTER_L(port);
developerfd40db22021-04-29 10:08:25 +08003540 reg_read(reg, &value);
3541 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003542 printf("\n port %d rx pfc (up=0)pause on counter is %d.\n",
3543 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003544 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003545 printf("\n port %d rx pfc (up=1)pause on counter is %d.\n",
3546 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003547 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003548 printf("\n port %d rx pfc (up=2)pause on counter is %d.\n",
3549 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003550 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003551 printf("\n port %d rx pfc (up=3)pause on counter is %d.\n",
3552 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003553
developerbe40a9e2024-03-07 21:44:26 +08003554 reg = PFC_RX_COUNTER_H(port);
developerfd40db22021-04-29 10:08:25 +08003555 reg_read(reg, &value);
3556 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003557 printf("\n port %d rx pfc (up=4)pause on counter is %d.\n",
3558 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003559 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003560 printf("\n port %d rx pfc (up=5)pause on counter is %d.\n",
3561 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003562 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003563 printf("\n port %d rx pfc (up=6)pause on counter is %d.\n",
3564 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003565 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003566 printf("\n port %d rx pfc (up=7)pause on counter is %d.\n",
3567 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003568
3569 /* for rx counter could be updated successfully */
3570 reg_read(PMSR_P(port), &value);
3571 reg_read(PMSR_P(port), &value);
developerbe40a9e2024-03-07 21:44:26 +08003572 } else {
developerfd40db22021-04-29 10:08:25 +08003573 printf("\nCommand not support by this chip.\n");
3574 }
3575
3576}
3577
3578void pfc_get_tx_counter(int argc, char *argv[])
3579{
developerbe40a9e2024-03-07 21:44:26 +08003580 int port = 0;
3581 unsigned int value = 0, reg = 0;
3582 unsigned int user_pri = 0;
developerfd40db22021-04-29 10:08:25 +08003583
3584 port = strtoul(argv[3], NULL, 0);
3585 if (port < 0 || 6 < port) {
3586 printf("wrong port range, should be within 0~6\n");
3587 return;
3588 }
3589
developer8c3871b2022-07-01 14:07:53 +08003590 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerbe40a9e2024-03-07 21:44:26 +08003591 reg = PFC_TX_COUNTER_L(port);
developerfd40db22021-04-29 10:08:25 +08003592 reg_read(reg, &value);
3593 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003594 printf("\n port %d tx pfc (up=0)pause on counter is %d.\n",
3595 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003596 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003597 printf("\n port %d tx pfc (up=1)pause on counter is %d.\n",
3598 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003599 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003600 printf("\n port %d tx pfc (up=2)pause on counter is %d.\n",
3601 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003602 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003603 printf("\n port %d tx pfc (up=3)pause on counter is %d.\n",
3604 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003605
developerbe40a9e2024-03-07 21:44:26 +08003606 reg = PFC_TX_COUNTER_H(port);
developerfd40db22021-04-29 10:08:25 +08003607 reg_read(reg, &value);
3608 user_pri = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003609 printf("\n port %d tx pfc (up=4)pause on counter is %d.\n",
3610 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003611 user_pri = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003612 printf("\n port %d tx pfc (up=5)pause on counter is %d.\n",
3613 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003614 user_pri = (value & 0xff0000) >> 16;
developerbe40a9e2024-03-07 21:44:26 +08003615 printf("\n port %d tx pfc (up=6)pause on counter is %d.\n",
3616 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003617 user_pri = (value & 0xff000000) >> 24;
developerbe40a9e2024-03-07 21:44:26 +08003618 printf("\n port %d tx pfc (up=7)pause on counter is %d.\n",
3619 port, user_pri);
developerfd40db22021-04-29 10:08:25 +08003620
3621 /* for tx counter could be updated successfully */
3622 reg_read(PMSR_P(port), &value);
3623 reg_read(PMSR_P(port), &value);
developerbe40a9e2024-03-07 21:44:26 +08003624 } else {
3625 printf("\nCommand not support by this chip.\n");
developerfd40db22021-04-29 10:08:25 +08003626 }
3627}
3628
developerbe40a9e2024-03-07 21:44:26 +08003629void read_output_queue_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003630{
developerbe40a9e2024-03-07 21:44:26 +08003631 unsigned int port = 0;
3632 unsigned int value = 0, output_queue = 0;
3633 unsigned int base = 0x220;
developerfd40db22021-04-29 10:08:25 +08003634
3635 for (port = 0; port < 7; port++) {
developerbe40a9e2024-03-07 21:44:26 +08003636 reg_write(0x7038, base + (port * 4));
developerfd40db22021-04-29 10:08:25 +08003637 reg_read(0x7034, &value);
3638 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003639 printf("\n port %d output queue 0 counter is %d.\n", port,
3640 output_queue);
developerfd40db22021-04-29 10:08:25 +08003641 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003642 printf("\n port %d output queue 1 counter is %d.\n", port,
3643 output_queue);
developerfd40db22021-04-29 10:08:25 +08003644
developerbe40a9e2024-03-07 21:44:26 +08003645 reg_write(0x7038, base + (port * 4) + 1);
developerfd40db22021-04-29 10:08:25 +08003646 reg_read(0x7034, &value);
3647 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003648 printf("\n port %d output queue 2 counter is %d.\n", port,
3649 output_queue);
developerfd40db22021-04-29 10:08:25 +08003650 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003651 printf("\n port %d output queue 3 counter is %d.\n", port,
3652 output_queue);
developerfd40db22021-04-29 10:08:25 +08003653
developerbe40a9e2024-03-07 21:44:26 +08003654 reg_write(0x7038, base + (port * 4) + 2);
developerfd40db22021-04-29 10:08:25 +08003655 reg_read(0x7034, &value);
3656 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003657 printf("\n port %d output queue 4 counter is %d.\n", port,
3658 output_queue);
developerfd40db22021-04-29 10:08:25 +08003659 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003660 printf("\n port %d output queue 5 counter is %d.\n", port,
3661 output_queue);
developerfd40db22021-04-29 10:08:25 +08003662
developerbe40a9e2024-03-07 21:44:26 +08003663 reg_write(0x7038, base + (port * 4) + 3);
developerfd40db22021-04-29 10:08:25 +08003664 reg_read(0x7034, &value);
3665 output_queue = value & 0xff;
developerbe40a9e2024-03-07 21:44:26 +08003666 printf("\n port %d output queue 6 counter is %d.\n", port,
3667 output_queue);
developerfd40db22021-04-29 10:08:25 +08003668 output_queue = (value & 0xff00) >> 8;
developerbe40a9e2024-03-07 21:44:26 +08003669 printf("\n port %d output queue 7 counter is %d.\n", port,
3670 output_queue);
developerfd40db22021-04-29 10:08:25 +08003671 }
3672}
3673
developerbe40a9e2024-03-07 21:44:26 +08003674void read_free_page_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003675{
developerbe40a9e2024-03-07 21:44:26 +08003676 unsigned int value = 0;
3677 unsigned int free_page = 0, free_page_last_read = 0;
3678 unsigned int fc_free_blk_lothd = 0, fc_free_blk_hithd = 0;
3679 unsigned int fc_port_blk_thd = 0, fc_port_blk_hi_thd = 0;
3680 unsigned int queue[8] = { 0 };
developerfd40db22021-04-29 10:08:25 +08003681
developer8c3871b2022-07-01 14:07:53 +08003682 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerbe40a9e2024-03-07 21:44:26 +08003683 /* get system free page link counter */
developerfd40db22021-04-29 10:08:25 +08003684 reg_read(0x1fc0, &value);
3685 free_page = value & 0xFFF;
3686 free_page_last_read = (value & 0xFFF0000) >> 16;
3687
3688 /* get system flow control waterwark */
3689 reg_read(0x1fe0, &value);
3690 fc_free_blk_lothd = value & 0x3FF;
3691 fc_free_blk_hithd = (value & 0x3FF0000) >> 16;
3692
3693 /* get port flow control waterwark */
3694 reg_read(0x1fe4, &value);
3695 fc_port_blk_thd = value & 0x3FF;
3696 fc_port_blk_hi_thd = (value & 0x3FF0000) >> 16;
3697
3698 /* get queue flow control waterwark */
3699 reg_read(0x1fe8, &value);
developerbe40a9e2024-03-07 21:44:26 +08003700 queue[0] = value & 0x3F;
3701 queue[1] = (value & 0x3F00) >> 8;
3702 queue[2] = (value & 0x3F0000) >> 16;
3703 queue[3] = (value & 0x3F000000) >> 24;
developerfd40db22021-04-29 10:08:25 +08003704 reg_read(0x1fec, &value);
developerbe40a9e2024-03-07 21:44:26 +08003705 queue[4] = value & 0x3F;
3706 queue[5] = (value & 0x3F00) >> 8;
3707 queue[6] = (value & 0x3F0000) >> 16;
3708 queue[7] = (value & 0x3F000000) >> 24;
developerfd40db22021-04-29 10:08:25 +08003709 } else {
developerbe40a9e2024-03-07 21:44:26 +08003710 /* get system free page link counter */
developerfd40db22021-04-29 10:08:25 +08003711 reg_read(0x1fc0, &value);
3712 free_page = value & 0x3FF;
3713 free_page_last_read = (value & 0x3FF0000) >> 16;
3714
3715 /* get system flow control waterwark */
3716 reg_read(0x1fe0, &value);
3717 fc_free_blk_lothd = value & 0xFF;
3718 fc_free_blk_hithd = (value & 0xFF00) >> 8;
3719
3720 /* get port flow control waterwark */
3721 reg_read(0x1fe0, &value);
3722 fc_port_blk_thd = (value & 0xFF0000) >> 16;
3723 reg_read(0x1ff4, &value);
3724 fc_port_blk_hi_thd = (value & 0xFF00) >> 8;
3725
3726 /* get queue flow control waterwark */
3727 reg_read(0x1fe4, &value);
developerbe40a9e2024-03-07 21:44:26 +08003728 queue[0] = value & 0xF;
3729 queue[1] = (value & 0xF0) >> 4;
3730 queue[2] = (value & 0xF00) >> 8;
3731 queue[3] = (value & 0xF000) >> 12;
3732 queue[4] = (value & 0xF0000) >> 16;
3733 queue[5] = (value & 0xF00000) >> 20;
3734 queue[6] = (value & 0xF000000) >> 24;
3735 queue[7] = (value & 0xF0000000) >> 28;
developerfd40db22021-04-29 10:08:25 +08003736 }
3737
developerbe40a9e2024-03-07 21:44:26 +08003738 printf("<===Free Page=======Current=======Last Read access=====>\n");
3739 printf("\n");
3740 printf(" page counter %u %u\n ",
3741 free_page, free_page_last_read);
3742 printf("\n ");
3743 printf("=========================================================\n");
3744 printf("<===Type=======High threshold======Low threshold=========\n");
3745 printf("\n ");
3746 printf(" system: %u %u\n",
3747 fc_free_blk_hithd * 2, fc_free_blk_lothd * 2);
3748 printf(" port: %u %u\n",
3749 fc_port_blk_hi_thd * 2, fc_port_blk_thd * 2);
3750 printf(" queue 0: %u NA\n",
3751 queue[0]);
3752 printf(" queue 1: %u NA\n",
3753 queue[1]);
3754 printf(" queue 2: %u NA\n",
3755 queue[2]);
3756 printf(" queue 3: %u NA\n",
3757 queue[3]);
3758 printf(" queue 4: %u NA\n",
3759 queue[4]);
3760 printf(" queue 5: %u NA\n",
3761 queue[5]);
3762 printf(" queue 6: %u NA\n",
3763 queue[6]);
3764 printf(" queue 7: %u NA\n",
3765 queue[7]);
3766 printf("=========================================================\n");
developerfd40db22021-04-29 10:08:25 +08003767}
3768
3769void eee_enable(int argc, char *argv[])
3770{
developerbe40a9e2024-03-07 21:44:26 +08003771 unsigned long enable = 0;
3772 unsigned int value = 0;
3773 unsigned int eee_cap = 0;
developerfd40db22021-04-29 10:08:25 +08003774 unsigned int eee_en_bitmap = 0;
developerbe40a9e2024-03-07 21:44:26 +08003775 unsigned long port_map = 0;
developerfd40db22021-04-29 10:08:25 +08003776 long port_num = -1;
developerbe40a9e2024-03-07 21:44:26 +08003777 int p = 0;
developerfd40db22021-04-29 10:08:25 +08003778
3779 if (argc < 3)
3780 goto error;
3781
developerbe40a9e2024-03-07 21:44:26 +08003782 /* Check the input parameters is right or not. */
developerfd40db22021-04-29 10:08:25 +08003783 if (!strncmp(argv[2], "enable", 7))
3784 enable = 1;
3785 else if (!strncmp(argv[2], "disable", 8))
3786 enable = 0;
3787 else
3788 goto error;
3789
3790 if (argc > 3) {
3791 if (strlen(argv[3]) == 1) {
3792 port_num = strtol(argv[3], (char **)NULL, 10);
3793 if (port_num < 0 || port_num > MAX_PHY_PORT - 1) {
3794 printf("Illegal port index and port:0~4\n");
3795 goto error;
3796 }
3797 port_map = 1 << port_num;
3798 } else if (strlen(argv[3]) == 5) {
3799 port_map = 0;
3800 for (p = 0; p < MAX_PHY_PORT; p++) {
3801 if (argv[3][p] != '0' && argv[3][p] != '1') {
developerbe40a9e2024-03-07 21:44:26 +08003802 printf
3803 ("portmap format error, should be combination of 0 or 1\n");
developerfd40db22021-04-29 10:08:25 +08003804 goto error;
3805 }
3806 port_map |= ((argv[3][p] - '0') << p);
3807 }
3808 } else {
developerbe40a9e2024-03-07 21:44:26 +08003809 printf
3810 ("port_no or portmap format error, should be length of 1 or 5\n");
developerfd40db22021-04-29 10:08:25 +08003811 goto error;
3812 }
3813 } else {
3814 port_map = 0x1f;
3815 }
3816
developerbe40a9e2024-03-07 21:44:26 +08003817 eee_cap = (enable) ? 6 : 0;
developerfd40db22021-04-29 10:08:25 +08003818 for (p = 0; p < MAX_PHY_PORT; p++) {
3819 /* port_map describe p0p1p2p3p4 from left to rignt */
developerbe40a9e2024-03-07 21:44:26 +08003820 if (!!(port_map & (1 << p)))
developerfd40db22021-04-29 10:08:25 +08003821 mii_mgr_c45_write(p, 0x7, 0x3c, eee_cap);
3822
3823 mii_mgr_c45_read(p, 0x7, 0x3c, &value);
3824 /* mt7531: Always readback eee_cap = 0 when global EEE switch
3825 * is turned off.
3826 */
3827 if (value | eee_cap)
3828 eee_en_bitmap |= (1 << (MAX_PHY_PORT - 1 - p));
3829 }
3830
3831 /* Turn on/off global EEE switch */
developer8c3871b2022-07-01 14:07:53 +08003832 if (chip_name == 0x7531 || chip_name == 0x7988) {
developerfd40db22021-04-29 10:08:25 +08003833 mii_mgr_c45_read(0, 0x1f, 0x403, &value);
3834 if (eee_en_bitmap)
3835 value |= (1 << 6);
3836 else
3837 value &= ~(1 << 6);
3838 mii_mgr_c45_write(0, 0x1f, 0x403, value);
3839 } else {
3840 printf("\nCommand not support by this chip.\n");
3841 }
3842
developerbe40a9e2024-03-07 21:44:26 +08003843 printf("EEE(802.3az) %s", (enable) ? "enable" : "disable");
developerfd40db22021-04-29 10:08:25 +08003844 if (argc == 4) {
3845 if (port_num >= 0)
3846 printf(" port%ld", port_num);
3847 else
3848 printf(" port_map: %s", argv[3]);
3849 } else {
3850 printf(" all ports");
3851 }
3852 printf("\n");
3853
3854 return;
3855error:
3856 printf(HELP_EEE_EN);
3857 return;
3858}
3859
3860void eee_dump(int argc, char *argv[])
3861{
developerbe40a9e2024-03-07 21:44:26 +08003862 unsigned int cap = 0, lp_cap = 0;
developerfd40db22021-04-29 10:08:25 +08003863 long port = -1;
developerbe40a9e2024-03-07 21:44:26 +08003864 int p = 0;
developerfd40db22021-04-29 10:08:25 +08003865
3866 if (argc > 3) {
3867 if (strlen(argv[3]) > 1) {
3868 printf("port# format error, should be of length 1\n");
3869 return;
3870 }
3871
3872 port = strtol(argv[3], (char **)NULL, 0);
3873 if (port < 0 || port > MAX_PHY_PORT) {
3874 printf("port# format error, should be 0 to %d\n",
developerbe40a9e2024-03-07 21:44:26 +08003875 MAX_PHY_PORT);
developerfd40db22021-04-29 10:08:25 +08003876 return;
3877 }
3878 }
3879
3880 for (p = 0; p < MAX_PHY_PORT; p++) {
3881 if (port >= 0 && p != port)
3882 continue;
3883
3884 mii_mgr_c45_read(p, 0x7, 0x3c, &cap);
3885 mii_mgr_c45_read(p, 0x7, 0x3d, &lp_cap);
3886 printf("port%d EEE cap=0x%02x, link partner EEE cap=0x%02x",
3887 p, cap, lp_cap);
3888
3889 if (port >= 0 && p == port) {
3890 mii_mgr_c45_read(p, 0x3, 0x1, &cap);
3891 printf(", st=0x%03x", cap);
3892 }
3893 printf("\n");
3894 }
3895}
3896
3897void dump_each_port(unsigned int base)
3898{
3899 unsigned int pkt_cnt = 0;
3900 int i = 0;
3901
3902 for (i = 0; i < 7; i++) {
developer0dea3402022-10-14 13:41:11 +08003903 if (chip_name == 0x7988) {
3904 if ((base == 0x402C) && (i == 6))
3905 base = 0x408C;
3906 else if ((base == 0x408C) && (i == 6))
3907 base = 0x402C;
3908 else
3909 ;
3910 }
developerfd40db22021-04-29 10:08:25 +08003911 reg_read((base) + (i * 0x100), &pkt_cnt);
3912 printf("%8u ", pkt_cnt);
3913 }
3914 printf("\n");
3915}
3916
developerbe40a9e2024-03-07 21:44:26 +08003917void read_mib_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003918{
3919 printf("===================== %8s %8s %8s %8s %8s %8s %8s\n",
3920 "Port0", "Port1", "Port2", "Port3", "Port4", "Port5", "Port6");
3921 printf("Tx Drop Packet :");
3922 dump_each_port(0x4000);
3923 printf("Tx CRC Error :");
3924 dump_each_port(0x4004);
3925 printf("Tx Unicast Packet :");
3926 dump_each_port(0x4008);
3927 printf("Tx Multicast Packet :");
3928 dump_each_port(0x400C);
3929 printf("Tx Broadcast Packet :");
3930 dump_each_port(0x4010);
3931 printf("Tx Collision Event :");
3932 dump_each_port(0x4014);
3933 printf("Tx Pause Packet :");
3934 dump_each_port(0x402C);
3935 printf("Rx Drop Packet :");
3936 dump_each_port(0x4060);
3937 printf("Rx Filtering Packet :");
3938 dump_each_port(0x4064);
3939 printf("Rx Unicast Packet :");
3940 dump_each_port(0x4068);
3941 printf("Rx Multicast Packet :");
3942 dump_each_port(0x406C);
3943 printf("Rx Broadcast Packet :");
3944 dump_each_port(0x4070);
3945 printf("Rx Alignment Error :");
3946 dump_each_port(0x4074);
3947 printf("Rx CRC Error :");
3948 dump_each_port(0x4078);
3949 printf("Rx Undersize Error :");
3950 dump_each_port(0x407C);
3951 printf("Rx Fragment Error :");
3952 dump_each_port(0x4080);
3953 printf("Rx Oversize Error :");
3954 dump_each_port(0x4084);
3955 printf("Rx Jabber Error :");
3956 dump_each_port(0x4088);
3957 printf("Rx Pause Packet :");
3958 dump_each_port(0x408C);
3959}
3960
developerbe40a9e2024-03-07 21:44:26 +08003961void clear_mib_counters(int argc, char *argv[])
developerfd40db22021-04-29 10:08:25 +08003962{
3963 reg_write(0x4fe0, 0xf0);
developerbe40a9e2024-03-07 21:44:26 +08003964 read_mib_counters(argc, argv);
developerfd40db22021-04-29 10:08:25 +08003965 reg_write(0x4fe0, 0x800000f0);
3966}
3967
developerfd40db22021-04-29 10:08:25 +08003968void exit_free()
3969{
3970 free(attres);
3971 attres = NULL;
3972 switch_ioctl_fini();
3973 mt753x_netlink_free();
3974}