blob: 366079e0d6f7074b41c15883bceb2ce8d0675658 [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001/*
2 * switch_ioctl.c: switch(ioctl) set API
3 */
4
developer0c1ae572021-05-27 15:32:01 +08005#include <errno.h>
developerfd40db22021-04-29 10:08:25 +08006#include <stdio.h>
7#include <stdlib.h>
8#include <unistd.h>
9#include <string.h>
10#include <sys/ioctl.h>
11#include <sys/socket.h>
12#include <linux/if.h>
13
14#include "switch_fun.h"
15#include "switch_ioctl.h"
16
17static int esw_fd;
18
developer0c1ae572021-05-27 15:32:01 +080019int switch_ioctl_init(void)
developerfd40db22021-04-29 10:08:25 +080020{
21 esw_fd = socket(AF_INET, SOCK_DGRAM, 0);
22 if (esw_fd < 0) {
23 perror("socket");
developer0c1ae572021-05-27 15:32:01 +080024 return -EINVAL;
developerfd40db22021-04-29 10:08:25 +080025 }
developer0c1ae572021-05-27 15:32:01 +080026
27 return 0;
developerfd40db22021-04-29 10:08:25 +080028}
29
30void switch_ioctl_fini(void)
31{
32 close(esw_fd);
33}
34
35int reg_read_ioctl(unsigned int offset, unsigned int *value)
36{
37 struct ifreq ifr;
38 struct ra_mii_ioctl_data mii;
39
40 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
41 ifr.ifr_data = &mii;
42
43 mii.phy_id = 0x1f;
44 mii.reg_num = offset;
45
46 if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) {
47 perror("ioctl");
48 close(esw_fd);
49 exit(0);
50 }
51 *value = mii.val_out;
52 return 0;
53}
54
55int reg_read_tr(int offset, int *value)
56{
57 struct ifreq ifr;
58 struct ra_mii_ioctl_data mii;
59
60 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
61 ifr.ifr_data = &mii;
62
63 mii.phy_id = 0;
64 mii.reg_num = offset;
65
66 if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) {
67 perror("ioctl");
68 close(esw_fd);
69 exit(0);
70 }
71 *value = mii.val_out;
72 return 0;
73}
74
75int reg_write_ioctl(unsigned int offset, unsigned int value)
76{
77 struct ifreq ifr;
78 struct ra_mii_ioctl_data mii;
79
80 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
81 ifr.ifr_data = &mii;
82
83 mii.phy_id = 0x1f;
84 mii.reg_num = offset;
85 mii.val_in = value;
86
87 if (-1 == ioctl(esw_fd, RAETH_MII_WRITE, &ifr)) {
88 perror("ioctl");
89 close(esw_fd);
90 exit(0);
91 }
92 return 0;
93}
94
95int reg_write_tr(int offset, int value)
96{
97 struct ifreq ifr;
98 struct ra_mii_ioctl_data mii;
99
100 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
101 ifr.ifr_data = &mii;
102
103 mii.phy_id = 0;
104 mii.reg_num = offset;
105 mii.val_in = value;
106
107 if (-1 == ioctl(esw_fd, RAETH_MII_WRITE, &ifr)) {
108 perror("ioctl");
109 close(esw_fd);
110 exit(0);
111 }
112 return 0;
113}
114
115int phy_dump_ioctl(unsigned int phy_addr)
116{
117 struct ifreq ifr;
118 struct esw_reg reg;
119
120 reg.val = phy_addr;
121 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
122 ifr.ifr_data = &reg;
123 if (-1 == ioctl(esw_fd, RAETH_ESW_PHY_DUMP, &ifr)) {
124 perror("ioctl");
125 close(esw_fd);
126 exit(0);
127 }
128 return 0;
129}
130
131int mii_mgr_cl22_read_ioctl(unsigned int port_num, unsigned int reg, unsigned int *value)
132{
133 unsigned int reg_value;
134 int loop_cnt;
135 int op_busy;
136
137 loop_cnt = 0;
138
139 /*Change to indirect access mode*/
140 /*if you need to use direct access mode, please change back manually by reset bit5*/
developer06979e42021-05-28 16:48:10 +0800141 if (chip_name == 0x7530) {
142 reg_read(0x7804, &reg_value);
143 if (((reg_value >> 5) & 0x1) == 0) {
144 reg_value |= 1 << 5;
145 reg_write(0x7804, reg_value);
146 printf("Change to indirect access mode:0x%x\n",
147 reg_value);
148 }
developerfd40db22021-04-29 10:08:25 +0800149 }
150 reg_value = 0x80090000 | (port_num << 20) | (reg << 25);
151 reg_write(0x701c, reg_value);
152 while (1)
153 {
154 reg_read(0x701c, &reg_value);
155 op_busy = reg_value & (1 << 31);
156 if (!op_busy) {
157 reg_value = reg_value & 0xFFFF;
158 break;
159 } else if (loop_cnt < 10)
160 loop_cnt++;
161 else {
162 printf("MDIO read opeartion timeout\n");
163 reg_value = 0;
164 break;
165 }
166 }
developer06979e42021-05-28 16:48:10 +0800167 //printf(" PHY Indirect Access Control(0x701c) register read value =0x%x \n", reg_value);
developerfd40db22021-04-29 10:08:25 +0800168 *value = reg_value;
169
170 return 0;
171}
172
173int mii_mgr_cl22_write_ioctl(unsigned int port_num, unsigned int reg, unsigned int value)
174{
175 unsigned int reg_value;
176 int loop_cnt;
177 int op_busy;
178
179 loop_cnt = 0;
180 /*Change to indirect access mode*/
181 /*if you need to use direct access mode, please change back manually by reset bit5*/
developer06979e42021-05-28 16:48:10 +0800182 if (chip_name == 0x7530) {
183 reg_read(0x7804, &reg_value);
184 if (((reg_value >> 5) & 0x1) == 0) {
185 reg_value |= 1 << 5;
186 reg_write(0x7804, reg_value);
187 printf("Change to indirect access mode:0x%x\n",
188 reg_value);
189 }
developerfd40db22021-04-29 10:08:25 +0800190 }
191
192 reg_value = 0x80050000 | (port_num << 20) | (reg << 25) | value;
193 reg_write(0x701c, reg_value);
194 while (1)
195 {
196 reg_read(0x701c, &reg_value);
197 op_busy = reg_value & (1 << 31);
198 if (!op_busy)
199 break;
200 else if (loop_cnt < 10)
201 loop_cnt++;
202 else {
203 printf("MDIO write opeartion timeout\n");
204 break;
205 }
206 }
207
developer06979e42021-05-28 16:48:10 +0800208 //printf(" PHY Indirect Access Control(0x701c) register write value =0x%x \n", reg_value);
developerfd40db22021-04-29 10:08:25 +0800209
210 return 0;
211}
212
developer06979e42021-05-28 16:48:10 +0800213int mii_mgr_cl45_read_indirect(unsigned int port_num, unsigned int dev,
214 unsigned int reg, unsigned int *value)
developerfd40db22021-04-29 10:08:25 +0800215{
216 int sk, method, ret;
217 struct ifreq ifr;
218 struct ra_mii_ioctl_data mii;
219
220 if (!value)
221 return -1;
222
223 sk = socket(AF_INET, SOCK_DGRAM, 0);
224 if (sk < 0) {
225 printf("Open socket failed\n");
226
227 return -1;
228 }
229
230 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
231 ifr.ifr_data = &mii;
232
233 method = RAETH_MII_WRITE;
234 mii.phy_id = port_num;
235 mii.reg_num = 13;
236 mii.val_in = dev;
237 ret = ioctl(sk, method, &ifr);
developer9ef022c2023-08-30 16:50:44 +0800238 if (ret < 0)
239 printf("ioctl failed with error %d\n", ret);
developerfd40db22021-04-29 10:08:25 +0800240
241 method = RAETH_MII_WRITE;
242 mii.phy_id = port_num;
243 mii.reg_num = 14;
244 mii.val_in = reg;
245 ret = ioctl(sk, method, &ifr);
developer9ef022c2023-08-30 16:50:44 +0800246 if (ret < 0)
247 printf("ioctl failed with error %d\n", ret);
developerfd40db22021-04-29 10:08:25 +0800248
249 method = RAETH_MII_WRITE;
250 mii.phy_id = port_num;
251 mii.reg_num = 13;
252 mii.val_in = (0x6000 | dev);
253 ret = ioctl(sk, method, &ifr);
developer9ef022c2023-08-30 16:50:44 +0800254 if (ret < 0)
255 printf("ioctl failed with error %d\n", ret);
developerfd40db22021-04-29 10:08:25 +0800256
257 usleep(1000);
258
259 method = RAETH_MII_READ;
260 mii.phy_id = port_num;
261 mii.reg_num = 14;
262 ret = ioctl(sk, method, &ifr);
developer9ef022c2023-08-30 16:50:44 +0800263 if (ret < 0)
264 printf("ioctl failed with error %d\n", ret);
developerfd40db22021-04-29 10:08:25 +0800265
266 close(sk);
267 *value = mii.val_out;
268
269 return ret;
270}
271
developer06979e42021-05-28 16:48:10 +0800272int mii_mgr_cl45_write_indirect(unsigned int port_num, unsigned int dev,
273 unsigned int reg, unsigned int value)
developerfd40db22021-04-29 10:08:25 +0800274{
275 int sk, method, ret;
276 struct ifreq ifr;
277 struct ra_mii_ioctl_data mii;
278
279 sk = socket(AF_INET, SOCK_DGRAM, 0);
280 if (sk < 0) {
281 printf("Open socket failed\n");
282
283 return -1;
284 }
285
286 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
287 ifr.ifr_data = &mii;
288
289 method = RAETH_MII_WRITE;
290 mii.phy_id = port_num;
291 mii.reg_num = 13;
292 mii.val_in = dev;
293 ret = ioctl(sk, method, &ifr);
developer9ef022c2023-08-30 16:50:44 +0800294 if (ret < 0)
295 printf("ioctl failed with error %d\n", ret);
developerfd40db22021-04-29 10:08:25 +0800296
297 method = RAETH_MII_WRITE;
298 mii.phy_id = port_num;
299 mii.reg_num = 14;
300 mii.val_in = reg;
301 ret = ioctl(sk, method, &ifr);
developer9ef022c2023-08-30 16:50:44 +0800302 if (ret < 0)
303 printf("ioctl failed with error %d\n", ret);
developerfd40db22021-04-29 10:08:25 +0800304
305 method = RAETH_MII_WRITE;
306 mii.phy_id = port_num;
307 mii.reg_num = 13;
308 mii.val_in = (0x6000 | dev);
309 ret = ioctl(sk, method, &ifr);
developer9ef022c2023-08-30 16:50:44 +0800310 if (ret < 0)
311 printf("ioctl failed with error %d\n", ret);
developerfd40db22021-04-29 10:08:25 +0800312
313 usleep(1000);
314
315 method = RAETH_MII_WRITE;
316 mii.phy_id = port_num;
317 mii.reg_num = 14;
318 mii.val_in = value;
319 ret = ioctl(sk, method, &ifr);
developer9ef022c2023-08-30 16:50:44 +0800320 if (ret < 0)
321 printf("ioctl failed with error %d\n", ret);
developerfd40db22021-04-29 10:08:25 +0800322
323 close(sk);
324
325 return ret;
326}
327
developer06979e42021-05-28 16:48:10 +0800328int mii_mgr_cl45_read(unsigned int port_num, unsigned int dev,
329 unsigned int reg, unsigned int *value)
330{
331 unsigned int reg_value;
332 int loop_cnt;
333 int op_busy;
334 int ret = 0;
335
336 loop_cnt = 0;
337
338 reg_value = 0x80000000 | (port_num << 20) | (dev << 25) | reg;
339 reg_write(0x701c, reg_value);
340 while (1)
341 {
342 reg_read(0x701c, &reg_value);
343 op_busy = reg_value & (1 << 31);
344 if (!op_busy) {
345 break;
346 } else if (loop_cnt < 10) {
347 loop_cnt++;
348 } else {
349 printf("MDIO cl45 set dev opeartion timeout\n");
350 reg_value = 0;
351 ret = -1;
352 goto out;
353 }
354 }
355
356 reg_value = 0x800c0000 | (port_num << 20) | (dev << 25);
357 reg_write(0x701c, reg_value);
358 while (1)
359 {
360 reg_read(0x701c, &reg_value);
361 op_busy = reg_value & (1 << 31);
362 if (!op_busy) {
363 reg_value = reg_value & 0xFFFF;
364 break;
365 } else if (loop_cnt < 10) {
366 loop_cnt++;
367 } else {
368 printf("MDIO cl45 read reg opeartion timeout\n");
369 reg_value = 0;
370 ret = -1;
371 break;
372 }
373 }
374out:
375 //printf(" PHY Indirect Access Control(0x701c) register read value =0x%x \n", reg_value);
376 *value = reg_value;
377
378 return ret;
379}
380
381int mii_mgr_cl45_write(unsigned int port_num, unsigned int dev,
382 unsigned int reg, unsigned int value)
383{
384 unsigned int reg_value;
385 int loop_cnt;
386 int op_busy;
387 int ret = 0;
388
389 loop_cnt = 0;
390
391 reg_value = 0x80000000 | (port_num << 20) | (dev << 25) | reg;
392 reg_write(0x701c, reg_value);
393 while (1)
394 {
395 reg_read(0x701c, &reg_value);
396 op_busy = reg_value & (1 << 31);
397 if (!op_busy)
398 break;
399 else if (loop_cnt < 10)
400 loop_cnt++;
401 else {
402 printf("MDIO cl45 set dev opeartion timeout\n");
403 ret = -1;
404 goto out;
405 }
406 }
407
408 reg_value = 0x80040000 | (port_num << 20) | (dev << 25) | value;
409 reg_write(0x701c, reg_value);
410 while (1)
411 {
412 reg_read(0x701c, &reg_value);
413 op_busy = reg_value & (1 << 31);
414 if (!op_busy)
415 break;
416 else if (loop_cnt < 10)
417 loop_cnt++;
418 else {
419 printf("MDIO cl45 write reg opeartion timeout\n");
420 ret = -1;
421 break;
422 }
423 }
424out:
425 //printf(" PHY Indirect Access Control(0x701c) register write value =0x%x \n", reg_value);
426 return ret;
427}
428
429int mii_mgr_cl45_read_ioctl(unsigned int port_num, unsigned int dev,
430 unsigned int reg, unsigned int *value)
431{
developer8c3871b2022-07-01 14:07:53 +0800432 if (chip_name == 0x7531 || chip_name == 0x7988)
developer06979e42021-05-28 16:48:10 +0800433 return mii_mgr_cl45_read(port_num, dev, reg, value);
434 else if (chip_name == 0x7530)
435 return mii_mgr_cl45_read_indirect(port_num, dev, reg, value);
436 else
437 return -1;
438}
439
440int mii_mgr_cl45_write_ioctl(unsigned int port_num, unsigned int dev,
441 unsigned int reg, unsigned int value)
442{
developer8c3871b2022-07-01 14:07:53 +0800443 if (chip_name == 0x7531 || chip_name == 0x7988)
developer06979e42021-05-28 16:48:10 +0800444 return mii_mgr_cl45_write(port_num, dev, reg, value);
445 else if (chip_name == 0x7530)
446 return mii_mgr_cl45_write_indirect(port_num, dev, reg, value);
447 else
448 return -1;
449}
450
developerfd40db22021-04-29 10:08:25 +0800451int dump_gphy(void)
452{
453 int cl22_reg[6] = {0x00, 0x01, 0x04, 0x05, 0x09, 0x0A};
454 int cl45_start_reg = 0x9B;
455 int cl45_end_reg = 0xA2;
456 unsigned int value;
457 int port_num = 5;
458 int i, j, ret;
459
460 int sk, method;
461 struct ifreq ifr;
462 struct ra_mii_ioctl_data mii;
463
464 sk = socket(AF_INET, SOCK_DGRAM, 0);
465 if (sk < 0) {
466 printf("Open socket failed\n");
467 return -1;
468 }
469
470 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
471 ifr.ifr_data = &mii;
472 /* dump CL45 reg first*/
473 for (i = 0; i < port_num; i++) {
474 printf("== Port %d ==\n", i);
475 for (j = cl45_start_reg; j < (cl45_end_reg + 1); j++) {
476 ret = mii_mgr_cl45_read_ioctl(i, 0x1E, j, &value);
477 if (ret)
478 continue;
479 printf("dev1Eh_reg%xh = 0x%x\n", j, value);
480 }
481 }
482 printf("== Global ==\n");
483 for (i = 0; i < sizeof(cl22_reg) / sizeof(cl22_reg[0]); i++) {
484 method = RAETH_MII_READ;
485 mii.phy_id = 0;
486 mii.reg_num = cl22_reg[i];
487 ret = ioctl(sk, method, &ifr);
488 printf("Reg%xh = 0x%x\n", cl22_reg[i], mii.val_out);
489 }
490
491 close(sk);
492
493 return ret;
494}