blob: f6b97d4058284efb35c8cf468295681fe175ff0d [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);
238
239 method = RAETH_MII_WRITE;
240 mii.phy_id = port_num;
241 mii.reg_num = 14;
242 mii.val_in = reg;
243 ret = ioctl(sk, method, &ifr);
244
245 method = RAETH_MII_WRITE;
246 mii.phy_id = port_num;
247 mii.reg_num = 13;
248 mii.val_in = (0x6000 | dev);
249 ret = ioctl(sk, method, &ifr);
250
251 usleep(1000);
252
253 method = RAETH_MII_READ;
254 mii.phy_id = port_num;
255 mii.reg_num = 14;
256 ret = ioctl(sk, method, &ifr);
257
258 close(sk);
259 *value = mii.val_out;
260
261 return ret;
262}
263
developer06979e42021-05-28 16:48:10 +0800264int mii_mgr_cl45_write_indirect(unsigned int port_num, unsigned int dev,
265 unsigned int reg, unsigned int value)
developerfd40db22021-04-29 10:08:25 +0800266{
267 int sk, method, ret;
268 struct ifreq ifr;
269 struct ra_mii_ioctl_data mii;
270
271 sk = socket(AF_INET, SOCK_DGRAM, 0);
272 if (sk < 0) {
273 printf("Open socket failed\n");
274
275 return -1;
276 }
277
278 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
279 ifr.ifr_data = &mii;
280
281 method = RAETH_MII_WRITE;
282 mii.phy_id = port_num;
283 mii.reg_num = 13;
284 mii.val_in = dev;
285 ret = ioctl(sk, method, &ifr);
286
287 method = RAETH_MII_WRITE;
288 mii.phy_id = port_num;
289 mii.reg_num = 14;
290 mii.val_in = reg;
291 ret = ioctl(sk, method, &ifr);
292
293 method = RAETH_MII_WRITE;
294 mii.phy_id = port_num;
295 mii.reg_num = 13;
296 mii.val_in = (0x6000 | dev);
297 ret = ioctl(sk, method, &ifr);
298
299 usleep(1000);
300
301 method = RAETH_MII_WRITE;
302 mii.phy_id = port_num;
303 mii.reg_num = 14;
304 mii.val_in = value;
305 ret = ioctl(sk, method, &ifr);
306
307 close(sk);
308
309 return ret;
310}
311
developer06979e42021-05-28 16:48:10 +0800312int mii_mgr_cl45_read(unsigned int port_num, unsigned int dev,
313 unsigned int reg, unsigned int *value)
314{
315 unsigned int reg_value;
316 int loop_cnt;
317 int op_busy;
318 int ret = 0;
319
320 loop_cnt = 0;
321
322 reg_value = 0x80000000 | (port_num << 20) | (dev << 25) | reg;
323 reg_write(0x701c, reg_value);
324 while (1)
325 {
326 reg_read(0x701c, &reg_value);
327 op_busy = reg_value & (1 << 31);
328 if (!op_busy) {
329 break;
330 } else if (loop_cnt < 10) {
331 loop_cnt++;
332 } else {
333 printf("MDIO cl45 set dev opeartion timeout\n");
334 reg_value = 0;
335 ret = -1;
336 goto out;
337 }
338 }
339
340 reg_value = 0x800c0000 | (port_num << 20) | (dev << 25);
341 reg_write(0x701c, reg_value);
342 while (1)
343 {
344 reg_read(0x701c, &reg_value);
345 op_busy = reg_value & (1 << 31);
346 if (!op_busy) {
347 reg_value = reg_value & 0xFFFF;
348 break;
349 } else if (loop_cnt < 10) {
350 loop_cnt++;
351 } else {
352 printf("MDIO cl45 read reg opeartion timeout\n");
353 reg_value = 0;
354 ret = -1;
355 break;
356 }
357 }
358out:
359 //printf(" PHY Indirect Access Control(0x701c) register read value =0x%x \n", reg_value);
360 *value = reg_value;
361
362 return ret;
363}
364
365int mii_mgr_cl45_write(unsigned int port_num, unsigned int dev,
366 unsigned int reg, unsigned int value)
367{
368 unsigned int reg_value;
369 int loop_cnt;
370 int op_busy;
371 int ret = 0;
372
373 loop_cnt = 0;
374
375 reg_value = 0x80000000 | (port_num << 20) | (dev << 25) | reg;
376 reg_write(0x701c, reg_value);
377 while (1)
378 {
379 reg_read(0x701c, &reg_value);
380 op_busy = reg_value & (1 << 31);
381 if (!op_busy)
382 break;
383 else if (loop_cnt < 10)
384 loop_cnt++;
385 else {
386 printf("MDIO cl45 set dev opeartion timeout\n");
387 ret = -1;
388 goto out;
389 }
390 }
391
392 reg_value = 0x80040000 | (port_num << 20) | (dev << 25) | value;
393 reg_write(0x701c, reg_value);
394 while (1)
395 {
396 reg_read(0x701c, &reg_value);
397 op_busy = reg_value & (1 << 31);
398 if (!op_busy)
399 break;
400 else if (loop_cnt < 10)
401 loop_cnt++;
402 else {
403 printf("MDIO cl45 write reg opeartion timeout\n");
404 ret = -1;
405 break;
406 }
407 }
408out:
409 //printf(" PHY Indirect Access Control(0x701c) register write value =0x%x \n", reg_value);
410 return ret;
411}
412
413int mii_mgr_cl45_read_ioctl(unsigned int port_num, unsigned int dev,
414 unsigned int reg, unsigned int *value)
415{
developer8c3871b2022-07-01 14:07:53 +0800416 if (chip_name == 0x7531 || chip_name == 0x7988)
developer06979e42021-05-28 16:48:10 +0800417 return mii_mgr_cl45_read(port_num, dev, reg, value);
418 else if (chip_name == 0x7530)
419 return mii_mgr_cl45_read_indirect(port_num, dev, reg, value);
420 else
421 return -1;
422}
423
424int mii_mgr_cl45_write_ioctl(unsigned int port_num, unsigned int dev,
425 unsigned int reg, unsigned int value)
426{
developer8c3871b2022-07-01 14:07:53 +0800427 if (chip_name == 0x7531 || chip_name == 0x7988)
developer06979e42021-05-28 16:48:10 +0800428 return mii_mgr_cl45_write(port_num, dev, reg, value);
429 else if (chip_name == 0x7530)
430 return mii_mgr_cl45_write_indirect(port_num, dev, reg, value);
431 else
432 return -1;
433}
434
developerfd40db22021-04-29 10:08:25 +0800435int dump_gphy(void)
436{
437 int cl22_reg[6] = {0x00, 0x01, 0x04, 0x05, 0x09, 0x0A};
438 int cl45_start_reg = 0x9B;
439 int cl45_end_reg = 0xA2;
440 unsigned int value;
441 int port_num = 5;
442 int i, j, ret;
443
444 int sk, method;
445 struct ifreq ifr;
446 struct ra_mii_ioctl_data mii;
447
448 sk = socket(AF_INET, SOCK_DGRAM, 0);
449 if (sk < 0) {
450 printf("Open socket failed\n");
451 return -1;
452 }
453
454 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
455 ifr.ifr_data = &mii;
456 /* dump CL45 reg first*/
457 for (i = 0; i < port_num; i++) {
458 printf("== Port %d ==\n", i);
459 for (j = cl45_start_reg; j < (cl45_end_reg + 1); j++) {
460 ret = mii_mgr_cl45_read_ioctl(i, 0x1E, j, &value);
461 if (ret)
462 continue;
463 printf("dev1Eh_reg%xh = 0x%x\n", j, value);
464 }
465 }
466 printf("== Global ==\n");
467 for (i = 0; i < sizeof(cl22_reg) / sizeof(cl22_reg[0]); i++) {
468 method = RAETH_MII_READ;
469 mii.phy_id = 0;
470 mii.reg_num = cl22_reg[i];
471 ret = ioctl(sk, method, &ifr);
472 printf("Reg%xh = 0x%x\n", cl22_reg[i], mii.val_out);
473 }
474
475 close(sk);
476
477 return ret;
478}