blob: 094bfc77c0a9b0c5cb96899f4f0f5311ebad446e [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*/
141 reg_read(0x7804, &reg_value);
142 if (((reg_value >> 5) & 0x1) == 0) {
143 reg_value |= 1 << 5;
144 reg_write(0x7804, reg_value);
145 printf("Change to indirect access mode:0x%x\n", reg_value);
146 }
147 reg_value = 0x80090000 | (port_num << 20) | (reg << 25);
148 reg_write(0x701c, reg_value);
149 while (1)
150 {
151 reg_read(0x701c, &reg_value);
152 op_busy = reg_value & (1 << 31);
153 if (!op_busy) {
154 reg_value = reg_value & 0xFFFF;
155 break;
156 } else if (loop_cnt < 10)
157 loop_cnt++;
158 else {
159 printf("MDIO read opeartion timeout\n");
160 reg_value = 0;
161 break;
162 }
163 }
164 printf(" PHY Indirect Access Control(0x701c) register read value =0x%x \n", reg_value);
165 *value = reg_value;
166
167 return 0;
168}
169
170int mii_mgr_cl22_write_ioctl(unsigned int port_num, unsigned int reg, unsigned int value)
171{
172 unsigned int reg_value;
173 int loop_cnt;
174 int op_busy;
175
176 loop_cnt = 0;
177 /*Change to indirect access mode*/
178 /*if you need to use direct access mode, please change back manually by reset bit5*/
179 reg_read(0x7804, &reg_value);
180 if (((reg_value >> 5) & 0x1) == 0) {
181 reg_value |= 1 << 5;
182 reg_write(0x7804, reg_value);
183 printf("Change to indirect access mode:0x%x\n", reg_value);
184 }
185
186 reg_value = 0x80050000 | (port_num << 20) | (reg << 25) | value;
187 reg_write(0x701c, reg_value);
188 while (1)
189 {
190 reg_read(0x701c, &reg_value);
191 op_busy = reg_value & (1 << 31);
192 if (!op_busy)
193 break;
194 else if (loop_cnt < 10)
195 loop_cnt++;
196 else {
197 printf("MDIO write opeartion timeout\n");
198 break;
199 }
200 }
201
202 printf(" PHY Indirect Access Control(0x701c) register write value =0x%x \n", reg_value);
203
204 return 0;
205}
206
207int mii_mgr_cl45_read_ioctl(unsigned int port_num, unsigned int dev,
208 unsigned int reg, unsigned int *value)
209{
210 int sk, method, ret;
211 struct ifreq ifr;
212 struct ra_mii_ioctl_data mii;
213
214 if (!value)
215 return -1;
216
217 sk = socket(AF_INET, SOCK_DGRAM, 0);
218 if (sk < 0) {
219 printf("Open socket failed\n");
220
221 return -1;
222 }
223
224 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
225 ifr.ifr_data = &mii;
226
227 method = RAETH_MII_WRITE;
228 mii.phy_id = port_num;
229 mii.reg_num = 13;
230 mii.val_in = dev;
231 ret = ioctl(sk, method, &ifr);
232
233 method = RAETH_MII_WRITE;
234 mii.phy_id = port_num;
235 mii.reg_num = 14;
236 mii.val_in = reg;
237 ret = ioctl(sk, method, &ifr);
238
239 method = RAETH_MII_WRITE;
240 mii.phy_id = port_num;
241 mii.reg_num = 13;
242 mii.val_in = (0x6000 | dev);
243 ret = ioctl(sk, method, &ifr);
244
245 usleep(1000);
246
247 method = RAETH_MII_READ;
248 mii.phy_id = port_num;
249 mii.reg_num = 14;
250 ret = ioctl(sk, method, &ifr);
251
252 close(sk);
253 *value = mii.val_out;
254
255 return ret;
256}
257
258int mii_mgr_cl45_write_ioctl(unsigned int port_num, unsigned int dev,
259 unsigned int reg, unsigned int value)
260{
261 int sk, method, ret;
262 struct ifreq ifr;
263 struct ra_mii_ioctl_data mii;
264
265 sk = socket(AF_INET, SOCK_DGRAM, 0);
266 if (sk < 0) {
267 printf("Open socket failed\n");
268
269 return -1;
270 }
271
272 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
273 ifr.ifr_data = &mii;
274
275 method = RAETH_MII_WRITE;
276 mii.phy_id = port_num;
277 mii.reg_num = 13;
278 mii.val_in = dev;
279 ret = ioctl(sk, method, &ifr);
280
281 method = RAETH_MII_WRITE;
282 mii.phy_id = port_num;
283 mii.reg_num = 14;
284 mii.val_in = reg;
285 ret = ioctl(sk, method, &ifr);
286
287 method = RAETH_MII_WRITE;
288 mii.phy_id = port_num;
289 mii.reg_num = 13;
290 mii.val_in = (0x6000 | dev);
291 ret = ioctl(sk, method, &ifr);
292
293 usleep(1000);
294
295 method = RAETH_MII_WRITE;
296 mii.phy_id = port_num;
297 mii.reg_num = 14;
298 mii.val_in = value;
299 ret = ioctl(sk, method, &ifr);
300
301 close(sk);
302
303 return ret;
304}
305
306int dump_gphy(void)
307{
308 int cl22_reg[6] = {0x00, 0x01, 0x04, 0x05, 0x09, 0x0A};
309 int cl45_start_reg = 0x9B;
310 int cl45_end_reg = 0xA2;
311 unsigned int value;
312 int port_num = 5;
313 int i, j, ret;
314
315 int sk, method;
316 struct ifreq ifr;
317 struct ra_mii_ioctl_data mii;
318
319 sk = socket(AF_INET, SOCK_DGRAM, 0);
320 if (sk < 0) {
321 printf("Open socket failed\n");
322 return -1;
323 }
324
325 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
326 ifr.ifr_data = &mii;
327 /* dump CL45 reg first*/
328 for (i = 0; i < port_num; i++) {
329 printf("== Port %d ==\n", i);
330 for (j = cl45_start_reg; j < (cl45_end_reg + 1); j++) {
331 ret = mii_mgr_cl45_read_ioctl(i, 0x1E, j, &value);
332 if (ret)
333 continue;
334 printf("dev1Eh_reg%xh = 0x%x\n", j, value);
335 }
336 }
337 printf("== Global ==\n");
338 for (i = 0; i < sizeof(cl22_reg) / sizeof(cl22_reg[0]); i++) {
339 method = RAETH_MII_READ;
340 mii.phy_id = 0;
341 mii.reg_num = cl22_reg[i];
342 ret = ioctl(sk, method, &ifr);
343 printf("Reg%xh = 0x%x\n", cl22_reg[i], mii.val_out);
344 }
345
346 close(sk);
347
348 return ret;
349}