blob: 4239e1a0f82990efba1deedc207dc38d2c8968cd [file] [log] [blame]
developer880c8292022-07-11 11:52:59 +08001/*
developercc8110b2024-08-19 13:53:34 +08002 * switch_fun.c: switch function sets
3 */
developer880c8292022-07-11 11:52:59 +08004#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>
developer1afdd342024-04-08 14:04:38 +080014#include <errno.h>
developer880c8292022-07-11 11:52:59 +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
developere78dab52024-03-25 14:26:39 +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
developer880c8292022-07-11 11:52:59 +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);
developer5dfa8b72022-11-03 11:33:07 +0800108 if (c == NULL)
developer880c8292022-07-11 11:52:59 +0800109 return -1;
developer880c8292022-07-11 11:52:59 +0800110
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 */
developerfed736e2024-07-12 14:00:34 +0800137static void ip_to_str(char *str, size_t size, unsigned int ip)
developer880c8292022-07-11 11:52:59 +0800138{
developer5dfa8b72022-11-03 11:33:07 +0800139 unsigned char *ptr = (unsigned char *)&ip;
developer880c8292022-07-11 11:52:59 +0800140 unsigned char c[4];
developerfed736e2024-07-12 14:00:34 +0800141 int ret;
142
143 if (str == NULL || size == 0) {
144 printf("convert IP address failed\n");
145 return;
146 }
developer880c8292022-07-11 11:52:59 +0800147
148 c[0] = *(ptr);
149 c[1] = *(ptr + 1);
150 c[2] = *(ptr + 2);
151 c[3] = *(ptr + 3);
developerfed736e2024-07-12 14:00:34 +0800152
153 ret = snprintf(str, size, "%d.%d.%d.%d", c[3], c[2], c[1], c[0]);
154 if (ret < 0) {
155 printf("Encoding error in snprintf\n");
156 return;
157 } else if ((size_t)ret >= size) {
158 printf("Required size %d, provided size %zu\n", ret, size);
159 return;
160 }
developer880c8292022-07-11 11:52:59 +0800161}
162
developer5dfa8b72022-11-03 11:33:07 +0800163int reg_read(unsigned int offset, unsigned int *value)
developer880c8292022-07-11 11:52:59 +0800164{
165 int ret = -1;
166
167 if (nl_init_flag == true) {
168 ret = reg_read_netlink(attres, offset, value);
169 } else {
170 if (attres->dev_id == -1)
171 ret = reg_read_ioctl(offset, value);
172 }
173 if (ret < 0) {
174 printf("Read fail\n");
developer5dfa8b72022-11-03 11:33:07 +0800175 *value = 0;
176 return ret;
developer880c8292022-07-11 11:52:59 +0800177 }
178
179 return 0;
180}
181
developer5dfa8b72022-11-03 11:33:07 +0800182int reg_write(unsigned int offset, unsigned int value)
developer880c8292022-07-11 11:52:59 +0800183{
184 int ret = -1;
185
186 if (nl_init_flag == true) {
187 ret = reg_write_netlink(attres, offset, value);
188 } else {
189 if (attres->dev_id == -1)
190 ret = reg_write_ioctl(offset, value);
191 }
192 if (ret < 0) {
193 printf("Write fail\n");
194 exit_free();
195 exit(0);
196 }
197 return 0;
198}
199
developer5dfa8b72022-11-03 11:33:07 +0800200int mii_mgr_read(unsigned int port_num, unsigned int reg, unsigned int *value)
developer880c8292022-07-11 11:52:59 +0800201{
developer5dfa8b72022-11-03 11:33:07 +0800202 int ret;
developer880c8292022-07-11 11:52:59 +0800203
developer5dfa8b72022-11-03 11:33:07 +0800204 if (port_num > 31) {
developercc8110b2024-08-19 13:53:34 +0800205 printf("Invalid Port or PHY addr\n");
developer880c8292022-07-11 11:52:59 +0800206 return -1;
207 }
208
209 if (nl_init_flag == true)
210 ret = phy_cl22_read_netlink(attres, port_num, reg, value);
211 else
212 ret = mii_mgr_cl22_read_ioctl(port_num, reg, value);
213
214 if (ret < 0) {
developer5dfa8b72022-11-03 11:33:07 +0800215 printf("Phy cl22 read fail\n");
developer880c8292022-07-11 11:52:59 +0800216 exit_free();
217 exit(0);
218 }
219
220 return 0;
221}
222
223int mii_mgr_write(unsigned int port_num, unsigned int reg, unsigned int value)
224{
developer5dfa8b72022-11-03 11:33:07 +0800225 int ret;
developer880c8292022-07-11 11:52:59 +0800226
developer5dfa8b72022-11-03 11:33:07 +0800227 if (port_num > 31) {
developercc8110b2024-08-19 13:53:34 +0800228 printf("Invalid Port or PHY addr\n");
developer880c8292022-07-11 11:52:59 +0800229 return -1;
230 }
231
232 if (nl_init_flag == true)
233 ret = phy_cl22_write_netlink(attres, port_num, reg, value);
234 else
235 ret = mii_mgr_cl22_write_ioctl(port_num, reg, value);
236
237 if (ret < 0) {
developer5dfa8b72022-11-03 11:33:07 +0800238 printf("Phy cl22 write fail\n");
developer880c8292022-07-11 11:52:59 +0800239 exit_free();
240 exit(0);
241 }
242
243 return 0;
244}
245
developere78dab52024-03-25 14:26:39 +0800246int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg,
247 unsigned int *value)
developer880c8292022-07-11 11:52:59 +0800248{
developer5dfa8b72022-11-03 11:33:07 +0800249 int ret;
developer880c8292022-07-11 11:52:59 +0800250
developer5dfa8b72022-11-03 11:33:07 +0800251 if (port_num > 31) {
developercc8110b2024-08-19 13:53:34 +0800252 printf("Invalid Port or PHY addr\n");
developer880c8292022-07-11 11:52:59 +0800253 return -1;
254 }
255
256 if (nl_init_flag == true)
257 ret = phy_cl45_read_netlink(attres, port_num, dev, reg, value);
258 else
259 ret = mii_mgr_cl45_read_ioctl(port_num, dev, reg, value);
260
261 if (ret < 0) {
developer5dfa8b72022-11-03 11:33:07 +0800262 printf("Phy cl45 read fail\n");
developer880c8292022-07-11 11:52:59 +0800263 exit_free();
264 exit(0);
265 }
266
267 return 0;
268}
269
developere78dab52024-03-25 14:26:39 +0800270int mii_mgr_c45_write(unsigned int port_num, unsigned int dev, unsigned int reg,
271 unsigned int value)
developer880c8292022-07-11 11:52:59 +0800272{
developer5dfa8b72022-11-03 11:33:07 +0800273 int ret;
developer880c8292022-07-11 11:52:59 +0800274
developer5dfa8b72022-11-03 11:33:07 +0800275 if (port_num > 31) {
developercc8110b2024-08-19 13:53:34 +0800276 printf("Invalid Port or PHY addr\n");
developer880c8292022-07-11 11:52:59 +0800277 return -1;
278 }
279
280 if (nl_init_flag == true)
281 ret = phy_cl45_write_netlink(attres, port_num, dev, reg, value);
282 else
283 ret = mii_mgr_cl45_write_ioctl(port_num, dev, reg, value);
284
285 if (ret < 0) {
developer5dfa8b72022-11-03 11:33:07 +0800286 printf("Phy cl45 write fail\n");
developer880c8292022-07-11 11:52:59 +0800287 exit_free();
288 exit(0);
289 }
developer5dfa8b72022-11-03 11:33:07 +0800290
developer880c8292022-07-11 11:52:59 +0800291 return 0;
292}
293
developer880c8292022-07-11 11:52:59 +0800294int phy_dump(int phy_addr)
295{
developer5dfa8b72022-11-03 11:33:07 +0800296 int ret;
developer880c8292022-07-11 11:52:59 +0800297
298 if (nl_init_flag == true)
299 ret = phy_dump_netlink(attres, phy_addr);
300 else
301 ret = phy_dump_ioctl(phy_addr);
302
303 if (ret < 0) {
304 printf("Phy dump fail\n");
305 exit_free();
306 exit(0);
307 }
308
309 return 0;
310}
311
312void phy_crossover(int argc, char *argv[])
313{
developer5dfa8b72022-11-03 11:33:07 +0800314 unsigned int port_num = strtoul(argv[2], NULL, 10);
developere78dab52024-03-25 14:26:39 +0800315 unsigned int value = 0;
developer5dfa8b72022-11-03 11:33:07 +0800316 int ret;
developer880c8292022-07-11 11:52:59 +0800317
developer5dfa8b72022-11-03 11:33:07 +0800318 if (port_num > 4) {
developer880c8292022-07-11 11:52:59 +0800319 printf("invaild value, port_name:0~4\n");
320 return;
321 }
322
323 if (nl_init_flag == true)
developere78dab52024-03-25 14:26:39 +0800324 ret =
325 phy_cl45_read_netlink(attres, port_num, 0x1E,
326 MT7530_T10_TEST_CONTROL, &value);
developer880c8292022-07-11 11:52:59 +0800327 else
developere78dab52024-03-25 14:26:39 +0800328 ret =
329 mii_mgr_cl45_read_ioctl(port_num, 0x1E,
330 MT7530_T10_TEST_CONTROL, &value);
developer880c8292022-07-11 11:52:59 +0800331 if (ret < 0) {
332 printf("phy_cl45 read fail\n");
333 exit_free();
334 exit(0);
335 }
336
337 printf("mii_mgr_cl45:");
developercc8110b2024-08-19 13:53:34 +0800338 printf("Read: port#=%d, device=0x%x, reg=0x%x, value=0x%x\n",
339 port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
developer880c8292022-07-11 11:52:59 +0800340
developere78dab52024-03-25 14:26:39 +0800341 if (!strncmp(argv[3], "auto", 5)) {
developer880c8292022-07-11 11:52:59 +0800342 value &= (~(0x3 << 3));
343 } else if (!strncmp(argv[3], "mdi", 4)) {
344 value &= (~(0x3 << 3));
345 value |= (0x2 << 3);
346 } else if (!strncmp(argv[3], "mdix", 5)) {
347 value |= (0x3 << 3);
348 } else {
349 printf("invaild parameter\n");
350 return;
351 }
developercc8110b2024-08-19 13:53:34 +0800352 printf("Write: port#=%d, device=0x%x, reg=0x%x. value=0x%x\n",
353 port_num, 0x1E, MT7530_T10_TEST_CONTROL, value);
developer880c8292022-07-11 11:52:59 +0800354
355 if (nl_init_flag == true)
developere78dab52024-03-25 14:26:39 +0800356 ret =
357 phy_cl45_write_netlink(attres, port_num, 0x1E,
358 MT7530_T10_TEST_CONTROL, value);
developer880c8292022-07-11 11:52:59 +0800359 else
developere78dab52024-03-25 14:26:39 +0800360 ret =
361 mii_mgr_cl45_write_ioctl(port_num, 0x1E,
362 MT7530_T10_TEST_CONTROL, value);
developer880c8292022-07-11 11:52:59 +0800363
364 if (ret < 0) {
365 printf("phy_cl45 write fail\n");
366 exit_free();
367 exit(0);
368 }
369}
370
371int rw_phy_token_ring(int argc, char *argv[])
372{
developer5dfa8b72022-11-03 11:33:07 +0800373 int ch_addr, node_addr, data_addr;
374 unsigned int tr_reg_control;
375 unsigned int val_l = 0;
376 unsigned int val_h = 0;
377 unsigned int port_num;
developerfed736e2024-07-12 14:00:34 +0800378 char *endptr;
developer880c8292022-07-11 11:52:59 +0800379
380 if (argc < 4)
381 return -1;
382
383 if (argv[2][0] == 'r') {
384 if (argc != 7)
385 return -1;
developere78dab52024-03-25 14:26:39 +0800386 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
developerfed736e2024-07-12 14:00:34 +0800387
388 errno = 0;
389 port_num = strtoul(argv[3], &endptr, 10);
390 if (errno != 0 || *endptr != '\0' || port_num > MAX_PORT) {
developer880c8292022-07-11 11:52:59 +0800391 printf("Illegal port index and port:0~6\n");
392 return -1;
393 }
developerfed736e2024-07-12 14:00:34 +0800394
395 errno = 0;
396 ch_addr = strtoul(argv[4], &endptr, 10);
397 if (errno != 0 || *endptr != '\0')
398 goto error;
399
400 errno = 0;
401 node_addr = strtoul(argv[5], &endptr, 16);
402 if (errno != 0 || *endptr != '\0')
403 goto error;
404
405 errno = 0;
406 data_addr = strtoul(argv[6], &endptr, 16);
407 if (errno != 0 || *endptr != '\0')
408 goto error;
409
developere78dab52024-03-25 14:26:39 +0800410 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n",
developercc8110b2024-08-19 13:53:34 +0800411 port_num, ch_addr, node_addr, data_addr);
developere78dab52024-03-25 14:26:39 +0800412 tr_reg_control =
413 (1 << 15) | (1 << 13) | (ch_addr << 11) | (node_addr << 7) |
414 (data_addr << 1);
415 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
developer880c8292022-07-11 11:52:59 +0800416 mii_mgr_read(port_num, 17, &val_l);
417 mii_mgr_read(port_num, 18, &val_h);
developercc8110b2024-08-19 13:53:34 +0800418 printf("switch trreg read tr_reg_control=%x, value_H=%x, value_L=%x\n",
419 tr_reg_control, val_h, val_l);
developer880c8292022-07-11 11:52:59 +0800420 } else if (argv[2][0] == 'w') {
421 if (argc != 9)
422 return -1;
developere78dab52024-03-25 14:26:39 +0800423 mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5
developerfed736e2024-07-12 14:00:34 +0800424
425 errno = 0;
426 port_num = strtoul(argv[3], &endptr, 10);
427 if (errno != 0 || *endptr != '\0' || port_num > MAX_PORT) {
428 printf("Illegal port index and port:0~6\n");
developer880c8292022-07-11 11:52:59 +0800429 return -1;
430 }
developerfed736e2024-07-12 14:00:34 +0800431
432 errno = 0;
433 ch_addr = strtoul(argv[4], &endptr, 10);
434 if (errno != 0 || *endptr != '\0')
435 goto error;
436
437 errno = 0;
438 node_addr = strtoul(argv[5], &endptr, 16);
439 if (errno != 0 || *endptr != '\0')
440 goto error;
441
442 errno = 0;
443 data_addr = strtoul(argv[6], &endptr, 16);
444 if (errno != 0 || *endptr != '\0')
445 goto error;
446
447 errno = 0;
448 val_h = strtoul(argv[7], &endptr, 16);
449 if (errno != 0 || *endptr != '\0')
450 goto error;
451
452 errno = 0;
453 val_l = strtoul(argv[8], &endptr, 16);
454 if (errno != 0 || *endptr != '\0')
455 goto error;
456
developere78dab52024-03-25 14:26:39 +0800457 printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n",
developercc8110b2024-08-19 13:53:34 +0800458 port_num, ch_addr, node_addr, data_addr);
developere78dab52024-03-25 14:26:39 +0800459 tr_reg_control =
460 (1 << 15) | (0 << 13) | (ch_addr << 11) | (node_addr << 7) |
461 (data_addr << 1);
developer880c8292022-07-11 11:52:59 +0800462 mii_mgr_write(port_num, 17, val_l);
463 mii_mgr_write(port_num, 18, val_h);
developere78dab52024-03-25 14:26:39 +0800464 mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control
developercc8110b2024-08-19 13:53:34 +0800465 printf("switch trreg Write tr_reg_control=%x, value_H=%x, value_L=%x\n",
466 tr_reg_control, val_h, val_l);
developer880c8292022-07-11 11:52:59 +0800467 } else
468 return -1;
developerfed736e2024-07-12 14:00:34 +0800469
developer880c8292022-07-11 11:52:59 +0800470 return 0;
developerfed736e2024-07-12 14:00:34 +0800471
472error:
473 printf("\n**Illegal parameters\n");
474 return -1;
developer880c8292022-07-11 11:52:59 +0800475}
476
developere78dab52024-03-25 14:26:39 +0800477void write_acl_table(unsigned char tbl_idx, unsigned int vawd1,
478 unsigned int vawd2)
developer880c8292022-07-11 11:52:59 +0800479{
developere78dab52024-03-25 14:26:39 +0800480 unsigned int value = 0, reg = 0;
developer880c8292022-07-11 11:52:59 +0800481 unsigned int max_index;
482
developer5dfa8b72022-11-03 11:33:07 +0800483 if (chip_name == 0x7531 || chip_name == 0x7988)
developer880c8292022-07-11 11:52:59 +0800484 max_index = 256;
485 else
486 max_index = 64;
487
488 printf("Pattern_acl_tbl_idx:%d\n", tbl_idx);
489
490 if (tbl_idx >= max_index) {
491 printf(HELP_ACL_ACL_TBL_ADD);
492 return;
493 }
494
495 reg = REG_VTCR_ADDR;
developere78dab52024-03-25 14:26:39 +0800496 while (1) { // wait until not busy
developer880c8292022-07-11 11:52:59 +0800497 reg_read(reg, &value);
developercc8110b2024-08-19 13:53:34 +0800498 if ((value & REG_VTCR_BUSY_MASK) == 0)
developer880c8292022-07-11 11:52:59 +0800499 break;
developer880c8292022-07-11 11:52:59 +0800500 }
501 reg_write(REG_VAWD1_ADDR, vawd1);
502 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
503 reg_write(REG_VAWD2_ADDR, vawd2);
504 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
505 reg = REG_VTCR_ADDR;
506 value = REG_VTCR_BUSY_MASK | (0x05 << REG_VTCR_FUNC_OFFT) | tbl_idx;
507 reg_write(reg, value);
508 printf("write reg: %x, value: %x\n", reg, value);
509
developere78dab52024-03-25 14:26:39 +0800510 while (1) { // wait until not busy
developer880c8292022-07-11 11:52:59 +0800511 reg_read(reg, &value);
512 if ((value & REG_VTCR_BUSY_MASK) == 0)
513 break;
514 }
515}
516
517void acl_table_add(int argc, char *argv[])
518{
developere78dab52024-03-25 14:26:39 +0800519 unsigned int vawd1 = 0, vawd2 = 0;
520 unsigned char tbl_idx = 0;
developercc8110b2024-08-19 13:53:34 +0800521 unsigned int max_index = 0;
developerfed736e2024-07-12 14:00:34 +0800522 char *endptr;
523
developercc8110b2024-08-19 13:53:34 +0800524 if (chip_name == 0x7531 || chip_name == 0x7988)
525 max_index = 256;
526 else
527 max_index = 64;
528
developerfed736e2024-07-12 14:00:34 +0800529 errno = 0;
530 tbl_idx = strtoul(argv[3], &endptr, 10);
developercc8110b2024-08-19 13:53:34 +0800531 if (errno != 0 || *endptr != '\0' || tbl_idx >= max_index) {
developerfed736e2024-07-12 14:00:34 +0800532 printf("Error: wrong ACL rule table index\n");
533 return;
534 }
535
536 errno = 0;
537 vawd1 = strtoul(argv[4], &endptr, 16);
538 if (errno != 0 || *endptr != '\0') {
539 printf("Error: wrong ACL rule table write data 1\n");
540 return;
541 }
542
543 errno = 0;
544 vawd2 = strtoul(argv[5], &endptr, 16);
545 if (errno != 0 || *endptr != '\0') {
546 printf("Error: wrong ACL rule table write data 2\n");
547 return;
548 }
developer880c8292022-07-11 11:52:59 +0800549
developer880c8292022-07-11 11:52:59 +0800550 write_acl_table(tbl_idx, vawd1, vawd2);
551}
552
developere78dab52024-03-25 14:26:39 +0800553void write_acl_mask_table(unsigned char tbl_idx, unsigned int vawd1,
554 unsigned int vawd2)
developer880c8292022-07-11 11:52:59 +0800555{
developere78dab52024-03-25 14:26:39 +0800556 unsigned int value = 0, reg = 0;
557 unsigned int max_index = 0;
developer880c8292022-07-11 11:52:59 +0800558
developer5dfa8b72022-11-03 11:33:07 +0800559 if (chip_name == 0x7531 || chip_name == 0x7988)
developer880c8292022-07-11 11:52:59 +0800560 max_index = 128;
561 else
562 max_index = 32;
563
564 printf("Rule_mask_tbl_idx:%d\n", tbl_idx);
565
566 if (tbl_idx >= max_index) {
567 printf(HELP_ACL_MASK_TBL_ADD);
568 return;
569 }
570 reg = REG_VTCR_ADDR;
developere78dab52024-03-25 14:26:39 +0800571 while (1) { // wait until not busy
developer880c8292022-07-11 11:52:59 +0800572 reg_read(reg, &value);
573 if ((value & REG_VTCR_BUSY_MASK) == 0)
574 break;
575 }
576 reg_write(REG_VAWD1_ADDR, vawd1);
577 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
578 reg_write(REG_VAWD2_ADDR, vawd2);
579 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
580 reg = REG_VTCR_ADDR;
581 value = REG_VTCR_BUSY_MASK | (0x09 << REG_VTCR_FUNC_OFFT) | tbl_idx;
582 reg_write(reg, value);
583 printf("write reg: %x, value: %x\n", reg, value);
developere78dab52024-03-25 14:26:39 +0800584 while (1) { // wait until not busy
developer880c8292022-07-11 11:52:59 +0800585 reg_read(reg, &value);
586 if ((value & REG_VTCR_BUSY_MASK) == 0)
587 break;
588 }
589}
590
591void acl_mask_table_add(int argc, char *argv[])
592{
developere78dab52024-03-25 14:26:39 +0800593 unsigned int vawd1 = 0, vawd2 = 0;
594 unsigned char tbl_idx = 0;
developercc8110b2024-08-19 13:53:34 +0800595 unsigned int max_index = 0;
developerfed736e2024-07-12 14:00:34 +0800596 char *endptr;
developer880c8292022-07-11 11:52:59 +0800597
developercc8110b2024-08-19 13:53:34 +0800598 if (chip_name == 0x7531 || chip_name == 0x7988)
599 max_index = 128;
600 else
601 max_index = 32;
602
developerfed736e2024-07-12 14:00:34 +0800603 errno = 0;
604 tbl_idx = strtoul(argv[3], &endptr, 10);
developercc8110b2024-08-19 13:53:34 +0800605 if (errno != 0 || *endptr != '\0' || tbl_idx >= max_index) {
developerfed736e2024-07-12 14:00:34 +0800606 printf("Error: wrong ACL mask table index\n");
607 return;
608 }
609
610 errno = 0;
611 vawd1 = strtoul(argv[4], &endptr, 16);
612 if (errno != 0 || *endptr != '\0') {
613 printf("Error: wrong ACL mask table write data 1\n");
614 return;
615 }
616
617 errno = 0;
618 vawd2 = strtoul(argv[5], &endptr, 16);
619 if (errno != 0 || *endptr != '\0') {
620 printf("Error: wrong ACL mask table write data 2\n");
621 return;
622 }
623
developer880c8292022-07-11 11:52:59 +0800624 write_acl_mask_table(tbl_idx, vawd1, vawd2);
625}
626
developere78dab52024-03-25 14:26:39 +0800627void write_acl_rule_table(unsigned char tbl_idx, unsigned int vawd1,
628 unsigned int vawd2)
developer880c8292022-07-11 11:52:59 +0800629{
developere78dab52024-03-25 14:26:39 +0800630 unsigned int value = 0, reg = 0;
631 unsigned int max_index = 0;
developer880c8292022-07-11 11:52:59 +0800632
developer5dfa8b72022-11-03 11:33:07 +0800633 if (chip_name == 0x7531 || chip_name == 0x7988)
developer880c8292022-07-11 11:52:59 +0800634 max_index = 128;
635 else
636 max_index = 32;
637
638 printf("Rule_control_tbl_idx:%d\n", tbl_idx);
639
developercc8110b2024-08-19 13:53:34 +0800640 if (tbl_idx >= max_index) {
641 /* Check the input parameters is right or not. */
developer880c8292022-07-11 11:52:59 +0800642 printf(HELP_ACL_RULE_TBL_ADD);
643 return;
644 }
645 reg = REG_VTCR_ADDR;
646
developere78dab52024-03-25 14:26:39 +0800647 while (1) { // wait until not busy
developer880c8292022-07-11 11:52:59 +0800648 reg_read(reg, &value);
developercc8110b2024-08-19 13:53:34 +0800649 if ((value & REG_VTCR_BUSY_MASK) == 0)
developer880c8292022-07-11 11:52:59 +0800650 break;
developer880c8292022-07-11 11:52:59 +0800651 }
652 reg_write(REG_VAWD1_ADDR, vawd1);
653 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
654 reg_write(REG_VAWD2_ADDR, vawd2);
655 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
656 reg = REG_VTCR_ADDR;
657 value = REG_VTCR_BUSY_MASK | (0x0B << REG_VTCR_FUNC_OFFT) | tbl_idx;
658 reg_write(reg, value);
659 printf("write reg: %x, value: %x\n", reg, value);
660
developere78dab52024-03-25 14:26:39 +0800661 while (1) { // wait until not busy
developer880c8292022-07-11 11:52:59 +0800662 reg_read(reg, &value);
developercc8110b2024-08-19 13:53:34 +0800663 if ((value & REG_VTCR_BUSY_MASK) == 0)
developer880c8292022-07-11 11:52:59 +0800664 break;
developer880c8292022-07-11 11:52:59 +0800665 }
666}
667
668void acl_rule_table_add(int argc, char *argv[])
669{
developere78dab52024-03-25 14:26:39 +0800670 unsigned int vawd1 = 0, vawd2 = 0;
671 unsigned char tbl_idx = 0;
developercc8110b2024-08-19 13:53:34 +0800672 unsigned int max_index = 0;
developerfed736e2024-07-12 14:00:34 +0800673 char *endptr;
674
developercc8110b2024-08-19 13:53:34 +0800675 if (chip_name == 0x7531 || chip_name == 0x7988)
676 max_index = 128;
677 else
678 max_index = 32;
679
developerfed736e2024-07-12 14:00:34 +0800680 errno = 0;
681 tbl_idx = strtoul(argv[3], &endptr, 10);
developercc8110b2024-08-19 13:53:34 +0800682 if (errno != 0 || *endptr != '\0' || tbl_idx >= max_index) {
developerfed736e2024-07-12 14:00:34 +0800683 printf("Error: wrong ACL rule control table index\n");
684 return;
685 }
686
687 errno = 0;
688 vawd1 = strtoul(argv[4], &endptr, 16);
689 if (errno != 0 || *endptr != '\0') {
690 printf("Error: wrong ACL rule control table write data 1\n");
691 return;
692 }
693
694 errno = 0;
695 vawd2 = strtoul(argv[5], &endptr, 16);
696 if (errno != 0 || *endptr != '\0') {
697 printf("Error: wrong ACL rule control table write data 2\n");
698 return;
699 }
developer880c8292022-07-11 11:52:59 +0800700
developer880c8292022-07-11 11:52:59 +0800701 write_acl_rule_table(tbl_idx, vawd1, vawd2);
702}
703
developere78dab52024-03-25 14:26:39 +0800704void write_rate_table(unsigned char tbl_idx, unsigned int vawd1,
705 unsigned int vawd2)
developer880c8292022-07-11 11:52:59 +0800706{
developere78dab52024-03-25 14:26:39 +0800707 unsigned int value = 0, reg = 0;
developer880c8292022-07-11 11:52:59 +0800708 unsigned int max_index = 32;
709
710 printf("Rule_action_tbl_idx:%d\n", tbl_idx);
711
712 if (tbl_idx >= max_index) {
713 printf(HELP_ACL_RATE_TBL_ADD);
714 return;
715 }
716
717 reg = REG_VTCR_ADDR;
developere78dab52024-03-25 14:26:39 +0800718 while (1) { // wait until not busy
developer880c8292022-07-11 11:52:59 +0800719 reg_read(reg, &value);
720 if ((value & REG_VTCR_BUSY_MASK) == 0)
721 break;
722 }
723
724 reg_write(REG_VAWD1_ADDR, vawd1);
725 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
726 reg_write(REG_VAWD2_ADDR, vawd2);
727 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
728 reg = REG_VTCR_ADDR;
729 value = REG_VTCR_BUSY_MASK | (0x0D << REG_VTCR_FUNC_OFFT) | tbl_idx;
730 reg_write(reg, value);
731 printf("write reg: %x, value: %x\n", reg, value);
732
developere78dab52024-03-25 14:26:39 +0800733 while (1) { // wait until not busy
developer880c8292022-07-11 11:52:59 +0800734 reg_read(reg, &value);
735 if ((value & REG_VTCR_BUSY_MASK) == 0)
736 break;
737 }
738}
739
740void acl_rate_table_add(int argc, char *argv[])
741{
developere78dab52024-03-25 14:26:39 +0800742 unsigned int vawd1 = 0, vawd2 = 0;
743 unsigned char tbl_idx = 0;
developercc8110b2024-08-19 13:53:34 +0800744 unsigned int max_index = 32;
developerfed736e2024-07-12 14:00:34 +0800745 char *endptr;
746
747 errno = 0;
748 tbl_idx = strtoul(argv[3], &endptr, 10);
developercc8110b2024-08-19 13:53:34 +0800749 if (errno != 0 || *endptr != '\0' || tbl_idx >= max_index) {
developerfed736e2024-07-12 14:00:34 +0800750 printf("Error: wrong ACL rate control table index\n");
751 return;
752 }
developer880c8292022-07-11 11:52:59 +0800753
developerfed736e2024-07-12 14:00:34 +0800754 errno = 0;
755 vawd1 = strtoul(argv[4], &endptr, 16);
756 if (errno != 0 || *endptr != '\0') {
757 printf("Error: wrong ACL rate control table write data 1\n");
758 return;
759 }
760
761 errno = 0;
762 vawd2 = strtoul(argv[5], &endptr, 16);
763 if (errno != 0 || *endptr != '\0') {
764 printf("Error: wrong ACL rate control table write data 2\n");
765 return;
766 }
developer880c8292022-07-11 11:52:59 +0800767
768 write_rate_table(tbl_idx, vawd1, vawd2);
769}
770
developere78dab52024-03-25 14:26:39 +0800771void write_trTCM_table(unsigned char tbl_idx, unsigned int vawd1,
772 unsigned int vawd2)
developer880c8292022-07-11 11:52:59 +0800773{
developere78dab52024-03-25 14:26:39 +0800774 unsigned int value = 0, reg = 0;
developer880c8292022-07-11 11:52:59 +0800775 unsigned int max_index = 32;
776
777 printf("trTCM_tbl_idx:%d\n", tbl_idx);
778
779 if (tbl_idx >= max_index) {
780 printf(HELP_ACL_TRTCM_TBL_ADD);
781 return;
782 }
783
784 reg = REG_VTCR_ADDR;
developere78dab52024-03-25 14:26:39 +0800785 while (1) { // wait until not busy
developer880c8292022-07-11 11:52:59 +0800786 reg_read(reg, &value);
787 if ((value & REG_VTCR_BUSY_MASK) == 0)
788 break;
789 }
790
791 reg_write(REG_VAWD1_ADDR, vawd1);
792 printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1);
793 reg_write(REG_VAWD2_ADDR, vawd2);
794 printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2);
795 reg = REG_VTCR_ADDR;
796 value = REG_VTCR_BUSY_MASK | (0x07 << REG_VTCR_FUNC_OFFT) | tbl_idx;
797 reg_write(reg, value);
798 printf("write reg: %x, value: %x\n", reg, value);
799
developere78dab52024-03-25 14:26:39 +0800800 while (1) { // wait until not busy
developer880c8292022-07-11 11:52:59 +0800801 reg_read(reg, &value);
802 if ((value & REG_VTCR_BUSY_MASK) == 0)
803 break;
804 }
805}
806
developere78dab52024-03-25 14:26:39 +0800807int acl_parameters_pre_del(int len1, int len2, int argc, char *argv[],
808 int *port)
developer880c8292022-07-11 11:52:59 +0800809{
developere78dab52024-03-25 14:26:39 +0800810 int i = 0;
developer5dfa8b72022-11-03 11:33:07 +0800811
developer880c8292022-07-11 11:52:59 +0800812 *port = 0;
813 if (argc < len1) {
814 printf("insufficient arguments!\n");
815 return -1;
816 }
817
developere78dab52024-03-25 14:26:39 +0800818 if (len2 == 12) {
developer880c8292022-07-11 11:52:59 +0800819 if (!argv[4] || strlen(argv[4]) != len2) {
developercc8110b2024-08-19 13:53:34 +0800820 printf("The [%s] format error, should be of length %d\n",
821 argv[4], len2);
developer880c8292022-07-11 11:52:59 +0800822 return -1;
823 }
824 }
825
826 if (!argv[5] || strlen(argv[5]) != 8) {
827 printf("portsmap format error, should be of length 7\n");
828 return -1;
829 }
830
831 for (i = 0; i < 7; i++) {
832 if (argv[5][i] != '0' && argv[5][i] != '1') {
developercc8110b2024-08-19 13:53:34 +0800833 printf("portmap format error, should be of combination of 0 or 1\n");
developer880c8292022-07-11 11:52:59 +0800834 return -1;
835 }
836 *port += (argv[5][i] - '0') * (1 << i);
837 }
developer5dfa8b72022-11-03 11:33:07 +0800838 return 0;
developer880c8292022-07-11 11:52:59 +0800839}
840
developere78dab52024-03-25 14:26:39 +0800841void acl_compare_pattern(int ports, int comparion, int base, int word,
842 unsigned char table_index)
developer880c8292022-07-11 11:52:59 +0800843{
developere78dab52024-03-25 14:26:39 +0800844 unsigned int value = 0;
developer880c8292022-07-11 11:52:59 +0800845
developere78dab52024-03-25 14:26:39 +0800846 comparion |= 0xffff0000; //compare mask
developer880c8292022-07-11 11:52:59 +0800847
developere78dab52024-03-25 14:26:39 +0800848 value = ports << 8; //w_port_map
849 value |= 0x1 << 19; //enable
850 value |= base << 16; //mac header
851 value |= word << 1; //word offset
developer880c8292022-07-11 11:52:59 +0800852
853 write_acl_table(table_index, comparion, value);
854}
855
856void acl_mac_add(int argc, char *argv[])
857{
developere78dab52024-03-25 14:26:39 +0800858 unsigned int value = 0;
859 int ports = 0;
developer880c8292022-07-11 11:52:59 +0800860 char tmpstr[5];
861 int ret;
developerfed736e2024-07-12 14:00:34 +0800862 char *endptr;
developer880c8292022-07-11 11:52:59 +0800863
864 ret = acl_parameters_pre_del(6, 12, argc, argv, &ports);
865 if (ret < 0)
866 return;
developere78dab52024-03-25 14:26:39 +0800867 /* Set pattern */
developer880c8292022-07-11 11:52:59 +0800868 strncpy(tmpstr, argv[4], 4);
869 tmpstr[4] = '\0';
developerfed736e2024-07-12 14:00:34 +0800870 errno = 0;
871 value = strtoul(tmpstr, &endptr, 16);
872 if (errno != 0 || *endptr != '\0')
873 goto error;
874
developer880c8292022-07-11 11:52:59 +0800875 acl_compare_pattern(ports, value, 0x0, 0, 0);
876
877 strncpy(tmpstr, argv[4] + 4, 4);
878 tmpstr[4] = '\0';
developerfed736e2024-07-12 14:00:34 +0800879 errno = 0;
880 value = strtoul(tmpstr, &endptr, 16);
881 if (errno != 0 || *endptr != '\0')
882 goto error;
developer880c8292022-07-11 11:52:59 +0800883 acl_compare_pattern(ports, value, 0x0, 1, 1);
884
885 strncpy(tmpstr, argv[4] + 8, 4);
886 tmpstr[4] = '\0';
developerfed736e2024-07-12 14:00:34 +0800887 errno = 0;
888 value = strtoul(tmpstr, &endptr, 16);
889 if (errno != 0 || *endptr != '\0')
890 goto error;
developer880c8292022-07-11 11:52:59 +0800891 acl_compare_pattern(ports, value, 0x0, 2, 2);
892
893 //set mask
developere78dab52024-03-25 14:26:39 +0800894 write_acl_mask_table(0, 0x7, 0);
developer880c8292022-07-11 11:52:59 +0800895
896 //set action
developere78dab52024-03-25 14:26:39 +0800897 value = 0x7; //drop
898 value |= 1 << 28; //acl intterupt enable
899 value |= 1 << 27; //acl hit count
900 value |= 2 << 24; //acl hit count group index (0~3)
901 write_acl_rule_table(0, value, 0);
developerfed736e2024-07-12 14:00:34 +0800902 return;
903
904error:
905 printf("Error: string converting\n");
developer880c8292022-07-11 11:52:59 +0800906}
907
908void acl_dip_meter(int argc, char *argv[])
909{
developere78dab52024-03-25 14:26:39 +0800910 unsigned int value = 0, ip_value = 0, meter = 0;
911 int ports = 0;
developer880c8292022-07-11 11:52:59 +0800912 int ret;
913
developer5dfa8b72022-11-03 11:33:07 +0800914 ip_value = 0;
developer880c8292022-07-11 11:52:59 +0800915 ret = acl_parameters_pre_del(7, -1, argc, argv, &ports);
916 if (ret < 0)
917 return;
918
919 str_to_ip(&ip_value, argv[4]);
920 //set pattern
921 value = (ip_value >> 16);
922 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
923
924 //set pattern
925 value = (ip_value & 0xffff);
926 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
927
928 //set mask
developere78dab52024-03-25 14:26:39 +0800929 write_acl_mask_table(0, 0x3, 0);
developer880c8292022-07-11 11:52:59 +0800930
931 //set action
932 meter = strtoul(argv[6], NULL, 0);
developer5dfa8b72022-11-03 11:33:07 +0800933 if (((chip_name == 0x7530) && (meter > 1000000)) ||
developere78dab52024-03-25 14:26:39 +0800934 ((chip_name == 0x7531) && (meter > 2500000)) ||
935 ((chip_name == 0x7988) && (meter > 4000000))) {
developer5dfa8b72022-11-03 11:33:07 +0800936 printf("\n**Illegal meter input, and 7530: 0~1000000Kpbs, 7531: 0~2500000Kpbs, 7988: 0~4000000Kpbs**\n");
developer880c8292022-07-11 11:52:59 +0800937 return;
938 }
developer5dfa8b72022-11-03 11:33:07 +0800939 if (((chip_name == 0x7531 || chip_name == 0x7988) && (meter > 1000000))) {
developere78dab52024-03-25 14:26:39 +0800940 reg_read(0xc, &value);
developer880c8292022-07-11 11:52:59 +0800941 value |= 0x1 << 30;
developere78dab52024-03-25 14:26:39 +0800942 reg_write(0xC, value);
943 printf("AGC: 0x%x\n", value);
944 value = meter / 1000; //uint is 1Mbps
developer880c8292022-07-11 11:52:59 +0800945 } else {
developere78dab52024-03-25 14:26:39 +0800946 reg_read(0xc, &value);
developer880c8292022-07-11 11:52:59 +0800947 value &= ~(0x1 << 30);
developere78dab52024-03-25 14:26:39 +0800948 reg_write(0xC, value);
949 printf("AGC: 0x%x\n", value);
950 value = meter >> 6; //uint is 64Kbps
developer880c8292022-07-11 11:52:59 +0800951 }
developere78dab52024-03-25 14:26:39 +0800952 value |= 0x1 << 15; //enable rate control
953 printf("Acl rate control:0x%x\n", value);
developer880c8292022-07-11 11:52:59 +0800954 write_rate_table(0, value, 0);
955}
956
957void acl_dip_trtcm(int argc, char *argv[])
958{
developer5dfa8b72022-11-03 11:33:07 +0800959 unsigned int value, value2, ip_value;
developer880c8292022-07-11 11:52:59 +0800960 unsigned int CIR, CBS, PIR, PBS;
developer880c8292022-07-11 11:52:59 +0800961 int ports;
developer880c8292022-07-11 11:52:59 +0800962 int ret;
963
developer5dfa8b72022-11-03 11:33:07 +0800964 ip_value = 0;
developer880c8292022-07-11 11:52:59 +0800965 ret = acl_parameters_pre_del(10, -1, argc, argv, &ports);
966 if (ret < 0)
967 return;
968
969 str_to_ip(&ip_value, argv[4]);
970 //set pattern
971 value = (ip_value >> 16);
972 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
973
974 //set pattern
975 value = (ip_value & 0xffff);
976 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
977
978 //set CBS PBS
979 CIR = strtoul(argv[6], NULL, 0);
980 CBS = strtoul(argv[7], NULL, 0);
981 PIR = strtoul(argv[8], NULL, 0);
982 PBS = strtoul(argv[9], NULL, 0);
983
developere78dab52024-03-25 14:26:39 +0800984 if (CIR > 65535 * 64 || CBS > 65535 || PIR > 65535 * 64 || PBS > 65535) {
developer880c8292022-07-11 11:52:59 +0800985 printf("\n**Illegal input parameters**\n");
986 return;
987 }
988
developere78dab52024-03-25 14:26:39 +0800989 value = CBS << 16; //bit16~31
990 value |= PBS; //bit0~15
991 //value |= 1;//valid
developer880c8292022-07-11 11:52:59 +0800992 CIR = CIR >> 6;
993 PIR = PIR >> 6;
994
developere78dab52024-03-25 14:26:39 +0800995 value2 = CIR << 16; //bit16~31
996 value2 |= PIR; //bit0~15
997 write_trTCM_table(0, value, value2);
developer880c8292022-07-11 11:52:59 +0800998
999 //set pattern
developere78dab52024-03-25 14:26:39 +08001000 write_acl_mask_table(0, 0x3, 0);
developer880c8292022-07-11 11:52:59 +08001001
1002 //set action
developere78dab52024-03-25 14:26:39 +08001003 value = 0x1 << (11 + 1); //TrTCM green meter#0 Low drop
1004 value |= 0x2 << (8 + 1); //TrTCM yellow meter#0 Med drop
1005 value |= 0x3 << (5 + 1); //TrTCM red meter#0 Hig drop
1006 value |= 0x1 << 0; //TrTCM drop pcd select
1007 write_acl_rule_table(0, 0, value);
developer880c8292022-07-11 11:52:59 +08001008}
1009
1010void acl_ethertype(int argc, char *argv[])
1011{
developer5dfa8b72022-11-03 11:33:07 +08001012 unsigned int value, ethertype;
developer880c8292022-07-11 11:52:59 +08001013 int ports;
developer880c8292022-07-11 11:52:59 +08001014 int ret;
1015
1016 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1017 if (ret < 0)
1018 return;
developere78dab52024-03-25 14:26:39 +08001019 printf("ports:0x%x\n", ports);
developer880c8292022-07-11 11:52:59 +08001020 ethertype = strtoul(argv[4], NULL, 16);
1021 //set pattern
1022 value = ethertype;
1023 acl_compare_pattern(ports, value, 0x0, 0x6, 0);
1024
1025 //set pattern
developere78dab52024-03-25 14:26:39 +08001026 write_acl_mask_table(0, 0x1, 0);
developer880c8292022-07-11 11:52:59 +08001027
1028 //set action(drop)
developere78dab52024-03-25 14:26:39 +08001029 value = 0x7; //default. Nodrop
1030 value |= 1 << 28; //acl intterupt enable
1031 value |= 1 << 27; //acl hit count
developer880c8292022-07-11 11:52:59 +08001032
developere78dab52024-03-25 14:26:39 +08001033 write_acl_rule_table(0, value, 0);
developer880c8292022-07-11 11:52:59 +08001034}
1035
1036void acl_dip_modify(int argc, char *argv[])
1037{
developer5dfa8b72022-11-03 11:33:07 +08001038 unsigned int value, ip_value;
developer880c8292022-07-11 11:52:59 +08001039 int ports;
1040 int priority;
developer880c8292022-07-11 11:52:59 +08001041 int ret;
1042
developer5dfa8b72022-11-03 11:33:07 +08001043 ip_value = 0;
developer880c8292022-07-11 11:52:59 +08001044 priority = strtoul(argv[6], NULL, 16);
1045 if (priority < 0 || priority > 7) {
1046 printf("\n**Illegal priority value!**\n");
1047 return;
1048 }
1049
1050 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1051 if (ret < 0)
1052 return;
1053
1054 str_to_ip(&ip_value, argv[4]);
1055 //set pattern
1056 value = (ip_value >> 16);
1057 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
1058
1059 //set pattern
1060 value = (ip_value & 0xffff);
1061 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
1062
1063 //set pattern
developere78dab52024-03-25 14:26:39 +08001064 write_acl_mask_table(0, 0x3, 0);
developer880c8292022-07-11 11:52:59 +08001065
1066 //set action
developere78dab52024-03-25 14:26:39 +08001067 value = 0x0; //default. Nodrop
1068 value |= 1 << 28; //acl intterupt enable
1069 value |= 1 << 27; //acl hit count
1070 value |= priority << 4; //acl UP
1071 write_acl_rule_table(0, value, 0);
developer880c8292022-07-11 11:52:59 +08001072}
1073
1074void acl_dip_pppoe(int argc, char *argv[])
1075{
developer5dfa8b72022-11-03 11:33:07 +08001076 unsigned int value, ip_value;
developer880c8292022-07-11 11:52:59 +08001077 int ports;
developer880c8292022-07-11 11:52:59 +08001078 int ret;
1079
developer5dfa8b72022-11-03 11:33:07 +08001080 ip_value = 0;
developer880c8292022-07-11 11:52:59 +08001081 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1082 if (ret < 0)
1083 return;
1084
1085 str_to_ip(&ip_value, argv[4]);
1086 //set pattern
1087 value = (ip_value >> 16);
1088 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
1089
1090 //set pattern
1091 value = (ip_value & 0xffff);
1092 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
1093
1094 //set pattern
developere78dab52024-03-25 14:26:39 +08001095 write_acl_mask_table(0, 0x3, 0);
developer880c8292022-07-11 11:52:59 +08001096
1097 //set action
developere78dab52024-03-25 14:26:39 +08001098 value = 0x0; //default. Nodrop
1099 value |= 1 << 28; //acl intterupt enable
1100 value |= 1 << 27; //acl hit count
1101 value |= 1 << 20; //pppoe header remove
1102 value |= 1 << 21; //SA MAC SWAP
1103 value |= 1 << 22; //DA MAC SWAP
1104 write_acl_rule_table(0, value, 7);
developer880c8292022-07-11 11:52:59 +08001105}
1106
1107void acl_dip_add(int argc, char *argv[])
1108{
developer5dfa8b72022-11-03 11:33:07 +08001109 unsigned int value, ip_value;
developer880c8292022-07-11 11:52:59 +08001110 int ports;
developer880c8292022-07-11 11:52:59 +08001111 int ret;
1112
developer5dfa8b72022-11-03 11:33:07 +08001113 ip_value = 0;
developer880c8292022-07-11 11:52:59 +08001114 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1115 if (ret < 0)
1116 return;
1117
1118 str_to_ip(&ip_value, argv[4]);
1119 //set pattern
1120 value = (ip_value >> 16);
1121 acl_compare_pattern(ports, value, 0x2, 0x8, 0);
1122
1123 //set pattern
1124 value = (ip_value & 0xffff);
1125 acl_compare_pattern(ports, value, 0x2, 0x9, 1);
1126
1127 //set pattern
developere78dab52024-03-25 14:26:39 +08001128 write_acl_mask_table(0, 0x3, 0);
developer880c8292022-07-11 11:52:59 +08001129
1130 //set action
1131 //value = 0x0; //default
developere78dab52024-03-25 14:26:39 +08001132 value = 0x7; //drop
1133 value |= 1 << 28; //acl intterupt enable
1134 value |= 1 << 27; //acl hit count
1135 value |= 2 << 24; //acl hit count group index (0~3)
1136 write_acl_rule_table(0, value, 0);
developer880c8292022-07-11 11:52:59 +08001137}
1138
1139void acl_l4_add(int argc, char *argv[])
1140{
developere78dab52024-03-25 14:26:39 +08001141 unsigned int value = 0;
developer880c8292022-07-11 11:52:59 +08001142 int ports;
developer880c8292022-07-11 11:52:59 +08001143 int ret;
1144
1145 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1146 if (ret < 0)
1147 return;
1148
1149 //set pattern
1150 value = strtoul(argv[4], NULL, 16);
1151 acl_compare_pattern(ports, value, 0x5, 0x0, 0);
1152
1153 //set rue mask
developere78dab52024-03-25 14:26:39 +08001154 write_acl_mask_table(0, 0x1, 0);
developer880c8292022-07-11 11:52:59 +08001155 //set action
developere78dab52024-03-25 14:26:39 +08001156 value = 0x7; //drop
1157 //value |= 1;//valid
1158 write_acl_rule_table(0, value, 0);
developer880c8292022-07-11 11:52:59 +08001159}
1160
1161void acl_sp_add(int argc, char *argv[])
1162{
developere78dab52024-03-25 14:26:39 +08001163 unsigned int value = 0;
developer880c8292022-07-11 11:52:59 +08001164 int ports;
developer880c8292022-07-11 11:52:59 +08001165 int ret;
1166
1167 ret = acl_parameters_pre_del(6, -1, argc, argv, &ports);
1168 if (ret < 0)
1169 return;
1170 //set pattern
1171 value = strtoul(argv[4], NULL, 0);
1172 acl_compare_pattern(ports, value, 0x4, 0x0, 0);
1173
1174 //set rue mask
developere78dab52024-03-25 14:26:39 +08001175 write_acl_mask_table(0, 0x1, 0);
developer880c8292022-07-11 11:52:59 +08001176
1177 //set action
developere78dab52024-03-25 14:26:39 +08001178 value = 0x7; //drop
1179 //value |= 1;//valid
1180 write_acl_rule_table(0, value, 0);
developer880c8292022-07-11 11:52:59 +08001181}
1182
1183void acl_port_enable(int argc, char *argv[])
1184{
developere78dab52024-03-25 14:26:39 +08001185 unsigned int value = 0, reg = 0;
1186 unsigned char acl_port = 0, acl_en = 0;
developerfed736e2024-07-12 14:00:34 +08001187 char *endptr;
developer880c8292022-07-11 11:52:59 +08001188
developerfed736e2024-07-12 14:00:34 +08001189 errno = 0;
1190 acl_port = strtoul(argv[3], &endptr, 10);
1191 if (errno != 0 || *endptr != '\0' || acl_port > MAX_PORT) {
1192 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
1193 return;
1194 }
developer880c8292022-07-11 11:52:59 +08001195
developerfed736e2024-07-12 14:00:34 +08001196 errno = 0;
1197 acl_en = strtoul(argv[4], &endptr, 10);
1198 if (errno != 0 || *endptr != '\0' || acl_en > 1) {
developer880c8292022-07-11 11:52:59 +08001199 printf(HELP_ACL_SETPORTEN);
1200 return;
1201 }
1202
developerfed736e2024-07-12 14:00:34 +08001203 printf("acl_port:%d, acl_en:%d\n", acl_port, acl_en);
1204
developere78dab52024-03-25 14:26:39 +08001205 reg = REG_PCR_P0_ADDR + (0x100 * acl_port); // 0x2004[10]
developer880c8292022-07-11 11:52:59 +08001206 reg_read(reg, &value);
1207 value &= (~REG_PORT_ACL_EN_MASK);
1208 value |= (acl_en << REG_PORT_ACL_EN_OFFT);
1209
1210 printf("write reg: %x, value: %x\n", reg, value);
1211 reg_write(reg, value);
1212}
1213
1214static void dip_dump_internal(int type)
1215{
developer5dfa8b72022-11-03 11:33:07 +08001216 unsigned int i, j, value, mac, mac2, value2;
developere78dab52024-03-25 14:26:39 +08001217 char tmpstr[16] = { 0 };
developer880c8292022-07-11 11:52:59 +08001218 int table_size = 0;
1219 int hit_value1 = 0;
1220 int hit_value2 = 0;
1221
developere78dab52024-03-25 14:26:39 +08001222 if (type == GENERAL_TABLE) {
developer880c8292022-07-11 11:52:59 +08001223 table_size = 0x800;
developere78dab52024-03-25 14:26:39 +08001224 reg_write(REG_ATC_ADDR, 0x8104); //dip search command
1225 } else {
developer880c8292022-07-11 11:52:59 +08001226 table_size = 0x40;
developere78dab52024-03-25 14:26:39 +08001227 reg_write(REG_ATC_ADDR, 0x811c); //dip search command
developer880c8292022-07-11 11:52:59 +08001228 }
developercc8110b2024-08-19 13:53:34 +08001229 printf("hash port(0:6) rsp_cnt flag timer dip-address ATRD\n");
developer880c8292022-07-11 11:52:59 +08001230 for (i = 0; i < table_size; i++) {
developere78dab52024-03-25 14:26:39 +08001231 while (1) {
developer880c8292022-07-11 11:52:59 +08001232 reg_read(REG_ATC_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08001233 if (type == GENERAL_TABLE) {
developer880c8292022-07-11 11:52:59 +08001234 hit_value1 = value & (0x1 << 13);
1235 hit_value2 = 1;
developere78dab52024-03-25 14:26:39 +08001236 } else {
developer880c8292022-07-11 11:52:59 +08001237 hit_value1 = value & (0x1 << 13);
1238 hit_value2 = value & (0x1 << 28);
1239 }
1240
developere78dab52024-03-25 14:26:39 +08001241 if (hit_value1 && hit_value2) { //search_rdy
developer880c8292022-07-11 11:52:59 +08001242 reg_read(REG_ATRD_ADDR, &value2);
1243 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1244
developere78dab52024-03-25 14:26:39 +08001245 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1246 j = (value2 >> 4) & 0xff; //r_port_map
developer880c8292022-07-11 11:52:59 +08001247 printf("%c", (j & 0x01) ? '1' : '-');
1248 printf("%c", (j & 0x02) ? '1' : '-');
1249 printf("%c", (j & 0x04) ? '1' : '-');
1250 printf("%c ", (j & 0x08) ? '1' : '-');
1251 printf("%c", (j & 0x10) ? '1' : '-');
1252 printf("%c", (j & 0x20) ? '1' : '-');
1253 printf("%c", (j & 0x40) ? '1' : '-');
1254
1255 reg_read(REG_TSRA2_ADDR, &mac2);
1256
developere78dab52024-03-25 14:26:39 +08001257 printf(" 0x%4x", (mac2 & 0xffff)); //RESP_CNT
1258 printf(" 0x%2x", ((mac2 >> 16) & 0xff)); //RESP_FLAG
1259 printf(" %3d", ((mac2 >> 24) & 0xff)); //RESP_TIMER
1260 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developer880c8292022-07-11 11:52:59 +08001261 reg_read(REG_TSRA1_ADDR, &mac);
developerfed736e2024-07-12 14:00:34 +08001262 ip_to_str(tmpstr, sizeof(tmpstr), mac);
developer880c8292022-07-11 11:52:59 +08001263 printf(" %s", tmpstr);
developere78dab52024-03-25 14:26:39 +08001264 printf(" 0x%8x\n", value2); //ATRD
1265 //printf("%04x", ((mac2 >> 16) & 0xffff));
1266 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
developer880c8292022-07-11 11:52:59 +08001267 if (value & 0x4000) {
1268 printf("end of table %d\n", i);
1269 return;
1270 }
1271 break;
developere78dab52024-03-25 14:26:39 +08001272 } else if (value & 0x4000) { //at_table_end
1273 printf("found the last entry %d (not ready)\n",
1274 i);
developer880c8292022-07-11 11:52:59 +08001275 return;
1276 }
1277 usleep(5000);
1278 }
1279
developere78dab52024-03-25 14:26:39 +08001280 if (type == GENERAL_TABLE)
1281 reg_write(REG_ATC_ADDR, 0x8105); //search for next dip address
developer880c8292022-07-11 11:52:59 +08001282 else
developere78dab52024-03-25 14:26:39 +08001283 reg_write(REG_ATC_ADDR, 0x811d); //search for next dip address
developer880c8292022-07-11 11:52:59 +08001284 usleep(5000);
1285 }
1286}
1287
developere78dab52024-03-25 14:26:39 +08001288void dip_dump(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08001289{
1290 dip_dump_internal(GENERAL_TABLE);
1291
1292}
1293
1294void dip_add(int argc, char *argv[])
1295{
developer5dfa8b72022-11-03 11:33:07 +08001296 unsigned int value = 0;
developere78dab52024-03-25 14:26:39 +08001297 unsigned int i = 0, j = 0;
developer5dfa8b72022-11-03 11:33:07 +08001298
1299 value = 0;
developer880c8292022-07-11 11:52:59 +08001300
1301 str_to_ip(&value, argv[3]);
1302
1303 reg_write(REG_ATA1_ADDR, value);
1304 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1305
developer880c8292022-07-11 11:52:59 +08001306 if (!argv[4] || strlen(argv[4]) != 8) {
1307 printf("portmap format error, should be of length 7\n");
1308 return;
1309 }
1310 j = 0;
1311 for (i = 0; i < 7; i++) {
1312 if (argv[4][i] != '0' && argv[4][i] != '1') {
developercc8110b2024-08-19 13:53:34 +08001313 printf("portmap format error, should be of combination of 0 or 1\n");
developer880c8292022-07-11 11:52:59 +08001314 return;
1315 }
1316 j += (argv[4][i] - '0') * (1 << i);
1317 }
developere78dab52024-03-25 14:26:39 +08001318 value = j << 4; //w_port_map
1319 value |= (0x3 << 2); //static
developer880c8292022-07-11 11:52:59 +08001320
1321 reg_write(REG_ATWD_ADDR, value);
1322
1323 usleep(5000);
1324 reg_read(REG_ATWD_ADDR, &value);
1325 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1326
developere78dab52024-03-25 14:26:39 +08001327 value = 0x8011; //single w_dip_cmd
developer880c8292022-07-11 11:52:59 +08001328 reg_write(REG_ATC_ADDR, value);
1329
1330 usleep(1000);
1331
1332 for (i = 0; i < 20; i++) {
1333 reg_read(REG_ATC_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08001334 if ((value & 0x8000) == 0) { //mac address busy
developer880c8292022-07-11 11:52:59 +08001335 printf("done.\n");
1336 return;
1337 }
1338 usleep(1000);
1339 }
1340 if (i == 20)
1341 printf("timeout.\n");
1342}
1343
1344void dip_del(int argc, char *argv[])
1345{
developer5dfa8b72022-11-03 11:33:07 +08001346 unsigned int i, value;
developer880c8292022-07-11 11:52:59 +08001347
developer5dfa8b72022-11-03 11:33:07 +08001348 value = 0;
developer880c8292022-07-11 11:52:59 +08001349 str_to_ip(&value, argv[3]);
1350
1351 reg_write(REG_ATA1_ADDR, value);
1352
1353 value = 0;
1354 reg_write(REG_ATA2_ADDR, value);
1355
developere78dab52024-03-25 14:26:39 +08001356 value = 0; //STATUS=0, delete dip
developer880c8292022-07-11 11:52:59 +08001357 reg_write(REG_ATWD_ADDR, value);
1358
developere78dab52024-03-25 14:26:39 +08001359 value = 0x8011; //w_dip_cmd
developer880c8292022-07-11 11:52:59 +08001360 reg_write(REG_ATC_ADDR, value);
1361
1362 for (i = 0; i < 20; i++) {
1363 reg_read(REG_ATC_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08001364 if ((value & 0x8000) == 0) { //mac address busy
developer880c8292022-07-11 11:52:59 +08001365 if (argv[1] != NULL)
1366 printf("done.\n");
1367 return;
1368 }
1369 usleep(1000);
1370 }
1371 if (i == 20)
1372 printf("timeout.\n");
1373}
1374
developere78dab52024-03-25 14:26:39 +08001375void dip_clear(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08001376{
developere78dab52024-03-25 14:26:39 +08001377 unsigned int value = 0;
developer5dfa8b72022-11-03 11:33:07 +08001378
developere78dab52024-03-25 14:26:39 +08001379 reg_write(REG_ATC_ADDR, 0x8102); //clear all dip
developer880c8292022-07-11 11:52:59 +08001380 usleep(5000);
1381 reg_read(REG_ATC_ADDR, &value);
1382 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1383}
1384
1385static void sip_dump_internal(int type)
1386{
developere78dab52024-03-25 14:26:39 +08001387 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developer880c8292022-07-11 11:52:59 +08001388 int table_size = 0;
1389 int hit_value1 = 0;
1390 int hit_value2 = 0;
developere78dab52024-03-25 14:26:39 +08001391 char tmpstr[16] = { 0 };
developer880c8292022-07-11 11:52:59 +08001392
1393 if (type == GENERAL_TABLE) {
1394 table_size = 0x800;
developere78dab52024-03-25 14:26:39 +08001395 reg_write(REG_ATC_ADDR, 0x8204); //sip search command
1396 } else {
developer880c8292022-07-11 11:52:59 +08001397 table_size = 0x40;
developere78dab52024-03-25 14:26:39 +08001398 reg_write(REG_ATC_ADDR, 0x822c); //sip search command
developer880c8292022-07-11 11:52:59 +08001399 }
1400 printf("hash port(0:6) dip-address sip-address ATRD\n");
1401 for (i = 0; i < table_size; i++) {
developere78dab52024-03-25 14:26:39 +08001402 while (1) {
developer880c8292022-07-11 11:52:59 +08001403 reg_read(REG_ATC_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08001404 if (type == GENERAL_TABLE) {
developer880c8292022-07-11 11:52:59 +08001405 hit_value1 = value & (0x1 << 13);
1406 hit_value2 = 1;
1407 } else {
1408 hit_value1 = value & (0x1 << 13);
1409 hit_value2 = value & (0x1 << 28);
1410 }
1411
developere78dab52024-03-25 14:26:39 +08001412 if (hit_value1 && hit_value2) { //search_rdy
developer880c8292022-07-11 11:52:59 +08001413 reg_read(REG_ATRD_ADDR, &value2);
1414 //printf("REG_ATRD_ADDR=0x%x\n\r",value2);
1415
developere78dab52024-03-25 14:26:39 +08001416 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
1417 j = (value2 >> 4) & 0xff; //r_port_map
developer880c8292022-07-11 11:52:59 +08001418 printf("%c", (j & 0x01) ? '1' : '-');
1419 printf("%c", (j & 0x02) ? '1' : '-');
1420 printf("%c", (j & 0x04) ? '1' : '-');
1421 printf("%c", (j & 0x08) ? '1' : '-');
1422 printf(" %c", (j & 0x10) ? '1' : '-');
1423 printf("%c", (j & 0x20) ? '1' : '-');
1424 printf("%c", (j & 0x40) ? '1' : '-');
1425
1426 reg_read(REG_TSRA2_ADDR, &mac2);
1427
developerfed736e2024-07-12 14:00:34 +08001428 ip_to_str(tmpstr, sizeof(tmpstr), mac2);
developer880c8292022-07-11 11:52:59 +08001429 printf(" %s", tmpstr);
1430
1431 //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
1432 reg_read(REG_TSRA1_ADDR, &mac);
developerfed736e2024-07-12 14:00:34 +08001433 ip_to_str(tmpstr, sizeof(tmpstr), mac);
developer880c8292022-07-11 11:52:59 +08001434 printf(" %s", tmpstr);
1435 printf(" 0x%x\n", value2);
1436 //printf("%04x", ((mac2 >> 16) & 0xffff));
1437 //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-');
1438 if (value & 0x4000) {
1439 printf("end of table %d\n", i);
1440 return;
1441 }
1442 break;
developere78dab52024-03-25 14:26:39 +08001443 } else if (value & 0x4000) { //at_table_end
1444 printf("found the last entry %d (not ready)\n",
1445 i);
developer880c8292022-07-11 11:52:59 +08001446 return;
1447 }
1448 usleep(5000);
1449 }
1450
developere78dab52024-03-25 14:26:39 +08001451 if (type == GENERAL_TABLE)
1452 reg_write(REG_ATC_ADDR, 0x8205); //search for next sip address
1453 else
1454 reg_write(REG_ATC_ADDR, 0x822d); //search for next sip address
1455 usleep(5000);
developer880c8292022-07-11 11:52:59 +08001456 }
1457}
1458
developere78dab52024-03-25 14:26:39 +08001459void sip_dump(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08001460{
1461
1462 sip_dump_internal(GENERAL_TABLE);
1463
1464}
1465
developer880c8292022-07-11 11:52:59 +08001466void sip_add(int argc, char *argv[])
1467{
developere78dab52024-03-25 14:26:39 +08001468 unsigned int i = 0, j = 0, value = 0;
developer880c8292022-07-11 11:52:59 +08001469
developer5dfa8b72022-11-03 11:33:07 +08001470 value = 0;
developere78dab52024-03-25 14:26:39 +08001471 str_to_ip(&value, argv[3]); //SIP
developer880c8292022-07-11 11:52:59 +08001472
1473 reg_write(REG_ATA2_ADDR, value);
1474 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1475
1476 value = 0;
1477
developere78dab52024-03-25 14:26:39 +08001478 str_to_ip(&value, argv[4]); //DIP
developer880c8292022-07-11 11:52:59 +08001479 reg_write(REG_ATA1_ADDR, value);
1480 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1481
1482 if (!argv[5] || strlen(argv[5]) != 8) {
1483 printf("portmap format error, should be of length 7\n");
1484 return;
1485 }
1486 j = 0;
1487 for (i = 0; i < 7; i++) {
1488 if (argv[5][i] != '0' && argv[5][i] != '1') {
developercc8110b2024-08-19 13:53:34 +08001489 printf("portmap format error, should be of combination of 0 or 1\n");
developer880c8292022-07-11 11:52:59 +08001490 return;
1491 }
1492 j += (argv[5][i] - '0') * (1 << i);
1493 }
developere78dab52024-03-25 14:26:39 +08001494 value = j << 4; //w_port_map
1495 value |= (0x3 << 2); //static
developer880c8292022-07-11 11:52:59 +08001496
1497 reg_write(REG_ATWD_ADDR, value);
1498
1499 usleep(5000);
1500 reg_read(REG_ATWD_ADDR, &value);
1501 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1502
developere78dab52024-03-25 14:26:39 +08001503 value = 0x8021; //single w_sip_cmd
developer880c8292022-07-11 11:52:59 +08001504 reg_write(REG_ATC_ADDR, value);
1505
1506 usleep(1000);
1507
1508 for (i = 0; i < 20; i++) {
1509 reg_read(REG_ATC_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08001510 if ((value & 0x8000) == 0) { //mac address busy
developer880c8292022-07-11 11:52:59 +08001511 printf("done.\n");
1512 return;
1513 }
1514 usleep(1000);
1515 }
1516 if (i == 20)
1517 printf("timeout.\n");
1518}
1519
1520void sip_del(int argc, char *argv[])
1521{
developere78dab52024-03-25 14:26:39 +08001522 unsigned int i = 0, value = 0;
developer880c8292022-07-11 11:52:59 +08001523
developer5dfa8b72022-11-03 11:33:07 +08001524 value = 0;
developer880c8292022-07-11 11:52:59 +08001525 str_to_ip(&value, argv[3]);
1526
developere78dab52024-03-25 14:26:39 +08001527 reg_write(REG_ATA2_ADDR, value); //SIP
developer880c8292022-07-11 11:52:59 +08001528
1529 str_to_ip(&value, argv[4]);
developere78dab52024-03-25 14:26:39 +08001530 reg_write(REG_ATA1_ADDR, value); //DIP
developer880c8292022-07-11 11:52:59 +08001531
developere78dab52024-03-25 14:26:39 +08001532 value = 0; //STATUS=0, delete sip
developer880c8292022-07-11 11:52:59 +08001533 reg_write(REG_ATWD_ADDR, value);
1534
developere78dab52024-03-25 14:26:39 +08001535 value = 0x8021; //w_sip_cmd
developer880c8292022-07-11 11:52:59 +08001536 reg_write(REG_ATC_ADDR, value);
1537
1538 for (i = 0; i < 20; i++) {
1539 reg_read(REG_ATC_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08001540 if ((value & 0x8000) == 0) { //mac address busy
developer880c8292022-07-11 11:52:59 +08001541 if (argv[1] != NULL)
1542 printf("done.\n");
1543 return;
1544 }
1545 usleep(1000);
1546 }
1547 if (i == 20)
1548 printf("timeout.\n");
1549}
1550
developere78dab52024-03-25 14:26:39 +08001551void sip_clear(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08001552{
developere78dab52024-03-25 14:26:39 +08001553 unsigned int value = 0;
developer880c8292022-07-11 11:52:59 +08001554
developere78dab52024-03-25 14:26:39 +08001555 reg_write(REG_ATC_ADDR, 0x8202); //clear all sip
developer880c8292022-07-11 11:52:59 +08001556 usleep(5000);
1557 reg_read(REG_ATC_ADDR, &value);
1558 printf("REG_ATC_ADDR is 0x%x\n\r", value);
1559}
1560
1561static void table_dump_internal(int type)
1562{
developere78dab52024-03-25 14:26:39 +08001563 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developer880c8292022-07-11 11:52:59 +08001564 int table_size = 0;
1565 int table_end = 0;
1566 int hit_value1 = 0;
1567 int hit_value2 = 0;
1568
developere78dab52024-03-25 14:26:39 +08001569 if (type == GENERAL_TABLE) {
developer880c8292022-07-11 11:52:59 +08001570 table_size = 0x800;
1571 table_end = 0x7FF;
1572 reg_write(REG_ATC_ADDR, 0x8004);
1573 } else {
1574 table_size = 0x40;
1575 table_end = 0x3F;
1576 reg_write(REG_ATC_ADDR, 0x800C);
1577 }
developercc8110b2024-08-19 13:53:34 +08001578 printf("hash port(0:6) fid vid age(s) mac-address filter my_mac\n");
developer880c8292022-07-11 11:52:59 +08001579 for (i = 0; i < table_size; i++) {
developere78dab52024-03-25 14:26:39 +08001580 while (1) {
developer880c8292022-07-11 11:52:59 +08001581 reg_read(REG_ATC_ADDR, &value);
1582 //printf("ATC = 0x%x\n", value);
developere78dab52024-03-25 14:26:39 +08001583 if (type == GENERAL_TABLE) {
developer880c8292022-07-11 11:52:59 +08001584 hit_value1 = value & (0x1 << 13);
1585 hit_value2 = 1;
1586 } else {
1587 hit_value1 = value & (0x1 << 13);
1588 hit_value2 = value & (0x1 << 28);
1589 }
1590
developere78dab52024-03-25 14:26:39 +08001591 if (hit_value1 && hit_value2
1592 && (((value >> 15) & 0x1) == 0)) {
developer880c8292022-07-11 11:52:59 +08001593 printf("%03x: ", (value >> 16) & 0xfff);
1594 reg_read(REG_ATRD_ADDR, &value2);
developere78dab52024-03-25 14:26:39 +08001595 j = (value2 >> 4) & 0xff; //r_port_map
developer880c8292022-07-11 11:52:59 +08001596 printf("%c", (j & 0x01) ? '1' : '-');
1597 printf("%c", (j & 0x02) ? '1' : '-');
1598 printf("%c", (j & 0x04) ? '1' : '-');
1599 printf("%c", (j & 0x08) ? '1' : '-');
1600 printf("%c", (j & 0x10) ? '1' : '-');
1601 printf("%c", (j & 0x20) ? '1' : '-');
1602 printf("%c", (j & 0x40) ? '1' : '-');
1603 printf("%c", (j & 0x80) ? '1' : '-');
developer5dfa8b72022-11-03 11:33:07 +08001604
developer880c8292022-07-11 11:52:59 +08001605 reg_read(REG_TSRA2_ADDR, &mac2);
1606
developere78dab52024-03-25 14:26:39 +08001607 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developer880c8292022-07-11 11:52:59 +08001608 printf(" %4d", (mac2 & 0xfff));
1609 if (((value2 >> 24) & 0xff) == 0xFF)
developere78dab52024-03-25 14:26:39 +08001610 printf(" --- "); //r_age_field:static
developer880c8292022-07-11 11:52:59 +08001611 else
developere78dab52024-03-25 14:26:39 +08001612 printf(" %5d ", (((value2 >> 24) & 0xff) + 1) * 2); //r_age_field
developer880c8292022-07-11 11:52:59 +08001613 reg_read(REG_TSRA1_ADDR, &mac);
1614 printf(" %08x", mac);
1615 printf("%04x", ((mac2 >> 16) & 0xffff));
developere78dab52024-03-25 14:26:39 +08001616 printf(" %c",
1617 (((value2 >> 20) & 0x03) ==
1618 0x03) ? 'y' : '-');
1619 printf(" %c\n",
1620 (((value2 >> 23) & 0x01) ==
1621 0x01) ? 'y' : '-');
1622 if ((value & 0x4000)
1623 && (((value >> 16) & 0xfff) == table_end)) {
developer880c8292022-07-11 11:52:59 +08001624 printf("end of table %d\n", i);
1625 return;
1626 }
1627 break;
developere78dab52024-03-25 14:26:39 +08001628 } else if ((value & 0x4000) && (((value >> 15) & 0x1) == 0) && (((value >> 16) & 0xfff) == table_end)) { //at_table_end
developercc8110b2024-08-19 13:53:34 +08001629 printf("found the last entry %d (not ready)\n", i);
developer880c8292022-07-11 11:52:59 +08001630 return;
developere78dab52024-03-25 14:26:39 +08001631 } else
developer880c8292022-07-11 11:52:59 +08001632 usleep(5);
1633 }
1634
developere78dab52024-03-25 14:26:39 +08001635 if (type == GENERAL_TABLE)
1636 reg_write(REG_ATC_ADDR, 0x8005); //search for next address
1637 else
1638 reg_write(REG_ATC_ADDR, 0x800d); //search for next address
developer880c8292022-07-11 11:52:59 +08001639 usleep(5);
1640 }
1641}
1642
developere78dab52024-03-25 14:26:39 +08001643void table_dump(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08001644{
1645 table_dump_internal(GENERAL_TABLE);
1646
1647}
1648
developer880c8292022-07-11 11:52:59 +08001649void table_add(int argc, char *argv[])
1650{
developere78dab52024-03-25 14:26:39 +08001651 unsigned int i = 0, j = 0, value = 0, is_filter = 0, is_mymac = 0;
developer880c8292022-07-11 11:52:59 +08001652 char tmpstr[9];
developerfed736e2024-07-12 14:00:34 +08001653 char *endptr;
developer880c8292022-07-11 11:52:59 +08001654
1655 is_filter = (argv[1][0] == 'f') ? 1 : 0;
1656 is_mymac = (argv[1][0] == 'm') ? 1 : 0;
1657 if (!argv[2] || strlen(argv[2]) != 12) {
1658 printf("MAC address format error, should be of length 12\n");
1659 return;
1660 }
1661 strncpy(tmpstr, argv[2], 8);
1662 tmpstr[8] = '\0';
developerfed736e2024-07-12 14:00:34 +08001663 errno = 0;
1664 value = strtoul(tmpstr, &endptr, 16);
1665 if (errno != 0 || *endptr != '\0') {
1666 printf("Error: string converting\n");
1667 return;
1668 }
developer880c8292022-07-11 11:52:59 +08001669 reg_write(REG_ATA1_ADDR, value);
1670 printf("REG_ATA1_ADDR is 0x%x\n\r", value);
1671
1672 strncpy(tmpstr, argv[2] + 8, 4);
1673 tmpstr[4] = '\0';
developerfed736e2024-07-12 14:00:34 +08001674 errno = 0;
1675 value = strtoul(tmpstr, &endptr, 16);
1676 if (errno != 0 || *endptr != '\0') {
1677 printf("Error: string converting\n");
1678 return;
1679 }
developer880c8292022-07-11 11:52:59 +08001680 value = (value << 16);
developere78dab52024-03-25 14:26:39 +08001681 value |= (1 << 15); //IVL=1
developer880c8292022-07-11 11:52:59 +08001682
1683 if (argc > 4) {
developerfed736e2024-07-12 14:00:34 +08001684 errno = 0;
1685 j = strtoul(argv[4], &endptr, 10);
1686 if (errno != 0 || *endptr != '\0' || j > 4095) {
developer880c8292022-07-11 11:52:59 +08001687 printf("wrong vid range, should be within 0~4095\n");
1688 return;
1689 }
developere78dab52024-03-25 14:26:39 +08001690 value |= j; //vid
developer880c8292022-07-11 11:52:59 +08001691 }
1692
1693 reg_write(REG_ATA2_ADDR, value);
1694 printf("REG_ATA2_ADDR is 0x%x\n\r", value);
1695
1696 if (!argv[3] || strlen(argv[3]) != 8) {
1697 if (is_filter)
1698 argv[3] = "11111111";
1699 else {
1700 printf("portmap format error, should be of length 8\n");
1701 return;
1702 }
1703 }
1704 j = 0;
1705 for (i = 0; i < 7; i++) {
1706 if (argv[3][i] != '0' && argv[3][i] != '1') {
developercc8110b2024-08-19 13:53:34 +08001707 printf("portmap format error, should be of combination of 0 or 1\n");
developer880c8292022-07-11 11:52:59 +08001708 return;
1709 }
1710 j += (argv[3][i] - '0') * (1 << i);
1711 }
developere78dab52024-03-25 14:26:39 +08001712 value = j << 4; //w_port_map
developer880c8292022-07-11 11:52:59 +08001713
1714 if (argc > 5) {
developerfed736e2024-07-12 14:00:34 +08001715 errno = 0;
1716 j = strtoul(argv[5], &endptr, 10);
1717 if (errno != 0 || *endptr != '\0' || j < 1 || 255 < j) {
developer880c8292022-07-11 11:52:59 +08001718 printf("wrong age range, should be within 1~255\n");
1719 return;
1720 }
developere78dab52024-03-25 14:26:39 +08001721 value |= (j << 24); //w_age_field
1722 value |= (0x1 << 2); //dynamic
developer880c8292022-07-11 11:52:59 +08001723 } else {
developere78dab52024-03-25 14:26:39 +08001724 value |= (0xff << 24); //w_age_field
1725 value |= (0x3 << 2); //static
developer880c8292022-07-11 11:52:59 +08001726 }
1727
1728 if (argc > 6) {
developerfed736e2024-07-12 14:00:34 +08001729 errno = 0;
1730 j = strtoul(argv[6], &endptr, 10);
1731 if (errno != 0 || *endptr != '\0' || j > 7) {
developer880c8292022-07-11 11:52:59 +08001732 printf("wrong eg-tag range, should be within 0~7\n");
1733 return;
1734 }
developere78dab52024-03-25 14:26:39 +08001735 value |= (j << 13); //EG_TAG
developer880c8292022-07-11 11:52:59 +08001736 }
1737
1738 if (is_filter)
developere78dab52024-03-25 14:26:39 +08001739 value |= (7 << 20); //sa_filter
developer880c8292022-07-11 11:52:59 +08001740
1741 if (is_mymac)
1742 value |= (1 << 23);
1743
1744 reg_write(REG_ATWD_ADDR, value);
1745
1746 usleep(5000);
1747 reg_read(REG_ATWD_ADDR, &value);
1748 printf("REG_ATWD_ADDR is 0x%x\n\r", value);
1749
developere78dab52024-03-25 14:26:39 +08001750 value = 0x8001; //w_mac_cmd
developer880c8292022-07-11 11:52:59 +08001751 reg_write(REG_ATC_ADDR, value);
1752
1753 usleep(1000);
1754
1755 for (i = 0; i < 20; i++) {
1756 reg_read(REG_ATC_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08001757 if ((value & 0x8000) == 0) { //mac address busy
developer880c8292022-07-11 11:52:59 +08001758 printf("done.\n");
1759 return;
1760 }
1761 usleep(1000);
1762 }
1763 if (i == 20)
1764 printf("timeout.\n");
1765}
1766
1767void table_search_mac_vid(int argc, char *argv[])
1768{
developere78dab52024-03-25 14:26:39 +08001769 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developer880c8292022-07-11 11:52:59 +08001770 char tmpstr[9];
developerfed736e2024-07-12 14:00:34 +08001771 char *endptr;
developer880c8292022-07-11 11:52:59 +08001772
1773 if (!argv[3] || strlen(argv[3]) != 12) {
1774 printf("MAC address format error, should be of length 12\n");
1775 return;
1776 }
1777 strncpy(tmpstr, argv[3], 8);
1778 tmpstr[8] = '\0';
developerfed736e2024-07-12 14:00:34 +08001779 errno = 0;
1780 value = strtoul(tmpstr, &endptr, 16);
1781 if (errno != 0 || *endptr != '\0') {
1782 printf("Error: string converting\n");
1783 return;
1784 }
developer880c8292022-07-11 11:52:59 +08001785 reg_write(REG_ATA1_ADDR, value);
1786 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1787
1788 strncpy(tmpstr, argv[3] + 8, 4);
1789 tmpstr[4] = '\0';
1790
developerfed736e2024-07-12 14:00:34 +08001791 errno = 0;
1792 value = strtoul(tmpstr, &endptr, 16);
1793 if (errno != 0 || *endptr != '\0') {
1794 printf("Error: string converting\n");
1795 return;
1796 }
developer880c8292022-07-11 11:52:59 +08001797 value = (value << 16);
developere78dab52024-03-25 14:26:39 +08001798 value |= (1 << 15); //IVL=1
developer880c8292022-07-11 11:52:59 +08001799
developerfed736e2024-07-12 14:00:34 +08001800 errno = 0;
1801 j = strtoul(argv[5], &endptr, 10);
1802 if (errno != 0 || *endptr != '\0' || j > 4095) {
developer880c8292022-07-11 11:52:59 +08001803 printf("wrong vid range, should be within 0~4095\n");
1804 return;
1805 }
developerfed736e2024-07-12 14:00:34 +08001806
developere78dab52024-03-25 14:26:39 +08001807 value |= j; //vid
developer880c8292022-07-11 11:52:59 +08001808
1809 reg_write(REG_ATA2_ADDR, value);
1810 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1811
developere78dab52024-03-25 14:26:39 +08001812 value = 0x8000; //w_mac_cmd
developer880c8292022-07-11 11:52:59 +08001813 reg_write(REG_ATC_ADDR, value);
1814
1815 usleep(1000);
1816
1817 for (i = 0; i < 20; i++) {
1818 reg_read(REG_ATC_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08001819 if ((value & 0x8000) == 0) { //mac address busy
developer880c8292022-07-11 11:52:59 +08001820 break;
1821 }
1822 usleep(1000);
1823 }
1824 if (i == 20) {
1825 printf("search timeout.\n");
1826 return;
1827 }
1828
1829 if (value & 0x1000) {
1830 printf("search no entry.\n");
1831 return;
1832 }
1833
1834 printf("search done.\n");
developere78dab52024-03-25 14:26:39 +08001835 printf
1836 ("hash port(0:6) fid vid age mac-address filter my_mac\n");
developer880c8292022-07-11 11:52:59 +08001837
developere78dab52024-03-25 14:26:39 +08001838 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
developer880c8292022-07-11 11:52:59 +08001839 reg_read(REG_ATRD_ADDR, &value2);
developere78dab52024-03-25 14:26:39 +08001840 j = (value2 >> 4) & 0xff; //r_port_map
developer880c8292022-07-11 11:52:59 +08001841 printf("%c", (j & 0x01) ? '1' : '-');
1842 printf("%c", (j & 0x02) ? '1' : '-');
1843 printf("%c", (j & 0x04) ? '1' : '-');
1844 printf("%c ", (j & 0x08) ? '1' : '-');
1845 printf("%c", (j & 0x10) ? '1' : '-');
1846 printf("%c", (j & 0x20) ? '1' : '-');
1847 printf("%c", (j & 0x40) ? '1' : '-');
1848 printf("%c", (j & 0x80) ? '1' : '-');
1849
1850 reg_read(REG_TSRA2_ADDR, &mac2);
1851
developere78dab52024-03-25 14:26:39 +08001852 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developer880c8292022-07-11 11:52:59 +08001853 printf(" %4d", (mac2 & 0xfff));
developere78dab52024-03-25 14:26:39 +08001854 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developer880c8292022-07-11 11:52:59 +08001855 reg_read(REG_TSRA1_ADDR, &mac);
1856 printf(" %08x", mac);
1857 printf("%04x", ((mac2 >> 16) & 0xffff));
1858 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1859 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1860}
1861
1862void table_search_mac_fid(int argc, char *argv[])
1863{
developere78dab52024-03-25 14:26:39 +08001864 unsigned int i = 0, j = 0, value = 0, mac = 0, mac2 = 0, value2 = 0;
developer880c8292022-07-11 11:52:59 +08001865 char tmpstr[9];
developerfed736e2024-07-12 14:00:34 +08001866 char *endptr;
developer880c8292022-07-11 11:52:59 +08001867
1868 if (!argv[3] || strlen(argv[3]) != 12) {
1869 printf("MAC address format error, should be of length 12\n");
1870 return;
1871 }
1872 strncpy(tmpstr, argv[3], 8);
1873 tmpstr[8] = '\0';
developerfed736e2024-07-12 14:00:34 +08001874 errno = 0;
1875 value = strtoul(tmpstr, &endptr, 16);
1876 if (errno != 0 || *endptr != '\0') {
1877 printf("Error: string converting\n");
1878 return;
1879 }
developer880c8292022-07-11 11:52:59 +08001880 reg_write(REG_ATA1_ADDR, value);
1881 //printf("REG_ATA1_ADDR is 0x%x\n\r",value);
1882
1883 strncpy(tmpstr, argv[3] + 8, 4);
1884 tmpstr[4] = '\0';
developerfed736e2024-07-12 14:00:34 +08001885 errno = 0;
1886 value = strtoul(tmpstr, &endptr, 16);
1887 if (errno != 0 || *endptr != '\0') {
1888 printf("Error: string converting\n");
1889 return;
1890 }
developer880c8292022-07-11 11:52:59 +08001891 value = (value << 16);
developere78dab52024-03-25 14:26:39 +08001892 value &= ~(1 << 15); //IVL=0
developer880c8292022-07-11 11:52:59 +08001893
developerfed736e2024-07-12 14:00:34 +08001894 errno = 0;
1895 j = strtoul(argv[5], &endptr, 10);
1896 if (errno != 0 || *endptr != '\0' || j > 7) {
developer880c8292022-07-11 11:52:59 +08001897 printf("wrong fid range, should be within 0~7\n");
1898 return;
1899 }
developerfed736e2024-07-12 14:00:34 +08001900
developere78dab52024-03-25 14:26:39 +08001901 value |= (j << 12); //vid
developer880c8292022-07-11 11:52:59 +08001902
1903 reg_write(REG_ATA2_ADDR, value);
1904 //printf("REG_ATA2_ADDR is 0x%x\n\r",value);
1905
developere78dab52024-03-25 14:26:39 +08001906 value = 0x8000; //w_mac_cmd
developer880c8292022-07-11 11:52:59 +08001907 reg_write(REG_ATC_ADDR, value);
1908
1909 usleep(1000);
1910
1911 for (i = 0; i < 20; i++) {
1912 reg_read(REG_ATC_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08001913 if ((value & 0x8000) == 0) { //mac address busy
developer880c8292022-07-11 11:52:59 +08001914 break;
1915 }
1916 usleep(1000);
1917 }
1918 if (i == 20) {
1919 printf("search timeout.\n");
1920 return;
1921 }
1922
1923 if (value & 0x1000) {
1924 printf("search no entry.\n");
1925 return;
1926 }
1927
1928 printf("search done.\n");
developere78dab52024-03-25 14:26:39 +08001929 printf
1930 ("hash port(0:6) fid vid age mac-address filter my_mac\n");
developer880c8292022-07-11 11:52:59 +08001931
developere78dab52024-03-25 14:26:39 +08001932 printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu
developer880c8292022-07-11 11:52:59 +08001933 reg_read(REG_ATRD_ADDR, &value2);
developere78dab52024-03-25 14:26:39 +08001934 j = (value2 >> 4) & 0xff; //r_port_map
developer880c8292022-07-11 11:52:59 +08001935 printf("%c", (j & 0x01) ? '1' : '-');
1936 printf("%c", (j & 0x02) ? '1' : '-');
1937 printf("%c", (j & 0x04) ? '1' : '-');
1938 printf("%c ", (j & 0x08) ? '1' : '-');
1939 printf("%c", (j & 0x10) ? '1' : '-');
1940 printf("%c", (j & 0x20) ? '1' : '-');
1941 printf("%c", (j & 0x40) ? '1' : '-');
1942 printf("%c", (j & 0x80) ? '1' : '-');
1943
1944 reg_read(REG_TSRA2_ADDR, &mac2);
1945
developere78dab52024-03-25 14:26:39 +08001946 printf(" %2d", (mac2 >> 12) & 0x7); //FID
developer880c8292022-07-11 11:52:59 +08001947 printf(" %4d", (mac2 & 0xfff));
developere78dab52024-03-25 14:26:39 +08001948 printf(" %4d", (value2 >> 24) & 0xff); //r_age_field
developer880c8292022-07-11 11:52:59 +08001949 reg_read(REG_TSRA1_ADDR, &mac);
1950 printf(" %08x", mac);
1951 printf("%04x", ((mac2 >> 16) & 0xffff));
1952 printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-');
1953 printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-');
1954}
1955
1956void table_del_fid(int argc, char *argv[])
1957{
developere78dab52024-03-25 14:26:39 +08001958 unsigned int i = 0, j = 0, value = 0;
developer880c8292022-07-11 11:52:59 +08001959 char tmpstr[9];
developerfed736e2024-07-12 14:00:34 +08001960 char *endptr;
developer880c8292022-07-11 11:52:59 +08001961
1962 if (!argv[3] || strlen(argv[3]) != 12) {
1963 printf("MAC address format error, should be of length 12\n");
1964 return;
1965 }
1966 strncpy(tmpstr, argv[3], 8);
1967 tmpstr[8] = '\0';
developerfed736e2024-07-12 14:00:34 +08001968 errno = 0;
1969 value = strtoul(tmpstr, &endptr, 16);
1970 if (errno != 0 || *endptr != '\0') {
1971 printf("Error: string converting\n");
1972 return;
1973 }
developer880c8292022-07-11 11:52:59 +08001974 reg_write(REG_ATA1_ADDR, value);
developerfed736e2024-07-12 14:00:34 +08001975
developer880c8292022-07-11 11:52:59 +08001976 strncpy(tmpstr, argv[3] + 8, 4);
1977 tmpstr[4] = '\0';
developerfed736e2024-07-12 14:00:34 +08001978 errno = 0;
1979 value = strtoul(tmpstr, &endptr, 16);
1980 if (errno != 0 || *endptr != '\0') {
1981 printf("Error: string converting\n");
1982 return;
1983 }
developer880c8292022-07-11 11:52:59 +08001984 value = (value << 16);
1985
1986 if (argc > 5) {
developerfed736e2024-07-12 14:00:34 +08001987 errno = 0;
1988 j = strtoul(argv[5], &endptr, 10);
1989 if (errno != 0 || *endptr != '\0' || j > 7) {
developer880c8292022-07-11 11:52:59 +08001990 printf("wrong fid range, should be within 0~7\n");
1991 return;
1992 }
developere78dab52024-03-25 14:26:39 +08001993 value |= (j << 12); /* fid */
developer880c8292022-07-11 11:52:59 +08001994 }
1995
1996 reg_write(REG_ATA2_ADDR, value);
1997
developere78dab52024-03-25 14:26:39 +08001998 value = 0; /* STATUS=0, delete mac */
developer880c8292022-07-11 11:52:59 +08001999 reg_write(REG_ATWD_ADDR, value);
2000
developere78dab52024-03-25 14:26:39 +08002001 value = 0x8001; //w_mac_cmd
developer880c8292022-07-11 11:52:59 +08002002 reg_write(REG_ATC_ADDR, value);
2003
2004 for (i = 0; i < 20; i++) {
2005 reg_read(REG_ATC_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08002006 if ((value & 0x8000) == 0) { /* mac address busy */
developer880c8292022-07-11 11:52:59 +08002007 if (argv[1] != NULL)
2008 printf("done.\n");
2009 return;
2010 }
2011 usleep(1000);
2012 }
2013 if (i == 20)
2014 printf("timeout.\n");
2015}
2016
2017void table_del_vid(int argc, char *argv[])
2018{
developere78dab52024-03-25 14:26:39 +08002019 unsigned int i = 0, j = 0, value = 0;
developer880c8292022-07-11 11:52:59 +08002020 char tmpstr[9];
developerfed736e2024-07-12 14:00:34 +08002021 char *endptr;
developer880c8292022-07-11 11:52:59 +08002022
2023 if (!argv[3] || strlen(argv[3]) != 12) {
2024 printf("MAC address format error, should be of length 12\n");
2025 return;
2026 }
2027 strncpy(tmpstr, argv[3], 8);
2028 tmpstr[8] = '\0';
developerfed736e2024-07-12 14:00:34 +08002029 errno = 0;
2030 value = strtoul(tmpstr, &endptr, 16);
2031 if (errno != 0 || *endptr != '\0') {
2032 printf("Error: string converting\n");
2033 return;
2034 }
developer880c8292022-07-11 11:52:59 +08002035 reg_write(REG_ATA1_ADDR, value);
2036
2037 strncpy(tmpstr, argv[3] + 8, 4);
2038 tmpstr[4] = '\0';
developerfed736e2024-07-12 14:00:34 +08002039 errno = 0;
2040 value = strtoul(tmpstr, &endptr, 16);
2041 if (errno != 0 || *endptr != '\0') {
2042 printf("Error: string converting\n");
2043 return;
2044 }
developer880c8292022-07-11 11:52:59 +08002045 value = (value << 16);
2046
developerfed736e2024-07-12 14:00:34 +08002047 errno = 0;
2048 j = strtoul(argv[5], &endptr, 10);
2049 if (errno != 0 || *endptr != '\0' || j > 4095) {
developer880c8292022-07-11 11:52:59 +08002050 printf("wrong fid range, should be within 0~4095\n");
2051 return;
2052 }
developerfed736e2024-07-12 14:00:34 +08002053
developere78dab52024-03-25 14:26:39 +08002054 value |= j; //vid
developer880c8292022-07-11 11:52:59 +08002055 value |= 1 << 15;
2056 reg_write(REG_ATA2_ADDR, value);
2057
developere78dab52024-03-25 14:26:39 +08002058 value = 0; //STATUS=0, delete mac
developer880c8292022-07-11 11:52:59 +08002059 reg_write(REG_ATWD_ADDR, value);
2060
developere78dab52024-03-25 14:26:39 +08002061 value = 0x8001; //w_mac_cmd
developer880c8292022-07-11 11:52:59 +08002062 reg_write(REG_ATC_ADDR, value);
2063
2064 for (i = 0; i < 20; i++) {
2065 reg_read(REG_ATC_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08002066 if ((value & 0x8000) == 0) { //mac address busy
developer880c8292022-07-11 11:52:59 +08002067 if (argv[1] != NULL)
2068 printf("done.\n");
2069 return;
2070 }
2071 usleep(1000);
2072 }
2073 if (i == 20)
2074 printf("timeout.\n");
2075}
2076
developere78dab52024-03-25 14:26:39 +08002077void table_clear(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08002078{
developere78dab52024-03-25 14:26:39 +08002079 unsigned int value = 0;
2080
developer880c8292022-07-11 11:52:59 +08002081 reg_write(REG_ATC_ADDR, 0x8002);
2082 usleep(5000);
2083 reg_read(REG_ATC_ADDR, &value);
2084
2085 printf("REG_ATC_ADDR is 0x%x\n\r", value);
2086}
2087
2088void set_mirror_to(int argc, char *argv[])
2089{
developere78dab52024-03-25 14:26:39 +08002090 unsigned int value = 0;
2091 int idx = 0;
developer880c8292022-07-11 11:52:59 +08002092
2093 idx = strtoul(argv[3], NULL, 0);
2094 if (idx < 0 || MAX_PORT < idx) {
2095 printf("wrong port member, should be within 0~%d\n", MAX_PORT);
2096 return;
2097 }
2098 if (chip_name == 0x7530) {
2099
2100 reg_read(REG_MFC_ADDR, &value);
2101 value |= 0x1 << 3;
2102 value &= 0xfffffff8;
2103 value |= idx << 0;
2104
2105 reg_write(REG_MFC_ADDR, value);
2106 } else {
2107
2108 reg_read(REG_CFC_ADDR, &value);
2109 value &= (~REG_CFC_MIRROR_EN_MASK);
2110 value |= (1 << REG_CFC_MIRROR_EN_OFFT);
2111 value &= (~REG_CFC_MIRROR_PORT_MASK);
2112 value |= (idx << REG_CFC_MIRROR_PORT_OFFT);
2113 reg_write(REG_CFC_ADDR, value);
2114 }
2115}
2116
2117void set_mirror_from(int argc, char *argv[])
2118{
developere78dab52024-03-25 14:26:39 +08002119 unsigned int offset = 0, value = 0;
developerfed736e2024-07-12 14:00:34 +08002120 unsigned int idx = 0, mirror = 0;
2121 char *endptr;
developer880c8292022-07-11 11:52:59 +08002122
developerfed736e2024-07-12 14:00:34 +08002123 errno = 0;
2124 idx = strtoul(argv[3], &endptr, 0);
2125 if (errno != 0 || *endptr != '\0' || idx > MAX_PORT) {
2126 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
developer880c8292022-07-11 11:52:59 +08002127 return;
2128 }
2129
developerfed736e2024-07-12 14:00:34 +08002130 errno = 0;
2131 mirror = strtoul(argv[4], &endptr, 0);
2132
2133 if (errno != 0 || *endptr != '\0' || mirror > 3) {
developer880c8292022-07-11 11:52:59 +08002134 printf("wrong mirror setting, should be within 0~3\n");
2135 return;
2136 }
2137
2138 offset = (0x2004 | (idx << 8));
2139 reg_read(offset, &value);
2140
2141 value &= 0xfffffcff;
2142 value |= mirror << 8;
2143
2144 reg_write(offset, value);
2145}
2146
developer5dfa8b72022-11-03 11:33:07 +08002147void vlan_dump(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08002148{
developere78dab52024-03-25 14:26:39 +08002149 unsigned int i = 0, j = 0, value = 0, value2 = 0;
developer5dfa8b72022-11-03 11:33:07 +08002150 int eg_tag = 0;
developer880c8292022-07-11 11:52:59 +08002151
developer5dfa8b72022-11-03 11:33:07 +08002152 if (argc == 4) {
2153 if (!strncmp(argv[3], "egtag", 6))
2154 eg_tag = 1;
2155 }
2156
2157 if (eg_tag)
developercc8110b2024-08-19 13:53:34 +08002158 printf(" vid fid portmap s-tag\teg_tag(0:untagged 2:tagged)\n");
developer5dfa8b72022-11-03 11:33:07 +08002159 else
2160 printf(" vid fid portmap s-tag\n");
2161
developer880c8292022-07-11 11:52:59 +08002162 for (i = 1; i < 4095; i++) {
developere78dab52024-03-25 14:26:39 +08002163 value = (0x80000000 + i); //r_vid_cmd
developer880c8292022-07-11 11:52:59 +08002164 reg_write(REG_VTCR_ADDR, value);
2165
2166 for (j = 0; j < 20; j++) {
2167 reg_read(REG_VTCR_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08002168 if ((value & 0x80000000) == 0) { //mac address busy
developer880c8292022-07-11 11:52:59 +08002169 break;
2170 }
2171 usleep(1000);
2172 }
2173 if (j == 20)
2174 printf("timeout.\n");
2175
2176 reg_read(REG_VAWD1_ADDR, &value);
2177 reg_read(REG_VAWD2_ADDR, &value2);
2178 //printf("REG_VAWD1_ADDR value%d is 0x%x\n\r", i, value);
2179 //printf("REG_VAWD2_ADDR value%d is 0x%x\n\r", i, value2);
2180
2181 if ((value & 0x01) != 0) {
2182 printf(" %4d ", i);
2183 printf(" %2d ", ((value & 0xe) >> 1));
2184 printf(" %c", (value & 0x00010000) ? '1' : '-');
2185 printf("%c", (value & 0x00020000) ? '1' : '-');
2186 printf("%c", (value & 0x00040000) ? '1' : '-');
2187 printf("%c", (value & 0x00080000) ? '1' : '-');
2188 printf("%c", (value & 0x00100000) ? '1' : '-');
2189 printf("%c", (value & 0x00200000) ? '1' : '-');
2190 printf("%c", (value & 0x00400000) ? '1' : '-');
2191 printf("%c", (value & 0x00800000) ? '1' : '-');
developer5dfa8b72022-11-03 11:33:07 +08002192 printf(" %4d", ((value & 0xfff0) >> 4));
2193 if (eg_tag) {
2194 printf("\t");
2195 if ((value & (0x3 << 28)) == (0x3 << 28)) {
2196 /* VTAG_EN=1 and EG_CON=1 */
2197 printf("CONSISTENT");
2198 } else if (value & (0x1 << 28)) {
2199 /* VTAG_EN=1 */
2200 printf("%d", (value2 & 0x0003) >> 0);
2201 printf("%d", (value2 & 0x000c) >> 2);
2202 printf("%d", (value2 & 0x0030) >> 4);
2203 printf("%d", (value2 & 0x00c0) >> 6);
2204 printf("%d", (value2 & 0x0300) >> 8);
2205 printf("%d", (value2 & 0x0c00) >> 10);
2206 printf("%d", (value2 & 0x3000) >> 12);
2207 printf("%d", (value2 & 0xc000) >> 14);
2208 } else {
2209 /* VTAG_EN=0 */
2210 printf("DISABLED");
2211 }
2212 }
2213 printf("\n");
developer880c8292022-07-11 11:52:59 +08002214 } else {
developere78dab52024-03-25 14:26:39 +08002215 /*print 16 vid for reference information */
developer880c8292022-07-11 11:52:59 +08002216 if (i <= 16) {
2217 printf(" %4d ", i);
2218 printf(" %2d ", ((value & 0xe) >> 1));
2219 printf(" invalid\n");
2220 }
2221 }
2222 }
2223}
2224
developer880c8292022-07-11 11:52:59 +08002225static long timespec_diff_us(struct timespec start, struct timespec end)
2226{
2227 struct timespec temp;
2228 unsigned long duration = 0;
2229
2230 if ((end.tv_nsec - start.tv_nsec) < 0) {
2231 temp.tv_sec = end.tv_sec - start.tv_sec - 1;
2232 temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
2233 } else {
2234 temp.tv_sec = end.tv_sec - start.tv_sec;
2235 temp.tv_nsec = end.tv_nsec - start.tv_nsec;
2236 }
developere78dab52024-03-25 14:26:39 +08002237 /* calculate second part */
developer880c8292022-07-11 11:52:59 +08002238 duration += temp.tv_sec * 1000000;
developere78dab52024-03-25 14:26:39 +08002239 /* calculate ns part */
developer880c8292022-07-11 11:52:59 +08002240 duration += temp.tv_nsec >> 10;
2241
2242 return duration;
2243}
2244
developer880c8292022-07-11 11:52:59 +08002245void vlan_clear(int argc, char *argv[])
2246{
developere78dab52024-03-25 14:26:39 +08002247 unsigned int value = 0;
2248 int vid = 0;
developer880c8292022-07-11 11:52:59 +08002249 unsigned long duration_us = 0;
2250 struct timespec start, end;
2251
2252 for (vid = 0; vid < 4096; vid++) {
2253 clock_gettime(CLOCK_REALTIME, &start);
developere78dab52024-03-25 14:26:39 +08002254 value = 0; //invalid
developer880c8292022-07-11 11:52:59 +08002255 reg_write(REG_VAWD1_ADDR, value);
2256
developere78dab52024-03-25 14:26:39 +08002257 value = (0x80001000 + vid); //w_vid_cmd
developer880c8292022-07-11 11:52:59 +08002258 reg_write(REG_VTCR_ADDR, value);
2259 while (duration_us <= 1000) {
2260 reg_read(REG_VTCR_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08002261 if ((value & 0x80000000) == 0) { //table busy
developer880c8292022-07-11 11:52:59 +08002262 break;
2263 }
2264 clock_gettime(CLOCK_REALTIME, &end);
2265 duration_us = timespec_diff_us(start, end);
2266 }
2267 if (duration_us > 1000)
2268 printf("config vlan timeout: %ld.\n", duration_us);
2269 }
2270}
2271
2272void vlan_set(int argc, char *argv[])
2273{
developer5dfa8b72022-11-03 11:33:07 +08002274 unsigned int vlan_mem = 0;
2275 unsigned int value = 0;
2276 unsigned int value2 = 0;
developere78dab52024-03-25 14:26:39 +08002277 int i = 0, vid = 0, fid = 0;
developer880c8292022-07-11 11:52:59 +08002278 int stag = 0;
developer5dfa8b72022-11-03 11:33:07 +08002279 unsigned long eg_con = 0;
2280 unsigned int eg_tag = 0;
developer880c8292022-07-11 11:52:59 +08002281
2282 if (argc < 5) {
2283 printf("insufficient arguments!\n");
2284 return;
2285 }
developer5dfa8b72022-11-03 11:33:07 +08002286
2287 fid = strtoul(argv[3], NULL, 0);
2288 if (fid < 0 || fid > 7) {
2289 printf("wrong filtering db id range, should be within 0~7\n");
2290 return;
2291 }
2292 value |= (fid << 1);
2293
developer880c8292022-07-11 11:52:59 +08002294 vid = strtoul(argv[4], NULL, 0);
2295 if (vid < 0 || 0xfff < vid) {
2296 printf("wrong vlan id range, should be within 0~4095\n");
2297 return;
2298 }
developer5dfa8b72022-11-03 11:33:07 +08002299
developer880c8292022-07-11 11:52:59 +08002300 if (strlen(argv[5]) != 8) {
2301 printf("portmap format error, should be of length 7\n");
2302 return;
2303 }
developer5dfa8b72022-11-03 11:33:07 +08002304
2305 vlan_mem = 0;
developer880c8292022-07-11 11:52:59 +08002306 for (i = 0; i < 8; i++) {
2307 if (argv[5][i] != '0' && argv[5][i] != '1') {
developercc8110b2024-08-19 13:53:34 +08002308 printf("portmap format error, should be of combination of 0 or 1\n");
developer880c8292022-07-11 11:52:59 +08002309 return;
2310 }
developer5dfa8b72022-11-03 11:33:07 +08002311 vlan_mem += (argv[5][i] - '0') * (1 << i);
developer880c8292022-07-11 11:52:59 +08002312 }
developer880c8292022-07-11 11:52:59 +08002313
developer5dfa8b72022-11-03 11:33:07 +08002314 /* VLAN stag */
developer880c8292022-07-11 11:52:59 +08002315 if (argc > 6) {
2316 stag = strtoul(argv[6], NULL, 16);
developer5dfa8b72022-11-03 11:33:07 +08002317 if (stag < 0 || 0xfff < stag) {
developercc8110b2024-08-19 13:53:34 +08002318 printf("wrong stag id range, should be within 0~4095\n");
developer5dfa8b72022-11-03 11:33:07 +08002319 return;
2320 }
2321 //printf("STAG is 0x%x\n", stag);
developer880c8292022-07-11 11:52:59 +08002322 }
2323
developer5dfa8b72022-11-03 11:33:07 +08002324 /* set vlan member */
2325 value |= (vlan_mem << 16);
developere78dab52024-03-25 14:26:39 +08002326 value |= (1 << 30); //IVL=1
2327 value |= ((stag & 0xfff) << 4); //stag
2328 value |= 1; //valid
developer880c8292022-07-11 11:52:59 +08002329
2330 if (argc > 7) {
developer5dfa8b72022-11-03 11:33:07 +08002331 eg_con = strtoul(argv[7], NULL, 2);
2332 eg_con = !!eg_con;
developere78dab52024-03-25 14:26:39 +08002333 value |= (eg_con << 29); //eg_con
2334 value |= (1 << 28); //eg tag control enable
developer880c8292022-07-11 11:52:59 +08002335 }
2336
developer5dfa8b72022-11-03 11:33:07 +08002337 if (argc > 8 && !eg_con) {
2338 if (strlen(argv[8]) != 8) {
developercc8110b2024-08-19 13:53:34 +08002339 printf("egtag portmap format error, should be of length 7\n");
developer5dfa8b72022-11-03 11:33:07 +08002340 return;
2341 }
2342
2343 for (i = 0; i < 8; i++) {
2344 if (argv[8][i] < '0' || argv[8][i] > '3') {
developercc8110b2024-08-19 13:53:34 +08002345 printf("egtag portmap format error, should be of combination of 0 or 3\n");
developer5dfa8b72022-11-03 11:33:07 +08002346 return;
2347 }
2348 //eg_tag += (argv[8][i] - '0') * (1 << i * 2);
2349 eg_tag |= (argv[8][i] - '0') << (i * 2);
2350 }
2351
developere78dab52024-03-25 14:26:39 +08002352 value |= (1 << 28); //eg tag control enable
developer5dfa8b72022-11-03 11:33:07 +08002353 value2 &= ~(0xffff);
2354 value2 |= eg_tag;
developer880c8292022-07-11 11:52:59 +08002355 }
2356 reg_write(REG_VAWD1_ADDR, value);
developer5dfa8b72022-11-03 11:33:07 +08002357 reg_write(REG_VAWD2_ADDR, value2);
2358 //printf("VAWD1=0x%08x VAWD2=0x%08x ", value, value2);
developer880c8292022-07-11 11:52:59 +08002359
developere78dab52024-03-25 14:26:39 +08002360 value = (0x80001000 + vid); //w_vid_cmd
developer880c8292022-07-11 11:52:59 +08002361 reg_write(REG_VTCR_ADDR, value);
developer5dfa8b72022-11-03 11:33:07 +08002362 //printf("VTCR=0x%08x\n", value);
developer880c8292022-07-11 11:52:59 +08002363
developer5dfa8b72022-11-03 11:33:07 +08002364 for (i = 0; i < 300; i++) {
developer880c8292022-07-11 11:52:59 +08002365 usleep(1000);
2366 reg_read(REG_VTCR_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08002367 if ((value & 0x80000000) == 0) //table busy
developer880c8292022-07-11 11:52:59 +08002368 break;
2369 }
2370
developer5dfa8b72022-11-03 11:33:07 +08002371 if (i == 300)
developer880c8292022-07-11 11:52:59 +08002372 printf("config vlan timeout.\n");
2373}
2374
2375void igmp_on(int argc, char *argv[])
2376{
2377 unsigned int leaky_en = 0;
2378 unsigned int wan_num = 4;
developere78dab52024-03-25 14:26:39 +08002379 unsigned int port = 0, offset = 0, value = 0;
developer880c8292022-07-11 11:52:59 +08002380 char cmd[80];
developer5dfa8b72022-11-03 11:33:07 +08002381 int ret;
developerfed736e2024-07-12 14:00:34 +08002382 char *endptr;
developer880c8292022-07-11 11:52:59 +08002383
developerfed736e2024-07-12 14:00:34 +08002384 if (argc > 3) {
2385 errno = 0;
2386 leaky_en = strtoul(argv[3], &endptr, 10);
2387 if (errno != 0 || *endptr != '\0') {
2388 printf("Error: string converting\n");
2389 return;
2390 }
2391 }
2392 if (argc > 4) {
2393 errno = 0;
2394 wan_num = strtoul(argv[4], &endptr, 10);
2395 if (errno != 0 || *endptr != '\0') {
2396 printf("Error: string converting\n");
2397 return;
2398 }
2399 }
developer880c8292022-07-11 11:52:59 +08002400
2401 if (leaky_en == 1) {
2402 if (wan_num == 4) {
2403 /* reg_write(0x2410, 0x810000c8); */
2404 reg_read(0x2410, &value);
2405 reg_write(0x2410, value | (1 << 3));
2406 /* reg_write(0x2010, 0x810000c0); */
2407 reg_read(0x2010, &value);
2408 reg_write(0x2010, value & (~(1 << 3)));
2409 reg_write(REG_ISC_ADDR, 0x10027d10);
2410 } else {
2411 /* reg_write(0x2010, 0x810000c8); */
2412 reg_read(0x2010, &value);
2413 reg_write(0x2010, value | (1 << 3));
2414 /* reg_write(0x2410, 0x810000c0); */
2415 reg_read(0x2410, &value);
2416 reg_write(0x2410, value & (~(1 << 3)));
2417 reg_write(REG_ISC_ADDR, 0x01027d01);
2418 }
developere78dab52024-03-25 14:26:39 +08002419 } else
developer880c8292022-07-11 11:52:59 +08002420 reg_write(REG_ISC_ADDR, 0x10027d60);
2421
2422 reg_write(0x1c, 0x08100810);
2423 reg_write(0x2008, 0xb3ff);
2424 reg_write(0x2108, 0xb3ff);
2425 reg_write(0x2208, 0xb3ff);
2426 reg_write(0x2308, 0xb3ff);
2427 reg_write(0x2408, 0xb3ff);
2428 reg_write(0x2608, 0xb3ff);
2429 /* Enable Port ACL
developere78dab52024-03-25 14:26:39 +08002430 * reg_write(0x2P04, 0xff0403);
2431 */
developer880c8292022-07-11 11:52:59 +08002432 for (port = 0; port <= 6; port++) {
2433 offset = 0x2004 + port * 0x100;
2434 reg_read(offset, &value);
2435 reg_write(offset, value | (1 << 10));
2436 }
2437
developere78dab52024-03-25 14:26:39 +08002438 /*IGMP query only p4 -> p5 */
developer880c8292022-07-11 11:52:59 +08002439 reg_write(0x94, 0x00ff0002);
2440 if (wan_num == 4)
2441 reg_write(0x98, 0x000a1008);
2442 else
2443 reg_write(0x98, 0x000a0108);
2444 reg_write(0x90, 0x80005000);
2445 reg_write(0x94, 0xff001100);
2446 if (wan_num == 4)
2447 reg_write(0x98, 0x000B1000);
2448 else
2449 reg_write(0x98, 0x000B0100);
2450 reg_write(0x90, 0x80005001);
2451 reg_write(0x94, 0x3);
2452 reg_write(0x98, 0x0);
2453 reg_write(0x90, 0x80009000);
2454 reg_write(0x94, 0x1a002080);
2455 reg_write(0x98, 0x0);
2456 reg_write(0x90, 0x8000b000);
2457
developere78dab52024-03-25 14:26:39 +08002458 /*IGMP p5 -> p4 */
developer880c8292022-07-11 11:52:59 +08002459 reg_write(0x94, 0x00ff0002);
2460 reg_write(0x98, 0x000a2008);
2461 reg_write(0x90, 0x80005002);
2462 reg_write(0x94, 0x4);
2463 reg_write(0x98, 0x0);
2464 reg_write(0x90, 0x80009001);
2465 if (wan_num == 4)
2466 reg_write(0x94, 0x1a001080);
2467 else
2468 reg_write(0x94, 0x1a000180);
2469 reg_write(0x98, 0x0);
2470 reg_write(0x90, 0x8000b001);
2471
developere78dab52024-03-25 14:26:39 +08002472 /*IGMP p0~p3 -> p6 */
developer880c8292022-07-11 11:52:59 +08002473 reg_write(0x94, 0x00ff0002);
2474 if (wan_num == 4)
2475 reg_write(0x98, 0x000a0f08);
2476 else
2477 reg_write(0x98, 0x000a1e08);
2478 reg_write(0x90, 0x80005003);
2479 reg_write(0x94, 0x8);
2480 reg_write(0x98, 0x0);
2481 reg_write(0x90, 0x80009002);
2482 reg_write(0x94, 0x1a004080);
2483 reg_write(0x98, 0x0);
2484 reg_write(0x90, 0x8000b002);
2485
developere78dab52024-03-25 14:26:39 +08002486 /*IGMP query only p6 -> p0~p3 */
developer880c8292022-07-11 11:52:59 +08002487 reg_write(0x94, 0x00ff0002);
2488 reg_write(0x98, 0x000a4008);
2489 reg_write(0x90, 0x80005004);
2490 reg_write(0x94, 0xff001100);
2491 reg_write(0x98, 0x000B4000);
2492 reg_write(0x90, 0x80005005);
2493 reg_write(0x94, 0x30);
2494 reg_write(0x98, 0x0);
2495 reg_write(0x90, 0x80009003);
2496 if (wan_num == 4)
2497 reg_write(0x94, 0x1a000f80);
2498 else
2499 reg_write(0x94, 0x1a001e80);
2500 reg_write(0x98, 0x0);
2501 reg_write(0x90, 0x8000b003);
2502
developere78dab52024-03-25 14:26:39 +08002503 /*Force eth2 to receive all igmp packets */
developerfed736e2024-07-12 14:00:34 +08002504 ret = snprintf(cmd, sizeof(cmd),
developere78dab52024-03-25 14:26:39 +08002505 "echo 2 > /sys/devices/virtual/net/%s/brif/%s/multicast_router",
2506 BR_DEVNAME, ETH_DEVNAME);
developerfed736e2024-07-12 14:00:34 +08002507
2508 if (ret < 0 || ret >= sizeof(cmd))
2509 goto error;
2510
developer5dfa8b72022-11-03 11:33:07 +08002511 ret = system(cmd);
2512 if (ret)
developerfed736e2024-07-12 14:00:34 +08002513 goto error;
2514
2515 return;
2516
2517error:
2518 printf("Failed to set /sys/devices/virtual/net/%s/brif/%s/multicast_router\n",
2519 BR_DEVNAME, ETH_DEVNAME);
developer880c8292022-07-11 11:52:59 +08002520}
2521
2522void igmp_disable(int argc, char *argv[])
2523{
developere78dab52024-03-25 14:26:39 +08002524 unsigned int reg_offset = 0, value = 0;
2525 int port_num = 0;
developer880c8292022-07-11 11:52:59 +08002526
2527 if (argc < 4) {
2528 printf("insufficient arguments!\n");
2529 return;
2530 }
2531 port_num = strtoul(argv[3], NULL, 0);
2532 if (port_num < 0 || 6 < port_num) {
2533 printf("wrong port range, should be within 0~6\n");
2534 return;
2535 }
developer880c8292022-07-11 11:52:59 +08002536 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2537 reg_offset = 0x2008;
2538 reg_offset |= (port_num << 8);
2539 value = 0x8000;
2540
2541 reg_write(reg_offset, value);
2542}
2543
2544void igmp_enable(int argc, char *argv[])
2545{
developere78dab52024-03-25 14:26:39 +08002546 unsigned int reg_offset = 0, value = 0;
developer880c8292022-07-11 11:52:59 +08002547 int port_num;
2548
2549 if (argc < 4) {
2550 printf("insufficient arguments!\n");
2551 return;
2552 }
2553 port_num = strtoul(argv[3], NULL, 0);
2554 if (port_num < 0 || 6 < port_num) {
2555 printf("wrong port range, should be within 0~6\n");
2556 return;
2557 }
developer880c8292022-07-11 11:52:59 +08002558 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2559 reg_offset = 0x2008;
2560 reg_offset |= (port_num << 8);
2561 value = 0x9755;
2562 reg_write(reg_offset, value);
2563}
2564
developere78dab52024-03-25 14:26:39 +08002565void igmp_off(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08002566{
developere78dab52024-03-25 14:26:39 +08002567 unsigned int value = 0;
developer880c8292022-07-11 11:52:59 +08002568 //set ISC: IGMP Snooping Control Register (offset: 0x0018)
2569 reg_read(REG_ISC_ADDR, &value);
developere78dab52024-03-25 14:26:39 +08002570 value &= ~(1 << 18); //disable
developer880c8292022-07-11 11:52:59 +08002571 reg_write(REG_ISC_ADDR, value);
2572
developere78dab52024-03-25 14:26:39 +08002573 /*restore wan port multicast leaky vlan function: default disabled */
developer880c8292022-07-11 11:52:59 +08002574 reg_read(0x2010, &value);
2575 reg_write(0x2010, value & (~(1 << 3)));
2576 reg_read(0x2410, &value);
2577 reg_write(0x2410, value & (~(1 << 3)));
2578
2579 printf("config igmpsnoop off.\n");
2580}
2581
developere78dab52024-03-25 14:26:39 +08002582void switch_reset(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08002583{
developer5dfa8b72022-11-03 11:33:07 +08002584 if (chip_name == 0x7988)
developere78dab52024-03-25 14:26:39 +08002585 return;
developer5dfa8b72022-11-03 11:33:07 +08002586
developer880c8292022-07-11 11:52:59 +08002587 unsigned int value = 0;
2588 /*Software Register Reset and Software System Reset */
2589 reg_write(0x7000, 0x3);
2590 reg_read(0x7000, &value);
developercc8110b2024-08-19 13:53:34 +08002591 printf("SYS_CTRL(0x7000) register value =0x%x\n", value);
developer880c8292022-07-11 11:52:59 +08002592 if (chip_name == 0x7531) {
2593 reg_write(0x7c0c, 0x11111111);
2594 reg_read(0x7c0c, &value);
developercc8110b2024-08-19 13:53:34 +08002595 printf("GPIO Mode (0x7c0c) select value =0x%x\n", value);
developer880c8292022-07-11 11:52:59 +08002596 }
developercc8110b2024-08-19 13:53:34 +08002597 printf("Switch Software Reset !!!\n");
developer880c8292022-07-11 11:52:59 +08002598}
2599
developere78dab52024-03-25 14:26:39 +08002600void phy_set_fc(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08002601{
developere78dab52024-03-25 14:26:39 +08002602 unsigned int port = 0, pause_capable = 0;
2603 unsigned int phy_value = 0;
developerfed736e2024-07-12 14:00:34 +08002604 char *endptr;
developer880c8292022-07-11 11:52:59 +08002605
developerfed736e2024-07-12 14:00:34 +08002606 errno = 0;
2607 port = strtoul(argv[3], &endptr, 10);
2608 if (errno != 0 || *endptr != '\0' || port > MAX_PORT - 2) {
2609 printf("Error: wrong PHY port number, should be within 0~4\n");
2610 return;
2611 }
developer880c8292022-07-11 11:52:59 +08002612
developerfed736e2024-07-12 14:00:34 +08002613 errno = 0;
2614 pause_capable = strtoul(argv[4], &endptr, 10);
2615 if (errno != 0 || *endptr != '\0' || pause_capable > 1) {
2616 printf("Illegal parameter, full_duplex_pause_capable:0|1\n");
developere78dab52024-03-25 14:26:39 +08002617 return;
developer880c8292022-07-11 11:52:59 +08002618 }
developerfed736e2024-07-12 14:00:34 +08002619
developer880c8292022-07-11 11:52:59 +08002620 printf("port=%d, full_duplex_pause_capable:%d\n", port, pause_capable);
developere78dab52024-03-25 14:26:39 +08002621
developer880c8292022-07-11 11:52:59 +08002622 mii_mgr_read(port, 4, &phy_value);
2623 printf("read phy_value:0x%x\r\n", phy_value);
2624 phy_value &= (~(0x1 << 10));
2625 phy_value &= (~(0x1 << 11));
2626 if (pause_capable == 1) {
2627 phy_value |= (0x1 << 10);
2628 phy_value |= (0x1 << 11);
2629 }
2630 mii_mgr_write(port, 4, phy_value);
2631 printf("write phy_value:0x%x\r\n", phy_value);
developercc8110b2024-08-19 13:53:34 +08002632}
developer880c8292022-07-11 11:52:59 +08002633
developere78dab52024-03-25 14:26:39 +08002634void phy_set_an(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08002635{
developere78dab52024-03-25 14:26:39 +08002636 unsigned int port = 0, auto_negotiation_en = 0;
2637 unsigned int phy_value = 0;
developerfed736e2024-07-12 14:00:34 +08002638 char *endptr;
developer880c8292022-07-11 11:52:59 +08002639
developerfed736e2024-07-12 14:00:34 +08002640 errno = 0;
2641 port = strtoul(argv[3], &endptr, 10);
2642 if (errno != 0 || *endptr != '\0' || port > MAX_PORT - 2) {
2643 printf("Error: wrong PHY port number, should be within 0~4\n");
2644 return;
2645 }
developer880c8292022-07-11 11:52:59 +08002646
developerfed736e2024-07-12 14:00:34 +08002647 errno = 0;
2648 auto_negotiation_en = strtoul(argv[4], &endptr, 10);
2649 if (errno != 0 || *endptr != '\0' || auto_negotiation_en > 1) {
2650 printf("Illegal parameter, auto_negotiation_en:0|1\n");
developere78dab52024-03-25 14:26:39 +08002651 return;
developer880c8292022-07-11 11:52:59 +08002652 }
developerfed736e2024-07-12 14:00:34 +08002653
developer880c8292022-07-11 11:52:59 +08002654 printf("port=%d, auto_negotiation_en:%d\n", port, auto_negotiation_en);
developere78dab52024-03-25 14:26:39 +08002655
developer880c8292022-07-11 11:52:59 +08002656 mii_mgr_read(port, 0, &phy_value);
2657 printf("read phy_value:0x%x\r\n", phy_value);
2658 phy_value &= (~(1 << 12));
2659 phy_value |= (auto_negotiation_en << 12);
2660 mii_mgr_write(port, 0, phy_value);
2661 printf("write phy_value:0x%x\r\n", phy_value);
developercc8110b2024-08-19 13:53:34 +08002662}
developer880c8292022-07-11 11:52:59 +08002663
developere78dab52024-03-25 14:26:39 +08002664void set_mac_pfc(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08002665{
developere78dab52024-03-25 14:26:39 +08002666 unsigned int value = 0;
developerfed736e2024-07-12 14:00:34 +08002667 unsigned int port, enable = 0;
2668 char *endptr;
developer880c8292022-07-11 11:52:59 +08002669
developerfed736e2024-07-12 14:00:34 +08002670 errno = 0;
2671 port = strtoul(argv[3], &endptr, 10);
2672 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2673 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
developere78dab52024-03-25 14:26:39 +08002674 return;
developer880c8292022-07-11 11:52:59 +08002675 }
developerfed736e2024-07-12 14:00:34 +08002676
2677 errno = 0;
2678 enable = strtoul(argv[4], &endptr, 10);
2679 if (errno != 0 || *endptr != '\0' || enable > 1) {
2680 printf("Error: Illegal paramete, enable|diable:0|1\n");
2681 return;
2682 }
2683 printf("enable: %d\n", enable);
2684
developer5dfa8b72022-11-03 11:33:07 +08002685 if (chip_name == 0x7531 || chip_name == 0x7988) {
developer880c8292022-07-11 11:52:59 +08002686 reg_read(REG_PFC_CTRL_ADDR, &value);
2687 value &= ~(1 << port);
2688 value |= (enable << port);
2689 printf("write reg: %x, value: %x\n", REG_PFC_CTRL_ADDR, value);
2690 reg_write(REG_PFC_CTRL_ADDR, value);
developere78dab52024-03-25 14:26:39 +08002691 } else
developer880c8292022-07-11 11:52:59 +08002692 printf("\nCommand not support by this chip.\n");
developer880c8292022-07-11 11:52:59 +08002693}
2694
developere78dab52024-03-25 14:26:39 +08002695void global_set_mac_fc(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08002696{
2697 unsigned char enable = 0;
developere78dab52024-03-25 14:26:39 +08002698 unsigned int value = 0, reg = 0;
developer880c8292022-07-11 11:52:59 +08002699
2700 if (chip_name == 0x7530) {
2701 enable = atoi(argv[3]);
2702 printf("enable: %d\n", enable);
2703
developere78dab52024-03-25 14:26:39 +08002704 /*Check the input parameters is right or not. */
developer880c8292022-07-11 11:52:59 +08002705 if (enable > 1) {
2706 printf(HELP_MACCTL_FC);
developere78dab52024-03-25 14:26:39 +08002707 return;
developer880c8292022-07-11 11:52:59 +08002708 }
2709 reg_write(0x7000, 0x3);
2710 reg = REG_GFCCR0_ADDR;
2711 reg_read(REG_GFCCR0_ADDR, &value);
2712 value &= (~REG_FC_EN_MASK);
2713 value |= (enable << REG_FC_EN_OFFT);
2714 printf("write reg: %x, value: %x\n", reg, value);
2715 reg_write(REG_GFCCR0_ADDR, value);
2716 } else
2717 printf("\r\nCommand not support by this chip.\n");
developere78dab52024-03-25 14:26:39 +08002718} /*end mac_set_fc */
developer880c8292022-07-11 11:52:59 +08002719
developere78dab52024-03-25 14:26:39 +08002720void qos_sch_select(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08002721{
developere78dab52024-03-25 14:26:39 +08002722 unsigned char port = 0, queue = 0;
developer5dfa8b72022-11-03 11:33:07 +08002723 unsigned char type = 0;
developere78dab52024-03-25 14:26:39 +08002724 unsigned int value = 0, reg = 0;
developerfed736e2024-07-12 14:00:34 +08002725 char *endptr;
developer880c8292022-07-11 11:52:59 +08002726
2727 if (argc < 7)
developere78dab52024-03-25 14:26:39 +08002728 return;
developer880c8292022-07-11 11:52:59 +08002729
developerfed736e2024-07-12 14:00:34 +08002730 errno = 0;
2731 port = strtoul(argv[3], &endptr, 10);
2732 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2733 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2734 return;
2735 }
developer880c8292022-07-11 11:52:59 +08002736
developerfed736e2024-07-12 14:00:34 +08002737 errno = 0;
2738 queue = strtoul(argv[4], &endptr, 10);
2739 if (errno != 0 || *endptr != '\0' || queue > 7) {
2740 printf("Error: wrong port queue member\n");
developere78dab52024-03-25 14:26:39 +08002741 return;
developer880c8292022-07-11 11:52:59 +08002742 }
developer5dfa8b72022-11-03 11:33:07 +08002743
developerfed736e2024-07-12 14:00:34 +08002744 errno = 0;
2745 type = strtoul(argv[6], &endptr, 10);
2746 if (errno != 0 || *endptr != '\0' || type > 2) {
developer880c8292022-07-11 11:52:59 +08002747 printf(HELP_QOS_TYPE);
developere78dab52024-03-25 14:26:39 +08002748 return;
developer880c8292022-07-11 11:52:59 +08002749 }
2750
developere78dab52024-03-25 14:26:39 +08002751 printf("\r\nswitch qos type: %d.\n", type);
developer880c8292022-07-11 11:52:59 +08002752
2753 if (!strncmp(argv[5], "min", 4)) {
2754
2755 if (type == 0) {
developere78dab52024-03-25 14:26:39 +08002756 /*min sharper-->round roubin, disable min sharper rate limit */
developer880c8292022-07-11 11:52:59 +08002757 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2758 reg_read(reg, &value);
developer5dfa8b72022-11-03 11:33:07 +08002759 value = 0x0;
developer880c8292022-07-11 11:52:59 +08002760 reg_write(reg, value);
2761 } else if (type == 1) {
developere78dab52024-03-25 14:26:39 +08002762 /*min sharper-->sp, disable min sharper rate limit */
developer880c8292022-07-11 11:52:59 +08002763 reg = GSW_MMSCR0_Q(queue) + 0x100 * port;
2764 reg_read(reg, &value);
developer5dfa8b72022-11-03 11:33:07 +08002765 value = 0x0;
developer880c8292022-07-11 11:52:59 +08002766 value |= (1 << 31);
2767 reg_write(reg, value);
2768 } else {
2769 printf("min sharper only support: rr or sp\n");
developere78dab52024-03-25 14:26:39 +08002770 return;
developer880c8292022-07-11 11:52:59 +08002771 }
2772 } else if (!strncmp(argv[5], "max", 4)) {
2773 if (type == 1) {
developere78dab52024-03-25 14:26:39 +08002774 /*max sharper-->sp, disable max sharper rate limit */
developer880c8292022-07-11 11:52:59 +08002775 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2776 reg_read(reg, &value);
developer5dfa8b72022-11-03 11:33:07 +08002777 value = 0x0;
developer880c8292022-07-11 11:52:59 +08002778 value |= (1 << 31);
2779 reg_write(reg, value);
2780 } else if (type == 2) {
developere78dab52024-03-25 14:26:39 +08002781 /*max sharper-->wfq, disable max sharper rate limit */
developer880c8292022-07-11 11:52:59 +08002782 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2783 reg_read(reg, &value);
developer5dfa8b72022-11-03 11:33:07 +08002784 value = 0x0;
developer880c8292022-07-11 11:52:59 +08002785 reg_write(reg, value);
2786 } else {
2787 printf("max sharper only support: wfq or sp\n");
developere78dab52024-03-25 14:26:39 +08002788 return;
developer880c8292022-07-11 11:52:59 +08002789 }
2790 } else {
developere78dab52024-03-25 14:26:39 +08002791 printf("\r\nIllegal sharper:%s\n", argv[5]);
2792 return;
developer880c8292022-07-11 11:52:59 +08002793 }
developere78dab52024-03-25 14:26:39 +08002794 printf("reg:0x%x--value:0x%x\n", reg, value);
developer880c8292022-07-11 11:52:59 +08002795}
2796
developer5dfa8b72022-11-03 11:33:07 +08002797void get_upw(unsigned int *value, unsigned char base)
developer880c8292022-07-11 11:52:59 +08002798{
2799 *value &= (~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
2800 (0x7 << 16) | (0x7 << 20)));
developere78dab52024-03-25 14:26:39 +08002801 switch (base) {
2802 case 0: /* port-based 0x2x40[18:16] */
2803 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2804 (0x2 << 12) | (0x7 << 16) | (0x2 << 20));
2805 break;
2806 case 1: /* tagged-based 0x2x40[10:8] */
2807 *value |= ((0x2 << 0) | (0x2 << 4) | (0x7 << 8) |
2808 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2809 break;
2810 case 2: /* DSCP-based 0x2x40[14:12] */
2811 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2812 (0x7 << 12) | (0x2 << 16) | (0x2 << 20));
2813 break;
2814 case 3: /* acl-based 0x2x40[2:0] */
2815 *value |= ((0x7 << 0) | (0x2 << 4) | (0x2 << 8) |
2816 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2817 break;
2818 case 4: /* arl-based 0x2x40[22:20] */
2819 *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) |
2820 (0x2 << 12) | (0x2 << 16) | (0x7 << 20));
2821 break;
2822 case 5: /* stag-based 0x2x40[6:4] */
2823 *value |= ((0x2 << 0) | (0x7 << 4) | (0x2 << 8) |
2824 (0x2 << 12) | (0x2 << 16) | (0x2 << 20));
2825 break;
2826 default:
2827 break;
developer880c8292022-07-11 11:52:59 +08002828 }
2829}
2830
2831void qos_set_base(int argc, char *argv[])
2832{
developer5dfa8b72022-11-03 11:33:07 +08002833 unsigned char base = 0;
developere78dab52024-03-25 14:26:39 +08002834 unsigned char port = 0;
2835 unsigned int value = 0;
developerfed736e2024-07-12 14:00:34 +08002836 char *endptr;
developer880c8292022-07-11 11:52:59 +08002837
2838 if (argc < 5)
2839 return;
2840
developerfed736e2024-07-12 14:00:34 +08002841 errno = 0;
2842 port = strtoul(argv[3], &endptr, 10);
2843 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2844 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
developer880c8292022-07-11 11:52:59 +08002845 return;
2846 }
2847
developerfed736e2024-07-12 14:00:34 +08002848 errno = 0;
2849 base = strtoul(argv[4], &endptr, 10);
2850 if (errno != 0 || *endptr != '\0' || base > 5) {
2851 printf(HELP_QOS_BASE);
developer880c8292022-07-11 11:52:59 +08002852 return;
2853 }
2854
2855 printf("\r\nswitch qos base : %d. (port-based:0, tag-based:1,\
developere78dab52024-03-25 14:26:39 +08002856 dscp-based:2, acl-based:3, arl-based:4, stag-based:5)\n", base);
developer880c8292022-07-11 11:52:59 +08002857 if (chip_name == 0x7530) {
2858
2859 reg_read(0x44, &value);
2860 get_upw(&value, base);
2861 reg_write(0x44, value);
2862 printf("reg: 0x44, value: 0x%x\n", value);
2863
developer5dfa8b72022-11-03 11:33:07 +08002864 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developer880c8292022-07-11 11:52:59 +08002865
2866 reg_read(GSW_UPW(port), &value);
2867 get_upw(&value, base);
2868 reg_write(GSW_UPW(port), value);
developere78dab52024-03-25 14:26:39 +08002869 printf("reg:0x%x, value: 0x%x\n", GSW_UPW(port), value);
developer880c8292022-07-11 11:52:59 +08002870
2871 } else {
2872 printf("unknown switch device");
2873 return;
2874 }
2875}
2876
2877void qos_wfq_set_weight(int argc, char *argv[])
2878{
developere78dab52024-03-25 14:26:39 +08002879 int port = 0, weight[8], i = 0;
2880 unsigned char queue = 0;
2881 unsigned int reg = 0, value = 0;
developer880c8292022-07-11 11:52:59 +08002882
2883 port = atoi(argv[3]);
2884
developercc8110b2024-08-19 13:53:34 +08002885 for (i = 0; i < 8; i++)
developer880c8292022-07-11 11:52:59 +08002886 weight[i] = atoi(argv[i + 4]);
developer880c8292022-07-11 11:52:59 +08002887
2888 /* MT7530 total 7 port */
2889 if (port < 0 || port > 6) {
2890 printf(HELP_QOS_PORT_WEIGHT);
2891 return;
2892 }
2893
2894 for (i = 0; i < 8; i++) {
2895 if (weight[i] < 1 || weight[i] > 16) {
2896 printf(HELP_QOS_PORT_WEIGHT);
2897 return;
2898 }
2899 }
2900 printf("port: %x, q0: %x, q1: %x, q2: %x, q3: %x, \
developere78dab52024-03-25 14:26:39 +08002901 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]);
developer880c8292022-07-11 11:52:59 +08002902
2903 for (queue = 0; queue < 8; queue++) {
2904 reg = GSW_MMSCR1_Q(queue) + 0x100 * port;
2905 reg_read(reg, &value);
developere78dab52024-03-25 14:26:39 +08002906 value &= (~(0xf << 24)); //bit24~27
developer880c8292022-07-11 11:52:59 +08002907 value |= (((weight[queue] - 1) & 0xf) << 24);
2908 printf("reg: %x, value: %x\n", reg, value);
2909 reg_write(reg, value);
2910 }
2911}
2912
2913void qos_set_portpri(int argc, char *argv[])
2914{
developere78dab52024-03-25 14:26:39 +08002915 unsigned char port = 0, prio = 0;
2916 unsigned int value = 0;
developerfed736e2024-07-12 14:00:34 +08002917 char *endptr;
developer880c8292022-07-11 11:52:59 +08002918
developerfed736e2024-07-12 14:00:34 +08002919 errno = 0;
2920 port = strtoul(argv[3], &endptr, 10);
2921 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2922 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2923 return;
2924 }
developer880c8292022-07-11 11:52:59 +08002925
developerfed736e2024-07-12 14:00:34 +08002926 errno = 0;
2927 prio = strtoul(argv[4], &endptr, 10);
2928 if (errno != 0 || *endptr != '\0' || prio > 7) {
2929 printf("Error: wrong priority, should be within 0~7\n");
developer880c8292022-07-11 11:52:59 +08002930 return;
2931 }
2932
2933 reg_read(GSW_PCR(port), &value);
2934 value &= (~(0x7 << 24));
2935 value |= (prio << 24);
2936 reg_write(GSW_PCR(port), value);
2937 printf("write reg: %x, value: %x\n", GSW_PCR(port), value);
2938}
2939
2940void qos_set_dscppri(int argc, char *argv[])
2941{
developere78dab52024-03-25 14:26:39 +08002942 unsigned char prio = 0, dscp = 0, pim_n = 0, pim_offset = 0;
2943 unsigned int value = 0, reg = 0;
developerfed736e2024-07-12 14:00:34 +08002944 char *endptr;
developer880c8292022-07-11 11:52:59 +08002945
developerfed736e2024-07-12 14:00:34 +08002946 errno = 0;
2947 dscp = strtoul(argv[3], &endptr, 10);
2948 if (errno != 0 || *endptr != '\0' || dscp > 63) {
2949 printf(HELP_QOS_DSCP_PRIO);
2950 return;
2951 }
developer880c8292022-07-11 11:52:59 +08002952
developerfed736e2024-07-12 14:00:34 +08002953 errno = 0;
2954 prio = strtoul(argv[4], &endptr, 10);
2955 if (errno != 0 || *endptr != '\0' || prio > 7) {
developer880c8292022-07-11 11:52:59 +08002956 printf(HELP_QOS_DSCP_PRIO);
2957 return;
2958 }
2959
2960 pim_n = dscp / 10;
2961 pim_offset = (dscp - pim_n * 10) * 3;
2962 reg = 0x0058 + pim_n * 4;
2963 reg_read(reg, &value);
2964 value &= (~(0x7 << pim_offset));
2965 value |= ((prio & 0x7) << pim_offset);
2966 reg_write(reg, value);
2967 printf("write reg: %x, value: %x\n", reg, value);
2968}
2969
2970void qos_pri_mapping_queue(int argc, char *argv[])
2971{
developere78dab52024-03-25 14:26:39 +08002972 unsigned char prio = 0, queue = 0, pem_n = 0, port = 0;
2973 unsigned int value = 0, reg = 0;
developerfed736e2024-07-12 14:00:34 +08002974 char *endptr;
developer880c8292022-07-11 11:52:59 +08002975
2976 if (argc < 6)
2977 return;
2978
developerfed736e2024-07-12 14:00:34 +08002979 errno = 0;
2980 port = strtoul(argv[3], &endptr, 10);
2981 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
2982 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
2983 return;
2984 }
2985
2986 errno = 0;
2987 prio = strtoul(argv[4], &endptr, 10);
2988 if (errno != 0 || *endptr != '\0' || prio > 7) {
2989 printf(HELP_QOS_PRIO_QMAP);
2990 return;
2991 }
developer880c8292022-07-11 11:52:59 +08002992
developerfed736e2024-07-12 14:00:34 +08002993 errno = 0;
2994 queue = strtoul(argv[5], &endptr, 10);
2995 if (errno != 0 || *endptr != '\0' || queue > 7) {
developer880c8292022-07-11 11:52:59 +08002996 printf(HELP_QOS_PRIO_QMAP);
2997 return;
2998 }
developere78dab52024-03-25 14:26:39 +08002999
developer880c8292022-07-11 11:52:59 +08003000 if (chip_name == 0x7530) {
3001 pem_n = prio / 2;
3002 reg = pem_n * 0x4 + 0x48;
3003 reg_read(reg, &value);
3004 if (prio % 2) {
3005 value &= (~(0x7 << 24));
3006 value |= ((queue & 0x7) << 24);
3007 } else {
3008 value &= (~(0x7 << 8));
3009 value |= ((queue & 0x7) << 8);
3010 }
3011 reg_write(reg, value);
3012 printf("write reg: %x, value: %x\n", reg, value);
developer5dfa8b72022-11-03 11:33:07 +08003013 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
developer880c8292022-07-11 11:52:59 +08003014 pem_n = prio / 2;
3015 reg = GSW_PEM(pem_n) + 0x100 * port;
3016 reg_read(reg, &value);
developere78dab52024-03-25 14:26:39 +08003017 if (prio % 2) { // 1 1
developer880c8292022-07-11 11:52:59 +08003018 value &= (~(0x7 << 25));
3019 value |= ((queue & 0x7) << 25);
developere78dab52024-03-25 14:26:39 +08003020 } else { // 0 0
developer880c8292022-07-11 11:52:59 +08003021 value &= (~(0x7 << 9));
3022 value |= ((queue & 0x7) << 9);
3023 }
3024 reg_write(reg, value);
3025 printf("write reg: %x, value: %x\n", reg, value);
developere78dab52024-03-25 14:26:39 +08003026 } else {
developer880c8292022-07-11 11:52:59 +08003027 printf("unknown switch device");
3028 return;
3029 }
3030}
3031
3032static int macMT753xVlanSetVid(unsigned char index, unsigned char active,
developere78dab52024-03-25 14:26:39 +08003033 unsigned short vid, unsigned char portMap,
3034 unsigned char tagPortMap, unsigned char ivl_en,
3035 unsigned char fid, unsigned short stag)
developer880c8292022-07-11 11:52:59 +08003036{
3037 unsigned int value = 0;
3038 unsigned int value2 = 0;
developere78dab52024-03-25 14:26:39 +08003039 unsigned int reg = 0;
3040 int i = 0;
developer880c8292022-07-11 11:52:59 +08003041
3042 printf("index: %x, active: %x, vid: %x, portMap: %x, \
developere78dab52024-03-25 14:26:39 +08003043 tagPortMap: %x, ivl_en: %x, fid: %x, stag: %x\n", index, active, vid, portMap, tagPortMap, ivl_en, fid, stag);
developer880c8292022-07-11 11:52:59 +08003044
3045 value = (portMap << 16);
3046 value |= (stag << 4);
3047 value |= (ivl_en << 30);
3048 value |= (fid << 1);
3049 value |= (active ? 1 : 0);
3050
3051 // total 7 ports
3052 for (i = 0; i < 7; i++) {
3053 if (tagPortMap & (1 << i))
3054 value2 |= 0x2 << (i * 2);
3055 }
3056
3057 if (value2)
developere78dab52024-03-25 14:26:39 +08003058 value |= (1 << 28); // eg_tag
developer880c8292022-07-11 11:52:59 +08003059
developere78dab52024-03-25 14:26:39 +08003060 reg = 0x98; // VAWD2
developer880c8292022-07-11 11:52:59 +08003061 reg_write(reg, value2);
3062
developere78dab52024-03-25 14:26:39 +08003063 reg = 0x94; // VAWD1
developer880c8292022-07-11 11:52:59 +08003064 reg_write(reg, value);
3065
developere78dab52024-03-25 14:26:39 +08003066 reg = 0x90; // VTCR
developer880c8292022-07-11 11:52:59 +08003067 value = (0x80001000 + vid);
3068 reg_write(reg, value);
3069
developere78dab52024-03-25 14:26:39 +08003070 reg = 0x90; // VTCR
developer880c8292022-07-11 11:52:59 +08003071 while (1) {
3072 reg_read(reg, &value);
developere78dab52024-03-25 14:26:39 +08003073 if ((value & 0x80000000) == 0) //table busy
developer880c8292022-07-11 11:52:59 +08003074 break;
3075 }
3076
3077 /* switch clear */
3078 reg = 0x80;
3079 reg_write(reg, 0x8002);
3080 usleep(5000);
3081 reg_read(reg, &value);
3082
3083 printf("SetVid: index:%d active:%d vid:%d portMap:%x tagPortMap:%x\r\n",
developercc8110b2024-08-19 13:53:34 +08003084 index, active, vid, portMap, tagPortMap);
developer880c8292022-07-11 11:52:59 +08003085 return 0;
3086
developere78dab52024-03-25 14:26:39 +08003087} /*end macMT753xVlanSetVid */
developer880c8292022-07-11 11:52:59 +08003088
3089static int macMT753xVlanSetPvid(unsigned char port, unsigned short pvid)
3090{
developere78dab52024-03-25 14:26:39 +08003091 unsigned int value = 0;
3092 unsigned int reg = 0;
developer880c8292022-07-11 11:52:59 +08003093
developere78dab52024-03-25 14:26:39 +08003094 /*Parameters is error */
developer880c8292022-07-11 11:52:59 +08003095 if (port > 6)
3096 return -1;
3097
3098 reg = 0x2014 + (port * 0x100);
3099 reg_read(reg, &value);
3100 value &= ~0xfff;
3101 value |= pvid;
3102 reg_write(reg, value);
3103
3104 /* switch clear */
3105 reg = 0x80;
3106 reg_write(reg, 0x8002);
3107 usleep(5000);
3108 reg_read(reg, &value);
3109
3110 printf("SetPVID: port:%d pvid:%d\r\n", port, pvid);
3111 return 0;
3112}
developer880c8292022-07-11 11:52:59 +08003113
3114void doVlanSetPvid(int argc, char *argv[])
3115{
3116 unsigned char port = 0;
3117 unsigned short pvid = 0;
developerfed736e2024-07-12 14:00:34 +08003118 char *endptr;
developer880c8292022-07-11 11:52:59 +08003119
developerfed736e2024-07-12 14:00:34 +08003120 errno = 0;
3121 port = strtoul(argv[3], &endptr, 10);
3122 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3123 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3124 return;
3125 }
3126
3127 errno = 0;
3128 pvid = strtoul(argv[4], &endptr, 10);
3129 if (errno != 0 || *endptr != '\0' || pvid > MAX_VID_VALUE) {
developer880c8292022-07-11 11:52:59 +08003130 printf(HELP_VLAN_PVID);
3131 return;
3132 }
3133
3134 macMT753xVlanSetPvid(port, pvid);
3135
3136 printf("port:%d pvid:%d,vlancap: max_port:%d maxvid:%d\r\n",
developercc8110b2024-08-19 13:53:34 +08003137 port, pvid, SWITCH_MAX_PORT, MAX_VID_VALUE);
3138}
developer880c8292022-07-11 11:52:59 +08003139
3140void doVlanSetVid(int argc, char *argv[])
3141{
developerfed736e2024-07-12 14:00:34 +08003142 unsigned char index = 0, active = 0;
3143 unsigned char portMap = 0, tagPortMap = 0;
3144 unsigned short vid = 0, stag = 0;
3145 unsigned char ivl_en = 0, fid = 0;
3146 char *endptr;
developer880c8292022-07-11 11:52:59 +08003147
developerfed736e2024-07-12 14:00:34 +08003148 errno = 0;
3149 index = strtoul(argv[3], &endptr, 10);
3150 if (errno != 0 || *endptr != '\0' || index >= MAX_VLAN_RULE) {
3151 printf(HELP_VLAN_VID);
3152 return;
3153 }
3154
3155 errno = 0;
3156 active = strtoul(argv[4], &endptr, 10);
3157 if (errno != 0 || *endptr != '\0' || active > ACTIVED) {
3158 printf(HELP_VLAN_VID);
3159 return;
3160 }
developer880c8292022-07-11 11:52:59 +08003161
developerfed736e2024-07-12 14:00:34 +08003162 errno = 0;
3163 vid = strtoul(argv[5], &endptr, 10);
3164 if (errno != 0 || *endptr != '\0' || vid >= 4096) {
3165 printf(HELP_VLAN_VID);
3166 return;
3167 }
developer880c8292022-07-11 11:52:59 +08003168
developerfed736e2024-07-12 14:00:34 +08003169 errno = 0;
3170 portMap = strtoul(argv[6], &endptr, 10);
3171 if (errno != 0 || *endptr != '\0') {
developer880c8292022-07-11 11:52:59 +08003172 printf(HELP_VLAN_VID);
3173 return;
3174 }
3175
developerfed736e2024-07-12 14:00:34 +08003176 errno = 0;
3177 tagPortMap = strtoul(argv[7], &endptr, 10);
3178 if (errno != 0 || *endptr != '\0') {
3179 printf(HELP_VLAN_VID);
3180 return;
3181 }
developer880c8292022-07-11 11:52:59 +08003182
3183 printf("subcmd parameter argc = %d\r\n", argc);
3184 if (argc >= 9) {
developerfed736e2024-07-12 14:00:34 +08003185 errno = 0;
3186 ivl_en = strtoul(argv[8], &endptr, 10);
3187 if (errno != 0 || *endptr != '\0') {
3188 printf(HELP_VLAN_VID);
3189 return;
3190 }
developer880c8292022-07-11 11:52:59 +08003191 if (argc >= 10) {
developerfed736e2024-07-12 14:00:34 +08003192 errno = 0;
3193 fid = strtoul(argv[9], &endptr, 16);
3194 if (errno != 0 || *endptr != '\0') {
3195 printf(HELP_VLAN_VID);
3196 return;
3197 }
3198 if (argc >= 11) {
3199 errno = 0;
3200 stag = strtoul(argv[10], &endptr, 10);
3201 if (errno != 0 || *endptr != '\0') {
3202 printf(HELP_VLAN_VID);
3203 return;
3204 }
3205 }
developer880c8292022-07-11 11:52:59 +08003206 }
3207 }
3208 macMT753xVlanSetVid(index, active, vid, portMap, tagPortMap,
developercc8110b2024-08-19 13:53:34 +08003209 ivl_en, fid, stag);
developer880c8292022-07-11 11:52:59 +08003210 printf("index:%d active:%d vid:%d\r\n", index, active, vid);
developercc8110b2024-08-19 13:53:34 +08003211}
developer880c8292022-07-11 11:52:59 +08003212
3213void doVlanSetAccFrm(int argc, char *argv[])
3214{
3215 unsigned char port = 0;
3216 unsigned char type = 0;
developere78dab52024-03-25 14:26:39 +08003217 unsigned int value = 0;
3218 unsigned int reg = 0;
developerfed736e2024-07-12 14:00:34 +08003219 char *endptr;
developer880c8292022-07-11 11:52:59 +08003220
developerfed736e2024-07-12 14:00:34 +08003221 errno = 0;
3222 port = strtoul(argv[3], &endptr, 10);
3223 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3224 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3225 return;
3226 }
developer880c8292022-07-11 11:52:59 +08003227
developerfed736e2024-07-12 14:00:34 +08003228 errno = 0;
3229 type = strtoul(argv[4], &endptr, 10);
3230 if (errno != 0 || *endptr != '\0' || type > REG_PVC_ACC_FRM_RELMASK) {
developer880c8292022-07-11 11:52:59 +08003231 printf(HELP_VLAN_ACC_FRM);
3232 return;
3233 }
3234
developerfed736e2024-07-12 14:00:34 +08003235 printf("port: %d, type: %d\n", port, type);
3236
developer880c8292022-07-11 11:52:59 +08003237 reg = REG_PVC_P0_ADDR + port * 0x100;
3238 reg_read(reg, &value);
3239 value &= (~REG_PVC_ACC_FRM_MASK);
3240 value |= ((unsigned int)type << REG_PVC_ACC_FRM_OFFT);
3241
3242 printf("write reg: %x, value: %x\n", reg, value);
3243 reg_write(reg, value);
developercc8110b2024-08-19 13:53:34 +08003244}
developer880c8292022-07-11 11:52:59 +08003245
3246void doVlanSetPortAttr(int argc, char *argv[])
3247{
3248 unsigned char port = 0;
3249 unsigned char attr = 0;
developere78dab52024-03-25 14:26:39 +08003250 unsigned int value = 0;
3251 unsigned int reg = 0;
developerfed736e2024-07-12 14:00:34 +08003252 char *endptr;
developer880c8292022-07-11 11:52:59 +08003253
developerfed736e2024-07-12 14:00:34 +08003254 errno = 0;
3255 port = strtoul(argv[3], &endptr, 10);
3256 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3257 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3258 return;
3259 }
developer880c8292022-07-11 11:52:59 +08003260
developerfed736e2024-07-12 14:00:34 +08003261 errno = 0;
3262 attr = strtoul(argv[4], &endptr, 10);
3263 if (errno != 0 || *endptr != '\0' || attr > 3) {
developer880c8292022-07-11 11:52:59 +08003264 printf(HELP_VLAN_PORT_ATTR);
3265 return;
3266 }
3267
developerfed736e2024-07-12 14:00:34 +08003268 printf("port: %x, attr: %x\n", port, attr);
3269
developer880c8292022-07-11 11:52:59 +08003270 reg = 0x2010 + port * 0x100;
3271 reg_read(reg, &value);
3272 value &= (0xffffff3f);
3273 value |= (attr << 6);
3274
3275 printf("write reg: %x, value: %x\n", reg, value);
3276 reg_write(reg, value);
3277}
3278
3279void doVlanSetPortMode(int argc, char *argv[])
3280{
3281 unsigned char port = 0;
3282 unsigned char mode = 0;
developere78dab52024-03-25 14:26:39 +08003283 unsigned int value = 0;
3284 unsigned int reg = 0;
developerfed736e2024-07-12 14:00:34 +08003285 char *endptr;
developere78dab52024-03-25 14:26:39 +08003286
developerfed736e2024-07-12 14:00:34 +08003287 errno = 0;
3288 port = strtoul(argv[3], &endptr, 10);
3289 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3290 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3291 return;
3292 }
developer880c8292022-07-11 11:52:59 +08003293
developerfed736e2024-07-12 14:00:34 +08003294 errno = 0;
3295 mode = strtoul(argv[4], &endptr, 10);
3296 if (errno != 0 || *endptr != '\0' || mode > 3) {
developer880c8292022-07-11 11:52:59 +08003297 printf(HELP_VLAN_PORT_MODE);
3298 return;
3299 }
3300
developerfed736e2024-07-12 14:00:34 +08003301 printf("port: %x, mode: %x\n", port, mode);
3302
developer880c8292022-07-11 11:52:59 +08003303 reg = 0x2004 + port * 0x100;
3304 reg_read(reg, &value);
3305 value &= (~((1 << 0) | (1 << 1)));
3306 value |= (mode & 0x3);
3307 printf("write reg: %x, value: %x\n", reg, value);
3308 reg_write(reg, value);
3309}
3310
3311void doVlanSetEgressTagPCR(int argc, char *argv[])
3312{
3313 unsigned char port = 0;
3314 unsigned char eg_tag = 0;
developere78dab52024-03-25 14:26:39 +08003315 unsigned int value = 0;
3316 unsigned int reg = 0;
developerfed736e2024-07-12 14:00:34 +08003317 char *endptr;
developer880c8292022-07-11 11:52:59 +08003318
developerfed736e2024-07-12 14:00:34 +08003319 errno = 0;
3320 port = strtoul(argv[3], &endptr, 10);
3321 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3322 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3323 return;
3324 }
developer880c8292022-07-11 11:52:59 +08003325
developerfed736e2024-07-12 14:00:34 +08003326 errno = 0;
3327 eg_tag = strtoul(argv[4], &endptr, 10);
3328 if (errno != 0 || *endptr != '\0' || (eg_tag > REG_PCR_EG_TAG_RELMASK)) {
developer880c8292022-07-11 11:52:59 +08003329 printf(HELP_VLAN_EGRESS_TAG_PCR);
3330 return;
3331 }
3332
developerfed736e2024-07-12 14:00:34 +08003333 printf("port: %d, eg_tag: %d\n", port, eg_tag);
3334
developer880c8292022-07-11 11:52:59 +08003335 reg = REG_PCR_P0_ADDR + port * 0x100;
3336 reg_read(reg, &value);
3337 value &= (~REG_PCR_EG_TAG_MASK);
3338 value |= ((unsigned int)eg_tag << REG_PCR_EG_TAG_OFFT);
3339
3340 printf("write reg: %x, value: %x\n", reg, value);
3341 reg_write(reg, value);
3342
developere78dab52024-03-25 14:26:39 +08003343} /*end doVlanSetEgressTagPCR */
developer880c8292022-07-11 11:52:59 +08003344
3345void doVlanSetEgressTagPVC(int argc, char *argv[])
3346{
3347 unsigned char port = 0;
3348 unsigned char eg_tag = 0;
developere78dab52024-03-25 14:26:39 +08003349 unsigned int value = 0;
3350 unsigned int reg = 0;
developerfed736e2024-07-12 14:00:34 +08003351 char *endptr;
developer880c8292022-07-11 11:52:59 +08003352
developerfed736e2024-07-12 14:00:34 +08003353 errno = 0;
3354 port = strtoul(argv[3], &endptr, 10);
3355 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3356 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3357 return;
3358 }
developer880c8292022-07-11 11:52:59 +08003359
developerfed736e2024-07-12 14:00:34 +08003360 errno = 0;
3361 eg_tag = strtoul(argv[4], &endptr, 10);
3362 if (errno != 0 || *endptr != '\0' || (eg_tag > REG_PVC_EG_TAG_RELMASK)) {
developer880c8292022-07-11 11:52:59 +08003363 printf(HELP_VLAN_EGRESS_TAG_PVC);
3364 return;
3365 }
3366
developerfed736e2024-07-12 14:00:34 +08003367 printf("port: %d, eg_tag: %d\n", port, eg_tag);
3368
developer880c8292022-07-11 11:52:59 +08003369 reg = REG_PVC_P0_ADDR + port * 0x100;
3370 reg_read(reg, &value);
3371 value &= (~REG_PVC_EG_TAG_MASK);
3372 value |= ((unsigned int)eg_tag << REG_PVC_EG_TAG_OFFT);
3373
3374 printf("write reg: %x, value: %x\n", reg, value);
3375 reg_write(reg, value);
developere78dab52024-03-25 14:26:39 +08003376} /*end doVlanSetEgressTagPVC */
developer880c8292022-07-11 11:52:59 +08003377
3378void doArlAging(int argc, char *argv[])
3379{
3380 unsigned char aging_en = 0;
developerfed736e2024-07-12 14:00:34 +08003381 unsigned int time = 0, aging_cnt = 0, aging_unit = 0;
3382 unsigned int value = 0, reg = 0;
3383 char *endptr;
developer880c8292022-07-11 11:52:59 +08003384
developerfed736e2024-07-12 14:00:34 +08003385 errno = 0;
3386 aging_en = strtoul(argv[3], &endptr, 10);
3387 if (errno != 0 || *endptr != '\0' || aging_en > 1) {
3388 printf(HELP_ARL_AGING);
3389 return;
3390 }
developer880c8292022-07-11 11:52:59 +08003391
developerfed736e2024-07-12 14:00:34 +08003392 errno = 0;
3393 time = strtoul(argv[4], &endptr, 10);
3394 if (errno != 0 || *endptr != '\0' || (time <= 0 || time > 65536)) {
developer880c8292022-07-11 11:52:59 +08003395 printf(HELP_ARL_AGING);
3396 return;
3397 }
3398
developerfed736e2024-07-12 14:00:34 +08003399 printf("aging_en: %x, aging time: %x\n", aging_en, time);
3400
developer880c8292022-07-11 11:52:59 +08003401 reg = 0xa0;
3402 reg_read(reg, &value);
3403 value &= (~(1 << 20));
developercc8110b2024-08-19 13:53:34 +08003404 if (!aging_en)
developer880c8292022-07-11 11:52:59 +08003405 value |= (1 << 20);
developer880c8292022-07-11 11:52:59 +08003406
3407 aging_unit = (time / 0x100) + 1;
3408 aging_cnt = (time / aging_unit);
3409 aging_unit--;
3410 aging_cnt--;
3411
3412 value &= (0xfff00000);
3413 value |= ((aging_cnt << 12) | aging_unit);
3414
3415 printf("aging_unit: %x, aging_cnt: %x\n", aging_unit, aging_cnt);
3416 printf("write reg: %x, value: %x\n", reg, value);
3417
3418 reg_write(reg, value);
3419}
3420
3421void doMirrorEn(int argc, char *argv[])
3422{
developere78dab52024-03-25 14:26:39 +08003423 unsigned char mirror_en = 0;
3424 unsigned char mirror_port = 0;
3425 unsigned int value = 0, reg = 0;
developerfed736e2024-07-12 14:00:34 +08003426 char *endptr;
developer880c8292022-07-11 11:52:59 +08003427
developerfed736e2024-07-12 14:00:34 +08003428 errno = 0;
3429 mirror_en = strtoul(argv[3], &endptr, 10);
3430 if (errno != 0 || *endptr != '\0' || mirror_en > 1) {
3431 printf(HELP_MIRROR_EN);
3432 return;
3433 }
developer880c8292022-07-11 11:52:59 +08003434
developerfed736e2024-07-12 14:00:34 +08003435 errno = 0;
3436 mirror_port = strtoul(argv[4], &endptr, 10);
3437 if (errno != 0 || *endptr != '\0' || mirror_port > REG_CFC_MIRROR_PORT_RELMASK) {
developer880c8292022-07-11 11:52:59 +08003438 printf(HELP_MIRROR_EN);
3439 return;
3440 }
3441
developerfed736e2024-07-12 14:00:34 +08003442 printf("mirror_en: %d, mirror_port: %d\n", mirror_en, mirror_port);
3443
developer880c8292022-07-11 11:52:59 +08003444 reg = REG_CFC_ADDR;
3445 reg_read(reg, &value);
3446 value &= (~REG_CFC_MIRROR_EN_MASK);
3447 value |= (mirror_en << REG_CFC_MIRROR_EN_OFFT);
3448 value &= (~REG_CFC_MIRROR_PORT_MASK);
3449 value |= (mirror_port << REG_CFC_MIRROR_PORT_OFFT);
3450
3451 printf("write reg: %x, value: %x\n", reg, value);
3452 reg_write(reg, value);
3453
developere78dab52024-03-25 14:26:39 +08003454} /*end doMirrorEn */
developer880c8292022-07-11 11:52:59 +08003455
3456void doMirrorPortBased(int argc, char *argv[])
3457{
developere78dab52024-03-25 14:26:39 +08003458 unsigned char port = 0, port_tx_mir = 0, port_rx_mir = 0, vlan_mis =
3459 0, acl_mir = 0, igmp_mir = 0;
3460 unsigned int value = 0, reg = 0;
developerfed736e2024-07-12 14:00:34 +08003461 char *endptr;
developer880c8292022-07-11 11:52:59 +08003462
developerfed736e2024-07-12 14:00:34 +08003463 errno = 0;
3464 port = strtoul(argv[3], &endptr, 10);
3465 if (errno != 0 || *endptr != '\0' || port > MAX_PORT)
3466 goto error;
3467
3468 errno = 0;
3469 port_tx_mir = strtoul(argv[4], &endptr, 10);
3470 if (errno != 0 || *endptr != '\0' || port_tx_mir > 1)
3471 goto error;
3472
3473 errno = 0;
3474 port_rx_mir = strtoul(argv[5], &endptr, 10);
3475 if (errno != 0 || *endptr != '\0' || port_rx_mir > 1)
3476 goto error;
3477
3478 errno = 0;
3479 acl_mir = strtoul(argv[6], &endptr, 10);
3480 if (errno != 0 || *endptr != '\0' || acl_mir > 1)
3481 goto error;
3482
3483 errno = 0;
3484 vlan_mis = strtoul(argv[7], &endptr, 10);
3485 if (errno != 0 || *endptr != '\0' || vlan_mis > 1)
3486 goto error;
3487
3488 errno = 0;
3489 igmp_mir = strtoul(argv[8], &endptr, 10);
3490 if (errno != 0 || *endptr != '\0' || igmp_mir > 1)
3491 goto error;
developer880c8292022-07-11 11:52:59 +08003492
developercc8110b2024-08-19 13:53:34 +08003493 printf("port:%d, port_tx_mir:%d, port_rx_mir:%d, acl_mir:%d, vlan_mis:%d, igmp_mir:%d\n",
3494 port, port_tx_mir, port_rx_mir, acl_mir, vlan_mis, igmp_mir);
developer880c8292022-07-11 11:52:59 +08003495
developer880c8292022-07-11 11:52:59 +08003496 reg = REG_PCR_P0_ADDR + port * 0x100;
3497 reg_read(reg, &value);
developere78dab52024-03-25 14:26:39 +08003498 value &=
3499 ~(REG_PORT_TX_MIR_MASK | REG_PORT_RX_MIR_MASK | REG_PCR_ACL_MIR_MASK
3500 | REG_PCR_VLAN_MIS_MASK);
3501 value |=
3502 (port_tx_mir << REG_PORT_TX_MIR_OFFT) +
3503 (port_rx_mir << REG_PORT_RX_MIR_OFFT);
3504 value |=
3505 (acl_mir << REG_PCR_ACL_MIR_OFFT) +
3506 (vlan_mis << REG_PCR_VLAN_MIS_OFFT);
developer880c8292022-07-11 11:52:59 +08003507
3508 printf("write reg: %x, value: %x\n", reg, value);
3509 reg_write(reg, value);
3510
3511 reg = REG_PIC_P0_ADDR + port * 0x100;
3512 reg_read(reg, &value);
3513 value &= ~(REG_PIC_IGMP_MIR_MASK);
3514 value |= (igmp_mir << REG_PIC_IGMP_MIR_OFFT);
3515
3516 printf("write reg: %x, value: %x\n", reg, value);
3517 reg_write(reg, value);
developerfed736e2024-07-12 14:00:34 +08003518 return;
developer880c8292022-07-11 11:52:59 +08003519
developerfed736e2024-07-12 14:00:34 +08003520error:
3521 printf(HELP_MIRROR_PORTBASED);
3522 return;
developere78dab52024-03-25 14:26:39 +08003523} /*end doMirrorPortBased */
developer880c8292022-07-11 11:52:59 +08003524
3525void doStp(int argc, char *argv[])
3526{
3527 unsigned char port = 0;
3528 unsigned char fid = 0;
3529 unsigned char state = 0;
developere78dab52024-03-25 14:26:39 +08003530 unsigned int value = 0;
3531 unsigned int reg = 0;
developerfed736e2024-07-12 14:00:34 +08003532 char *endptr;
developer880c8292022-07-11 11:52:59 +08003533
developerfed736e2024-07-12 14:00:34 +08003534 errno = 0;
3535 port = strtoul(argv[2], &endptr, 10);
3536 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3537 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3538 return;
3539 }
developer880c8292022-07-11 11:52:59 +08003540
developerfed736e2024-07-12 14:00:34 +08003541 errno = 0;
3542 fid = strtoul(argv[3], &endptr, 10);
3543 if (errno != 0 || *endptr != '\0' || fid > 7) {
3544 printf(HELP_STP);
3545 return;
3546 }
developer880c8292022-07-11 11:52:59 +08003547
developerfed736e2024-07-12 14:00:34 +08003548 errno = 0;
3549 state = strtoul(argv[4], &endptr, 10);
3550 if (errno != 0 || *endptr != '\0' || state > 3) {
developer880c8292022-07-11 11:52:59 +08003551 printf(HELP_STP);
3552 return;
3553 }
3554
developerfed736e2024-07-12 14:00:34 +08003555 printf("port: %d, fid: %d, state: %d\n", port, fid, state);
3556
developer880c8292022-07-11 11:52:59 +08003557 reg = REG_SSC_P0_ADDR + port * 0x100;
3558 reg_read(reg, &value);
3559 value &= (~(3 << (fid << 2)));
3560 value |= ((unsigned int)state << (fid << 2));
3561
3562 printf("write reg: %x, value: %x\n", reg, value);
3563 reg_write(reg, value);
3564}
3565
developere78dab52024-03-25 14:26:39 +08003566void _ingress_rate_set(int on_off, int port, int bw)
developer880c8292022-07-11 11:52:59 +08003567{
developere78dab52024-03-25 14:26:39 +08003568 unsigned int reg = 0, value = 0;
developer880c8292022-07-11 11:52:59 +08003569
3570 reg = 0x1800 + (0x100 * port);
3571 value = 0;
developere78dab52024-03-25 14:26:39 +08003572 /*token-bucket */
developer880c8292022-07-11 11:52:59 +08003573 if (on_off == 1) {
3574 if (chip_name == 0x7530) {
developer5dfa8b72022-11-03 11:33:07 +08003575 if (bw > 1000000) {
developercc8110b2024-08-19 13:53:34 +08003576 printf("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n", bw);
developere78dab52024-03-25 14:26:39 +08003577 return;
developer880c8292022-07-11 11:52:59 +08003578 }
developercc8110b2024-08-19 13:53:34 +08003579 value = ((bw / 32) << 16) + (1 << 15) + (7 << 8) + (1 << 7) + 0x0f;
developer5dfa8b72022-11-03 11:33:07 +08003580 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3581 if ((chip_name == 0x7531) && (bw > 2500000)) {
developercc8110b2024-08-19 13:53:34 +08003582 printf("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n", bw);
developere78dab52024-03-25 14:26:39 +08003583 return;
developer880c8292022-07-11 11:52:59 +08003584 }
developer5dfa8b72022-11-03 11:33:07 +08003585
3586 if ((chip_name == 0x7988) && (bw > 4000000)) {
developercc8110b2024-08-19 13:53:34 +08003587 printf("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n", bw);
developere78dab52024-03-25 14:26:39 +08003588 return;
developer880c8292022-07-11 11:52:59 +08003589 }
developer5dfa8b72022-11-03 11:33:07 +08003590
developere78dab52024-03-25 14:26:39 +08003591 if (bw / 32 >= 65536) //supoort 2.5G case
developercc8110b2024-08-19 13:53:34 +08003592 value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (1 << 12) +
3593 (7 << 8) + 0xf;
developer5dfa8b72022-11-03 11:33:07 +08003594 else
developercc8110b2024-08-19 13:53:34 +08003595 value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (7 << 8) + 0xf;
developere78dab52024-03-25 14:26:39 +08003596 } else
developer880c8292022-07-11 11:52:59 +08003597 printf("unknow chip\n");
3598 }
developer880c8292022-07-11 11:52:59 +08003599#if leaky_bucket
3600 reg_read(reg, &value);
3601 value &= 0xffff0000;
developere78dab52024-03-25 14:26:39 +08003602 if (on_off == 1) {
developer880c8292022-07-11 11:52:59 +08003603 value |= on_off << 15;
3604 //7530 same as 7531
3605 if (bw < 100) {
3606 value |= (0x0 << 8);
3607 value |= bw;
3608 } else if (bw < 1000) {
3609 value |= (0x1 << 8);
3610 value |= bw / 10;
3611 } else if (bw < 10000) {
3612 value |= (0x2 << 8);
3613 value |= bw / 100;
3614 } else if (bw < 100000) {
3615 value |= (0x3 << 8);
3616 value |= bw / 1000;
3617 } else {
3618 value |= (0x4 << 8);
3619 value |= bw / 10000;
3620 }
3621 }
3622#endif
3623 reg_write(reg, value);
3624 reg = 0x1FFC;
3625 reg_read(reg, &value);
3626 value = 0x110104;
3627 reg_write(reg, value);
developere78dab52024-03-25 14:26:39 +08003628
3629 if (on_off)
3630 printf("switch port=%d, bw=%d\n", port, bw);
3631 else
3632 printf("switch port=%d ingress rate limit off\n", port);
developer880c8292022-07-11 11:52:59 +08003633}
3634
developere78dab52024-03-25 14:26:39 +08003635void ingress_rate_set(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08003636{
developere78dab52024-03-25 14:26:39 +08003637 int on_off = 0, port = 0, bw = 0;
developer1afdd342024-04-08 14:04:38 +08003638 char *endptr;
developere78dab52024-03-25 14:26:39 +08003639
developer1afdd342024-04-08 14:04:38 +08003640 /* clear errno before conversion to detect overflow */
3641 errno = 0;
3642 port = strtoul(argv[3], &endptr, 0);
3643
3644 if (errno == ERANGE) {
3645 printf("Conversion error, value out of range\n");
3646 return;
3647 }
3648 if (*endptr != '\0') {
3649 printf("Conversion error, no digits were found\n");
3650 return;
3651 }
3652
3653 if (port < 0 || port > 6) {
3654 printf("Wrong port range, should be within 0-6\n");
3655 return;
3656 }
3657
developere78dab52024-03-25 14:26:39 +08003658 if (argv[2][1] == 'n') {
developer1afdd342024-04-08 14:04:38 +08003659 errno = 0;
3660 bw = strtoul(argv[4], &endptr, 0);
3661 if (errno == ERANGE) {
3662 printf("Conversion error, value out of range\n");
3663 return;
3664 }
3665 if (*endptr != '\0') {
3666 printf("Conversion error, no digits were found\n");
3667 return;
3668 }
developere78dab52024-03-25 14:26:39 +08003669 on_off = 1;
3670 } else if (argv[2][1] == 'f') {
3671 if (argc != 4)
3672 return;
3673 on_off = 0;
3674 }
3675
3676 _ingress_rate_set(on_off, port, bw);
3677}
3678
3679void _egress_rate_set(int on_off, int port, int bw)
3680{
3681 unsigned int value = 0, reg = 0;
developer880c8292022-07-11 11:52:59 +08003682
3683 reg = 0x1040 + (0x100 * port);
3684 value = 0;
developere78dab52024-03-25 14:26:39 +08003685 /*token-bucket */
developer880c8292022-07-11 11:52:59 +08003686 if (on_off == 1) {
3687 if (chip_name == 0x7530) {
3688 if (bw < 0 || bw > 1000000) {
developercc8110b2024-08-19 13:53:34 +08003689 printf("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n", bw);
developere78dab52024-03-25 14:26:39 +08003690 return;
developer880c8292022-07-11 11:52:59 +08003691 }
developercc8110b2024-08-19 13:53:34 +08003692 value = ((bw / 32) << 16) + (1 << 15) + (7 << 8) + (1 << 7) + 0xf;
developer5dfa8b72022-11-03 11:33:07 +08003693 } else if (chip_name == 0x7531 || chip_name == 0x7988) {
3694 if ((chip_name == 0x7531) && (bw < 0 || bw > 2500000)) {
developercc8110b2024-08-19 13:53:34 +08003695 printf("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n", bw);
developere78dab52024-03-25 14:26:39 +08003696 return;
developer880c8292022-07-11 11:52:59 +08003697 }
developer5dfa8b72022-11-03 11:33:07 +08003698 if ((chip_name == 0x7988) && (bw < 0 || bw > 4000000)) {
developercc8110b2024-08-19 13:53:34 +08003699 printf("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n", bw);
developere78dab52024-03-25 14:26:39 +08003700 return;
developer5dfa8b72022-11-03 11:33:07 +08003701 }
3702
developere78dab52024-03-25 14:26:39 +08003703 if (bw / 32 >= 65536) //support 2.5G cases
developercc8110b2024-08-19 13:53:34 +08003704 value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (1 << 12) +
3705 (7 << 8) + 0xf;
developer5dfa8b72022-11-03 11:33:07 +08003706 else
developercc8110b2024-08-19 13:53:34 +08003707 value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (7 << 8) + 0xf;
developere78dab52024-03-25 14:26:39 +08003708 } else
developer880c8292022-07-11 11:52:59 +08003709 printf("unknow chip\n");
3710 }
3711 reg_write(reg, value);
3712 reg = 0x10E0;
3713 reg_read(reg, &value);
3714 value &= 0x18;
3715 reg_write(reg, value);
3716
developere78dab52024-03-25 14:26:39 +08003717 if (on_off)
3718 printf("switch port=%d, bw=%d\n", port, bw);
3719 else
3720 printf("switch port=%d egress rate limit off\n", port);
3721}
3722
3723void egress_rate_set(int argc, char *argv[])
3724{
3725 unsigned int value = 0, reg = 0;
3726 int on_off = 0, port = 0, bw = 0;
developer1afdd342024-04-08 14:04:38 +08003727 char *endptr;
developere78dab52024-03-25 14:26:39 +08003728
developer1afdd342024-04-08 14:04:38 +08003729 /* clear errno before conversion to detect overflow */
3730 errno = 0;
3731 port = strtoul(argv[3], &endptr, 0);
3732 if (errno == ERANGE) {
3733 printf("Conversion error, value out of range\n");
3734 return;
3735 }
3736 if (*endptr != '\0') {
3737 printf("Conversion error, no digits were found\n");
3738 return;
3739 }
3740 if (port < 0 || port > 6) {
3741 printf("Wrong port range, should be within 0-6\n");
3742 return;
3743 }
developere78dab52024-03-25 14:26:39 +08003744 if (argv[2][1] == 'n') {
developer1afdd342024-04-08 14:04:38 +08003745 errno = 0;
3746 bw = strtoul(argv[4], &endptr, 0);
3747 if (errno == ERANGE) {
3748 printf("Conversion error, value out of range\n");
3749 return;
3750 }
3751 if (*endptr != '\0') {
3752 printf("Conversion error, no digits were found\n");
3753 return;
3754 }
developere78dab52024-03-25 14:26:39 +08003755 on_off = 1;
3756 } else if (argv[2][1] == 'f') {
3757 if (argc != 4)
3758 return;
3759 on_off = 0;
3760 }
3761
3762 _egress_rate_set(on_off, port, bw);
developer880c8292022-07-11 11:52:59 +08003763}
3764
3765void rate_control(int argc, char *argv[])
3766{
3767 unsigned char dir = 0;
3768 unsigned char port = 0;
3769 unsigned int rate = 0;
developerfed736e2024-07-12 14:00:34 +08003770 char *endptr;
developer880c8292022-07-11 11:52:59 +08003771
developerfed736e2024-07-12 14:00:34 +08003772 errno = 0;
3773 dir = strtoul(argv[2], &endptr, 10);
3774 if (errno != 0 || *endptr != '\0' || dir > 1) {
3775 printf("Error: wrong port member, should be 0:egress, 1:ingress\n");
3776 return;
3777 }
developer880c8292022-07-11 11:52:59 +08003778
developerfed736e2024-07-12 14:00:34 +08003779 errno = 0;
3780 port = strtoul(argv[3], &endptr, 10);
3781 if (errno != 0 || *endptr != '\0' || port > MAX_PORT) {
3782 printf("Error: wrong port member, should be within 0~%d\n", MAX_PORT);
3783 return;
3784 }
3785
3786 errno = 0;
3787 rate = strtoul(argv[4], &endptr, 10);
3788 if (errno != 0 || *endptr != '\0') {
3789 printf("Error: wrong traffic rate, unit is kbps\n");
developer880c8292022-07-11 11:52:59 +08003790 return;
developerfed736e2024-07-12 14:00:34 +08003791 }
developer880c8292022-07-11 11:52:59 +08003792
developere78dab52024-03-25 14:26:39 +08003793 if (dir == 1) //ingress
3794 _ingress_rate_set(1, port, rate);
3795 else if (dir == 0) //egress
3796 _egress_rate_set(1, port, rate);
developer880c8292022-07-11 11:52:59 +08003797}
3798
developere78dab52024-03-25 14:26:39 +08003799void collision_pool_enable(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08003800{
3801
developere78dab52024-03-25 14:26:39 +08003802 unsigned char enable = 0;
3803 unsigned int value = 0, reg = 0;
developer880c8292022-07-11 11:52:59 +08003804
3805 enable = atoi(argv[3]);
3806
developere78dab52024-03-25 14:26:39 +08003807 /*Check the input parameters is right or not. */
developer5dfa8b72022-11-03 11:33:07 +08003808 if (enable > 1) {
developer880c8292022-07-11 11:52:59 +08003809 printf(HELP_COLLISION_POOL_EN);
developere78dab52024-03-25 14:26:39 +08003810 return;
developer880c8292022-07-11 11:52:59 +08003811 }
3812
developercc8110b2024-08-19 13:53:34 +08003813 printf("collision pool enable: %d\n", enable);
developer5dfa8b72022-11-03 11:33:07 +08003814 if (chip_name == 0x7531 || chip_name == 0x7988) {
developer880c8292022-07-11 11:52:59 +08003815 reg = REG_CPGC_ADDR;
developere78dab52024-03-25 14:26:39 +08003816 if (enable == 1) {
developer880c8292022-07-11 11:52:59 +08003817 /* active reset */
3818 reg_read(reg, &value);
3819 value &= (~REG_CPCG_COL_RST_N_MASK);
3820 reg_write(reg, value);
3821
3822 /* enanble clock */
3823 reg_read(reg, &value);
3824 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3825 value |= (1 << REG_CPCG_COL_CLK_EN_OFFT);
3826 reg_write(reg, value);
3827
3828 /* inactive reset */
3829 reg_read(reg, &value);
3830 value &= (~REG_CPCG_COL_RST_N_MASK);
3831 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3832 reg_write(reg, value);
3833
3834 /* enable collision pool */
3835 reg_read(reg, &value);
3836 value &= (~REG_CPCG_COL_EN_MASK);
3837 value |= (1 << REG_CPCG_COL_EN_OFFT);
3838 reg_write(reg, value);
3839
3840 reg_read(reg, &value);
3841 printf("write reg: %x, value: %x\n", reg, value);
developere78dab52024-03-25 14:26:39 +08003842 } else {
developer880c8292022-07-11 11:52:59 +08003843
3844 /* disable collision pool */
3845 reg_read(reg, &value);
3846 value &= (~REG_CPCG_COL_EN_MASK);
3847 reg_write(reg, value);
3848
3849 /* active reset */
3850 reg_read(reg, &value);
3851 value &= (~REG_CPCG_COL_RST_N_MASK);
3852 reg_write(reg, value);
3853
3854 /* inactive reset */
3855 reg_read(reg, &value);
3856 value &= (~REG_CPCG_COL_RST_N_MASK);
3857 value |= (1 << REG_CPCG_COL_RST_N_OFFT);
3858 reg_write(reg, value);
3859
3860 /* disable clock */
3861 reg_read(reg, &value);
3862 value &= (~REG_CPCG_COL_CLK_EN_MASK);
3863 reg_write(reg, value);
3864
3865 reg_read(reg, &value);
3866 printf("write reg: %x, value: %x\n", reg, value);
3867
3868 }
developere78dab52024-03-25 14:26:39 +08003869 } else {
developer880c8292022-07-11 11:52:59 +08003870 printf("\nCommand not support by this chip.\n");
developere78dab52024-03-25 14:26:39 +08003871 }
developer880c8292022-07-11 11:52:59 +08003872}
3873
developere78dab52024-03-25 14:26:39 +08003874void collision_pool_mac_dump(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08003875{
developere78dab52024-03-25 14:26:39 +08003876 unsigned int value = 0, reg = 0;
developer880c8292022-07-11 11:52:59 +08003877
developer5dfa8b72022-11-03 11:33:07 +08003878 if (chip_name == 0x7531 || chip_name == 0x7988) {
developer880c8292022-07-11 11:52:59 +08003879 reg = REG_CPGC_ADDR;
3880 reg_read(reg, &value);
developere78dab52024-03-25 14:26:39 +08003881 if (value & REG_CPCG_COL_EN_MASK)
developer880c8292022-07-11 11:52:59 +08003882 table_dump_internal(COLLISION_TABLE);
3883 else
developercc8110b2024-08-19 13:53:34 +08003884 printf("\ncollision pool is disabled, please enable it before use this command.\n");
developere78dab52024-03-25 14:26:39 +08003885 } else {
developer880c8292022-07-11 11:52:59 +08003886 printf("\nCommand not support by this chip.\n");
3887 }
3888}
3889
developere78dab52024-03-25 14:26:39 +08003890void collision_pool_dip_dump(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08003891{
developere78dab52024-03-25 14:26:39 +08003892 unsigned int value = 0, reg = 0;
developer880c8292022-07-11 11:52:59 +08003893
developer5dfa8b72022-11-03 11:33:07 +08003894 if (chip_name == 0x7531 || chip_name == 0x7988) {
developer880c8292022-07-11 11:52:59 +08003895 reg = REG_CPGC_ADDR;
3896 reg_read(reg, &value);
developere78dab52024-03-25 14:26:39 +08003897 if (value & REG_CPCG_COL_EN_MASK)
developer880c8292022-07-11 11:52:59 +08003898 dip_dump_internal(COLLISION_TABLE);
3899 else
developercc8110b2024-08-19 13:53:34 +08003900 printf("\ncollision pool is disabled, please enable it before use this command.\n");
developere78dab52024-03-25 14:26:39 +08003901 } else {
developer880c8292022-07-11 11:52:59 +08003902 printf("\nCommand not support by this chip.\n");
3903 }
developer880c8292022-07-11 11:52:59 +08003904}
3905
developere78dab52024-03-25 14:26:39 +08003906void collision_pool_sip_dump(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08003907{
developere78dab52024-03-25 14:26:39 +08003908 unsigned int value = 0, reg = 0;
developer880c8292022-07-11 11:52:59 +08003909
developere78dab52024-03-25 14:26:39 +08003910 if (chip_name == 0x7531 || chip_name == 0x7988) {
developer880c8292022-07-11 11:52:59 +08003911 reg = REG_CPGC_ADDR;
3912 reg_read(reg, &value);
developere78dab52024-03-25 14:26:39 +08003913 if (value & REG_CPCG_COL_EN_MASK)
developer880c8292022-07-11 11:52:59 +08003914 sip_dump_internal(COLLISION_TABLE);
3915 else
developercc8110b2024-08-19 13:53:34 +08003916 printf("\ncollision pool is disabled, please enable it before use this command.\n");
developere78dab52024-03-25 14:26:39 +08003917 } else {
developer880c8292022-07-11 11:52:59 +08003918 printf("\nCommand not support by this chip.\n");
3919 }
developer880c8292022-07-11 11:52:59 +08003920}
3921
3922void pfc_get_rx_counter(int argc, char *argv[])
3923{
developere78dab52024-03-25 14:26:39 +08003924 int port = 0;
3925 unsigned int value = 0, reg = 0;
3926 unsigned int user_pri = 0;
developer880c8292022-07-11 11:52:59 +08003927
3928 port = strtoul(argv[3], NULL, 0);
3929 if (port < 0 || 6 < port) {
3930 printf("wrong port range, should be within 0~6\n");
3931 return;
3932 }
3933
developere78dab52024-03-25 14:26:39 +08003934 if (chip_name == 0x7531 || chip_name == 0x7988) {
3935 reg = PFC_RX_COUNTER_L(port);
developer880c8292022-07-11 11:52:59 +08003936 reg_read(reg, &value);
3937 user_pri = value & 0xff;
developere78dab52024-03-25 14:26:39 +08003938 printf("\n port %d rx pfc (up=0)pause on counter is %d.\n",
3939 port, user_pri);
developer880c8292022-07-11 11:52:59 +08003940 user_pri = (value & 0xff00) >> 8;
developere78dab52024-03-25 14:26:39 +08003941 printf("\n port %d rx pfc (up=1)pause on counter is %d.\n",
3942 port, user_pri);
developer880c8292022-07-11 11:52:59 +08003943 user_pri = (value & 0xff0000) >> 16;
developere78dab52024-03-25 14:26:39 +08003944 printf("\n port %d rx pfc (up=2)pause on counter is %d.\n",
3945 port, user_pri);
developer880c8292022-07-11 11:52:59 +08003946 user_pri = (value & 0xff000000) >> 24;
developere78dab52024-03-25 14:26:39 +08003947 printf("\n port %d rx pfc (up=3)pause on counter is %d.\n",
3948 port, user_pri);
developer880c8292022-07-11 11:52:59 +08003949
developere78dab52024-03-25 14:26:39 +08003950 reg = PFC_RX_COUNTER_H(port);
developer880c8292022-07-11 11:52:59 +08003951 reg_read(reg, &value);
3952 user_pri = value & 0xff;
developere78dab52024-03-25 14:26:39 +08003953 printf("\n port %d rx pfc (up=4)pause on counter is %d.\n",
3954 port, user_pri);
developer880c8292022-07-11 11:52:59 +08003955 user_pri = (value & 0xff00) >> 8;
developere78dab52024-03-25 14:26:39 +08003956 printf("\n port %d rx pfc (up=5)pause on counter is %d.\n",
3957 port, user_pri);
developer880c8292022-07-11 11:52:59 +08003958 user_pri = (value & 0xff0000) >> 16;
developere78dab52024-03-25 14:26:39 +08003959 printf("\n port %d rx pfc (up=6)pause on counter is %d.\n",
3960 port, user_pri);
developer880c8292022-07-11 11:52:59 +08003961 user_pri = (value & 0xff000000) >> 24;
developere78dab52024-03-25 14:26:39 +08003962 printf("\n port %d rx pfc (up=7)pause on counter is %d.\n",
3963 port, user_pri);
developer880c8292022-07-11 11:52:59 +08003964
3965 /* for rx counter could be updated successfully */
3966 reg_read(PMSR_P(port), &value);
3967 reg_read(PMSR_P(port), &value);
developere78dab52024-03-25 14:26:39 +08003968 } else {
developer880c8292022-07-11 11:52:59 +08003969 printf("\nCommand not support by this chip.\n");
3970 }
3971
3972}
3973
3974void pfc_get_tx_counter(int argc, char *argv[])
3975{
developere78dab52024-03-25 14:26:39 +08003976 int port = 0;
3977 unsigned int value = 0, reg = 0;
3978 unsigned int user_pri = 0;
developer880c8292022-07-11 11:52:59 +08003979
3980 port = strtoul(argv[3], NULL, 0);
3981 if (port < 0 || 6 < port) {
3982 printf("wrong port range, should be within 0~6\n");
3983 return;
3984 }
3985
developer5dfa8b72022-11-03 11:33:07 +08003986 if (chip_name == 0x7531 || chip_name == 0x7988) {
developere78dab52024-03-25 14:26:39 +08003987 reg = PFC_TX_COUNTER_L(port);
developer880c8292022-07-11 11:52:59 +08003988 reg_read(reg, &value);
3989 user_pri = value & 0xff;
developere78dab52024-03-25 14:26:39 +08003990 printf("\n port %d tx pfc (up=0)pause on counter is %d.\n",
3991 port, user_pri);
developer880c8292022-07-11 11:52:59 +08003992 user_pri = (value & 0xff00) >> 8;
developere78dab52024-03-25 14:26:39 +08003993 printf("\n port %d tx pfc (up=1)pause on counter is %d.\n",
3994 port, user_pri);
developer880c8292022-07-11 11:52:59 +08003995 user_pri = (value & 0xff0000) >> 16;
developere78dab52024-03-25 14:26:39 +08003996 printf("\n port %d tx pfc (up=2)pause on counter is %d.\n",
3997 port, user_pri);
developer880c8292022-07-11 11:52:59 +08003998 user_pri = (value & 0xff000000) >> 24;
developere78dab52024-03-25 14:26:39 +08003999 printf("\n port %d tx pfc (up=3)pause on counter is %d.\n",
4000 port, user_pri);
developer880c8292022-07-11 11:52:59 +08004001
developere78dab52024-03-25 14:26:39 +08004002 reg = PFC_TX_COUNTER_H(port);
developer880c8292022-07-11 11:52:59 +08004003 reg_read(reg, &value);
4004 user_pri = value & 0xff;
developere78dab52024-03-25 14:26:39 +08004005 printf("\n port %d tx pfc (up=4)pause on counter is %d.\n",
4006 port, user_pri);
developer880c8292022-07-11 11:52:59 +08004007 user_pri = (value & 0xff00) >> 8;
developere78dab52024-03-25 14:26:39 +08004008 printf("\n port %d tx pfc (up=5)pause on counter is %d.\n",
4009 port, user_pri);
developer880c8292022-07-11 11:52:59 +08004010 user_pri = (value & 0xff0000) >> 16;
developere78dab52024-03-25 14:26:39 +08004011 printf("\n port %d tx pfc (up=6)pause on counter is %d.\n",
4012 port, user_pri);
developer880c8292022-07-11 11:52:59 +08004013 user_pri = (value & 0xff000000) >> 24;
developere78dab52024-03-25 14:26:39 +08004014 printf("\n port %d tx pfc (up=7)pause on counter is %d.\n",
4015 port, user_pri);
developer880c8292022-07-11 11:52:59 +08004016
4017 /* for tx counter could be updated successfully */
4018 reg_read(PMSR_P(port), &value);
4019 reg_read(PMSR_P(port), &value);
developere78dab52024-03-25 14:26:39 +08004020 } else {
4021 printf("\nCommand not support by this chip.\n");
developer880c8292022-07-11 11:52:59 +08004022 }
4023}
4024
developere78dab52024-03-25 14:26:39 +08004025void read_output_queue_counters(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08004026{
developere78dab52024-03-25 14:26:39 +08004027 unsigned int port = 0;
4028 unsigned int value = 0, output_queue = 0;
4029 unsigned int base = 0x220;
developer880c8292022-07-11 11:52:59 +08004030
developer5dfa8b72022-11-03 11:33:07 +08004031 for (port = 0; port < 7; port++) {
developere78dab52024-03-25 14:26:39 +08004032 reg_write(0x7038, base + (port * 4));
developer5dfa8b72022-11-03 11:33:07 +08004033 reg_read(0x7034, &value);
4034 output_queue = value & 0xff;
developere78dab52024-03-25 14:26:39 +08004035 printf("\n port %d output queue 0 counter is %d.\n", port,
4036 output_queue);
developer5dfa8b72022-11-03 11:33:07 +08004037 output_queue = (value & 0xff00) >> 8;
developere78dab52024-03-25 14:26:39 +08004038 printf("\n port %d output queue 1 counter is %d.\n", port,
4039 output_queue);
developer880c8292022-07-11 11:52:59 +08004040
developere78dab52024-03-25 14:26:39 +08004041 reg_write(0x7038, base + (port * 4) + 1);
developer5dfa8b72022-11-03 11:33:07 +08004042 reg_read(0x7034, &value);
4043 output_queue = value & 0xff;
developere78dab52024-03-25 14:26:39 +08004044 printf("\n port %d output queue 2 counter is %d.\n", port,
4045 output_queue);
developer5dfa8b72022-11-03 11:33:07 +08004046 output_queue = (value & 0xff00) >> 8;
developere78dab52024-03-25 14:26:39 +08004047 printf("\n port %d output queue 3 counter is %d.\n", port,
4048 output_queue);
developer880c8292022-07-11 11:52:59 +08004049
developere78dab52024-03-25 14:26:39 +08004050 reg_write(0x7038, base + (port * 4) + 2);
developer5dfa8b72022-11-03 11:33:07 +08004051 reg_read(0x7034, &value);
4052 output_queue = value & 0xff;
developere78dab52024-03-25 14:26:39 +08004053 printf("\n port %d output queue 4 counter is %d.\n", port,
4054 output_queue);
developer5dfa8b72022-11-03 11:33:07 +08004055 output_queue = (value & 0xff00) >> 8;
developere78dab52024-03-25 14:26:39 +08004056 printf("\n port %d output queue 5 counter is %d.\n", port,
4057 output_queue);
developer880c8292022-07-11 11:52:59 +08004058
developere78dab52024-03-25 14:26:39 +08004059 reg_write(0x7038, base + (port * 4) + 3);
developer5dfa8b72022-11-03 11:33:07 +08004060 reg_read(0x7034, &value);
4061 output_queue = value & 0xff;
developere78dab52024-03-25 14:26:39 +08004062 printf("\n port %d output queue 6 counter is %d.\n", port,
4063 output_queue);
developer5dfa8b72022-11-03 11:33:07 +08004064 output_queue = (value & 0xff00) >> 8;
developere78dab52024-03-25 14:26:39 +08004065 printf("\n port %d output queue 7 counter is %d.\n", port,
4066 output_queue);
developer880c8292022-07-11 11:52:59 +08004067 }
4068}
4069
developere78dab52024-03-25 14:26:39 +08004070void read_free_page_counters(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08004071{
developere78dab52024-03-25 14:26:39 +08004072 unsigned int value = 0;
4073 unsigned int free_page = 0, free_page_last_read = 0;
4074 unsigned int fc_free_blk_lothd = 0, fc_free_blk_hithd = 0;
4075 unsigned int fc_port_blk_thd = 0, fc_port_blk_hi_thd = 0;
4076 unsigned int queue[8] = { 0 };
developer880c8292022-07-11 11:52:59 +08004077
developer5dfa8b72022-11-03 11:33:07 +08004078 if (chip_name == 0x7531 || chip_name == 0x7988) {
developere78dab52024-03-25 14:26:39 +08004079 /* get system free page link counter */
developer5dfa8b72022-11-03 11:33:07 +08004080 reg_read(0x1fc0, &value);
4081 free_page = value & 0xFFF;
4082 free_page_last_read = (value & 0xFFF0000) >> 16;
developer880c8292022-07-11 11:52:59 +08004083
developer5dfa8b72022-11-03 11:33:07 +08004084 /* get system flow control waterwark */
4085 reg_read(0x1fe0, &value);
4086 fc_free_blk_lothd = value & 0x3FF;
4087 fc_free_blk_hithd = (value & 0x3FF0000) >> 16;
developer880c8292022-07-11 11:52:59 +08004088
developer5dfa8b72022-11-03 11:33:07 +08004089 /* get port flow control waterwark */
4090 reg_read(0x1fe4, &value);
4091 fc_port_blk_thd = value & 0x3FF;
4092 fc_port_blk_hi_thd = (value & 0x3FF0000) >> 16;
developer880c8292022-07-11 11:52:59 +08004093
developer5dfa8b72022-11-03 11:33:07 +08004094 /* get queue flow control waterwark */
4095 reg_read(0x1fe8, &value);
developere78dab52024-03-25 14:26:39 +08004096 queue[0] = value & 0x3F;
4097 queue[1] = (value & 0x3F00) >> 8;
4098 queue[2] = (value & 0x3F0000) >> 16;
4099 queue[3] = (value & 0x3F000000) >> 24;
developer5dfa8b72022-11-03 11:33:07 +08004100 reg_read(0x1fec, &value);
developere78dab52024-03-25 14:26:39 +08004101 queue[4] = value & 0x3F;
4102 queue[5] = (value & 0x3F00) >> 8;
4103 queue[6] = (value & 0x3F0000) >> 16;
4104 queue[7] = (value & 0x3F000000) >> 24;
developer5dfa8b72022-11-03 11:33:07 +08004105 } else {
developere78dab52024-03-25 14:26:39 +08004106 /* get system free page link counter */
developer5dfa8b72022-11-03 11:33:07 +08004107 reg_read(0x1fc0, &value);
4108 free_page = value & 0x3FF;
4109 free_page_last_read = (value & 0x3FF0000) >> 16;
developer880c8292022-07-11 11:52:59 +08004110
developer5dfa8b72022-11-03 11:33:07 +08004111 /* get system flow control waterwark */
4112 reg_read(0x1fe0, &value);
4113 fc_free_blk_lothd = value & 0xFF;
4114 fc_free_blk_hithd = (value & 0xFF00) >> 8;
developer880c8292022-07-11 11:52:59 +08004115
developer5dfa8b72022-11-03 11:33:07 +08004116 /* get port flow control waterwark */
4117 reg_read(0x1fe0, &value);
4118 fc_port_blk_thd = (value & 0xFF0000) >> 16;
4119 reg_read(0x1ff4, &value);
4120 fc_port_blk_hi_thd = (value & 0xFF00) >> 8;
developer880c8292022-07-11 11:52:59 +08004121
developer5dfa8b72022-11-03 11:33:07 +08004122 /* get queue flow control waterwark */
4123 reg_read(0x1fe4, &value);
developere78dab52024-03-25 14:26:39 +08004124 queue[0] = value & 0xF;
4125 queue[1] = (value & 0xF0) >> 4;
4126 queue[2] = (value & 0xF00) >> 8;
4127 queue[3] = (value & 0xF000) >> 12;
4128 queue[4] = (value & 0xF0000) >> 16;
4129 queue[5] = (value & 0xF00000) >> 20;
4130 queue[6] = (value & 0xF000000) >> 24;
4131 queue[7] = (value & 0xF0000000) >> 28;
developer880c8292022-07-11 11:52:59 +08004132 }
4133
developere78dab52024-03-25 14:26:39 +08004134 printf("<===Free Page=======Current=======Last Read access=====>\n");
4135 printf("\n");
4136 printf(" page counter %u %u\n ",
4137 free_page, free_page_last_read);
4138 printf("\n ");
4139 printf("=========================================================\n");
4140 printf("<===Type=======High threshold======Low threshold=========\n");
4141 printf("\n ");
4142 printf(" system: %u %u\n",
4143 fc_free_blk_hithd * 2, fc_free_blk_lothd * 2);
4144 printf(" port: %u %u\n",
4145 fc_port_blk_hi_thd * 2, fc_port_blk_thd * 2);
4146 printf(" queue 0: %u NA\n",
4147 queue[0]);
4148 printf(" queue 1: %u NA\n",
4149 queue[1]);
4150 printf(" queue 2: %u NA\n",
4151 queue[2]);
4152 printf(" queue 3: %u NA\n",
4153 queue[3]);
4154 printf(" queue 4: %u NA\n",
4155 queue[4]);
4156 printf(" queue 5: %u NA\n",
4157 queue[5]);
4158 printf(" queue 6: %u NA\n",
4159 queue[6]);
4160 printf(" queue 7: %u NA\n",
4161 queue[7]);
4162 printf("=========================================================\n");
developer880c8292022-07-11 11:52:59 +08004163}
4164
developer5dfa8b72022-11-03 11:33:07 +08004165void eee_enable(int argc, char *argv[])
4166{
developere78dab52024-03-25 14:26:39 +08004167 unsigned long enable = 0;
4168 unsigned int value = 0;
4169 unsigned int eee_cap = 0;
developer5dfa8b72022-11-03 11:33:07 +08004170 unsigned int eee_en_bitmap = 0;
developere78dab52024-03-25 14:26:39 +08004171 unsigned long port_map = 0;
developer5dfa8b72022-11-03 11:33:07 +08004172 long port_num = -1;
developere78dab52024-03-25 14:26:39 +08004173 int p = 0;
developer5dfa8b72022-11-03 11:33:07 +08004174
4175 if (argc < 3)
4176 goto error;
4177
developere78dab52024-03-25 14:26:39 +08004178 /* Check the input parameters is right or not. */
developer5dfa8b72022-11-03 11:33:07 +08004179 if (!strncmp(argv[2], "enable", 7))
4180 enable = 1;
4181 else if (!strncmp(argv[2], "disable", 8))
4182 enable = 0;
4183 else
4184 goto error;
4185
4186 if (argc > 3) {
4187 if (strlen(argv[3]) == 1) {
4188 port_num = strtol(argv[3], (char **)NULL, 10);
4189 if (port_num < 0 || port_num > MAX_PHY_PORT - 1) {
4190 printf("Illegal port index and port:0~4\n");
4191 goto error;
4192 }
4193 port_map = 1 << port_num;
4194 } else if (strlen(argv[3]) == 5) {
4195 port_map = 0;
4196 for (p = 0; p < MAX_PHY_PORT; p++) {
4197 if (argv[3][p] != '0' && argv[3][p] != '1') {
developercc8110b2024-08-19 13:53:34 +08004198 printf("portmap format error, should be combination of 0 or 1\n");
developer5dfa8b72022-11-03 11:33:07 +08004199 goto error;
4200 }
4201 port_map |= ((argv[3][p] - '0') << p);
4202 }
4203 } else {
developercc8110b2024-08-19 13:53:34 +08004204 printf("port_no or portmap format error, should be length of 1 or 5\n");
developer5dfa8b72022-11-03 11:33:07 +08004205 goto error;
4206 }
4207 } else {
4208 port_map = 0x1f;
4209 }
4210
developere78dab52024-03-25 14:26:39 +08004211 eee_cap = (enable) ? 6 : 0;
developer5dfa8b72022-11-03 11:33:07 +08004212 for (p = 0; p < MAX_PHY_PORT; p++) {
4213 /* port_map describe p0p1p2p3p4 from left to rignt */
developere78dab52024-03-25 14:26:39 +08004214 if (!!(port_map & (1 << p)))
developer5dfa8b72022-11-03 11:33:07 +08004215 mii_mgr_c45_write(p, 0x7, 0x3c, eee_cap);
4216
4217 mii_mgr_c45_read(p, 0x7, 0x3c, &value);
4218 /* mt7531: Always readback eee_cap = 0 when global EEE switch
4219 * is turned off.
4220 */
4221 if (value | eee_cap)
4222 eee_en_bitmap |= (1 << (MAX_PHY_PORT - 1 - p));
4223 }
4224
4225 /* Turn on/off global EEE switch */
4226 if (chip_name == 0x7531 || chip_name == 0x7988) {
4227 mii_mgr_c45_read(0, 0x1f, 0x403, &value);
4228 if (eee_en_bitmap)
4229 value |= (1 << 6);
4230 else
4231 value &= ~(1 << 6);
4232 mii_mgr_c45_write(0, 0x1f, 0x403, value);
4233 } else {
4234 printf("\nCommand not support by this chip.\n");
4235 }
4236
developere78dab52024-03-25 14:26:39 +08004237 printf("EEE(802.3az) %s", (enable) ? "enable" : "disable");
developer5dfa8b72022-11-03 11:33:07 +08004238 if (argc == 4) {
4239 if (port_num >= 0)
4240 printf(" port%ld", port_num);
4241 else
4242 printf(" port_map: %s", argv[3]);
4243 } else {
4244 printf(" all ports");
4245 }
4246 printf("\n");
4247
4248 return;
4249error:
4250 printf(HELP_EEE_EN);
developer5dfa8b72022-11-03 11:33:07 +08004251}
4252
4253void eee_dump(int argc, char *argv[])
4254{
developere78dab52024-03-25 14:26:39 +08004255 unsigned int cap = 0, lp_cap = 0;
developer5dfa8b72022-11-03 11:33:07 +08004256 long port = -1;
developere78dab52024-03-25 14:26:39 +08004257 int p = 0;
developer5dfa8b72022-11-03 11:33:07 +08004258
4259 if (argc > 3) {
4260 if (strlen(argv[3]) > 1) {
4261 printf("port# format error, should be of length 1\n");
4262 return;
4263 }
4264
4265 port = strtol(argv[3], (char **)NULL, 0);
4266 if (port < 0 || port > MAX_PHY_PORT) {
4267 printf("port# format error, should be 0 to %d\n",
developere78dab52024-03-25 14:26:39 +08004268 MAX_PHY_PORT);
developer5dfa8b72022-11-03 11:33:07 +08004269 return;
4270 }
4271 }
4272
4273 for (p = 0; p < MAX_PHY_PORT; p++) {
4274 if (port >= 0 && p != port)
4275 continue;
4276
4277 mii_mgr_c45_read(p, 0x7, 0x3c, &cap);
4278 mii_mgr_c45_read(p, 0x7, 0x3d, &lp_cap);
4279 printf("port%d EEE cap=0x%02x, link partner EEE cap=0x%02x",
4280 p, cap, lp_cap);
4281
4282 if (port >= 0 && p == port) {
4283 mii_mgr_c45_read(p, 0x3, 0x1, &cap);
4284 printf(", st=0x%03x", cap);
4285 }
4286 printf("\n");
4287 }
4288}
4289
4290void dump_each_port(unsigned int base)
developer880c8292022-07-11 11:52:59 +08004291{
4292 unsigned int pkt_cnt = 0;
4293 int i = 0;
4294
4295 for (i = 0; i < 7; i++) {
developerb403ad02022-11-08 10:16:29 +08004296 if (chip_name == 0x7988) {
4297 if ((base == 0x402C) && (i == 6))
4298 base = 0x408C;
4299 else if ((base == 0x408C) && (i == 6))
4300 base = 0x402C;
4301 else
4302 ;
4303 }
developer880c8292022-07-11 11:52:59 +08004304 reg_read((base) + (i * 0x100), &pkt_cnt);
4305 printf("%8u ", pkt_cnt);
4306 }
4307 printf("\n");
4308}
4309
developere78dab52024-03-25 14:26:39 +08004310void read_mib_counters(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08004311{
4312 printf("===================== %8s %8s %8s %8s %8s %8s %8s\n",
4313 "Port0", "Port1", "Port2", "Port3", "Port4", "Port5", "Port6");
4314 printf("Tx Drop Packet :");
4315 dump_each_port(0x4000);
4316 printf("Tx CRC Error :");
4317 dump_each_port(0x4004);
4318 printf("Tx Unicast Packet :");
4319 dump_each_port(0x4008);
4320 printf("Tx Multicast Packet :");
4321 dump_each_port(0x400C);
4322 printf("Tx Broadcast Packet :");
4323 dump_each_port(0x4010);
4324 printf("Tx Collision Event :");
4325 dump_each_port(0x4014);
4326 printf("Tx Pause Packet :");
4327 dump_each_port(0x402C);
4328 printf("Rx Drop Packet :");
4329 dump_each_port(0x4060);
4330 printf("Rx Filtering Packet :");
4331 dump_each_port(0x4064);
4332 printf("Rx Unicast Packet :");
4333 dump_each_port(0x4068);
4334 printf("Rx Multicast Packet :");
4335 dump_each_port(0x406C);
4336 printf("Rx Broadcast Packet :");
4337 dump_each_port(0x4070);
4338 printf("Rx Alignment Error :");
4339 dump_each_port(0x4074);
4340 printf("Rx CRC Error :");
4341 dump_each_port(0x4078);
4342 printf("Rx Undersize Error :");
4343 dump_each_port(0x407C);
4344 printf("Rx Fragment Error :");
4345 dump_each_port(0x4080);
4346 printf("Rx Oversize Error :");
4347 dump_each_port(0x4084);
4348 printf("Rx Jabber Error :");
4349 dump_each_port(0x4088);
4350 printf("Rx Pause Packet :");
4351 dump_each_port(0x408C);
4352}
4353
developere78dab52024-03-25 14:26:39 +08004354void clear_mib_counters(int argc, char *argv[])
developer880c8292022-07-11 11:52:59 +08004355{
4356 reg_write(0x4fe0, 0xf0);
developere78dab52024-03-25 14:26:39 +08004357 read_mib_counters(argc, argv);
developer880c8292022-07-11 11:52:59 +08004358 reg_write(0x4fe0, 0x800000f0);
4359}
4360
developercc8110b2024-08-19 13:53:34 +08004361void exit_free(void)
developer880c8292022-07-11 11:52:59 +08004362{
4363 free(attres);
4364 attres = NULL;
4365 switch_ioctl_fini();
4366 mt753x_netlink_free();
4367}