blob: 082eab1c013f49fe0629e0f6ccf4ef96bc6ee28c [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001/*
2 * switch_ioctl.c: switch(ioctl) set API
3 */
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <unistd.h>
8#include <string.h>
9#include <sys/ioctl.h>
10#include <sys/socket.h>
11#include <linux/if.h>
12
13#include "switch_fun.h"
14#include "switch_ioctl.h"
15
16static int esw_fd;
17
18void switch_ioctl_init(void)
19{
20 esw_fd = socket(AF_INET, SOCK_DGRAM, 0);
21 if (esw_fd < 0) {
22 perror("socket");
23 exit(0);
24 }
25}
26
27void switch_ioctl_fini(void)
28{
29 close(esw_fd);
30}
31
32int reg_read_ioctl(unsigned int offset, unsigned int *value)
33{
34 struct ifreq ifr;
35 struct ra_mii_ioctl_data mii;
36
37 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
38 ifr.ifr_data = &mii;
39
40 mii.phy_id = 0x1f;
41 mii.reg_num = offset;
42
43 if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) {
44 perror("ioctl");
45 close(esw_fd);
46 exit(0);
47 }
48 *value = mii.val_out;
49 return 0;
50}
51
52int reg_read_tr(int offset, int *value)
53{
54 struct ifreq ifr;
55 struct ra_mii_ioctl_data mii;
56
57 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
58 ifr.ifr_data = &mii;
59
60 mii.phy_id = 0;
61 mii.reg_num = offset;
62
63 if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) {
64 perror("ioctl");
65 close(esw_fd);
66 exit(0);
67 }
68 *value = mii.val_out;
69 return 0;
70}
71
72int reg_write_ioctl(unsigned int offset, unsigned int value)
73{
74 struct ifreq ifr;
75 struct ra_mii_ioctl_data mii;
76
77 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
78 ifr.ifr_data = &mii;
79
80 mii.phy_id = 0x1f;
81 mii.reg_num = offset;
82 mii.val_in = value;
83
84 if (-1 == ioctl(esw_fd, RAETH_MII_WRITE, &ifr)) {
85 perror("ioctl");
86 close(esw_fd);
87 exit(0);
88 }
89 return 0;
90}
91
92int reg_write_tr(int offset, int value)
93{
94 struct ifreq ifr;
95 struct ra_mii_ioctl_data mii;
96
97 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
98 ifr.ifr_data = &mii;
99
100 mii.phy_id = 0;
101 mii.reg_num = offset;
102 mii.val_in = value;
103
104 if (-1 == ioctl(esw_fd, RAETH_MII_WRITE, &ifr)) {
105 perror("ioctl");
106 close(esw_fd);
107 exit(0);
108 }
109 return 0;
110}
111
112int phy_dump_ioctl(unsigned int phy_addr)
113{
114 struct ifreq ifr;
115 struct esw_reg reg;
116
117 reg.val = phy_addr;
118 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
119 ifr.ifr_data = &reg;
120 if (-1 == ioctl(esw_fd, RAETH_ESW_PHY_DUMP, &ifr)) {
121 perror("ioctl");
122 close(esw_fd);
123 exit(0);
124 }
125 return 0;
126}
127
128int mii_mgr_cl22_read_ioctl(unsigned int port_num, unsigned int reg, unsigned int *value)
129{
130 unsigned int reg_value;
131 int loop_cnt;
132 int op_busy;
133
134 loop_cnt = 0;
135
136 /*Change to indirect access mode*/
137 /*if you need to use direct access mode, please change back manually by reset bit5*/
138 reg_read(0x7804, &reg_value);
139 if (((reg_value >> 5) & 0x1) == 0) {
140 reg_value |= 1 << 5;
141 reg_write(0x7804, reg_value);
142 printf("Change to indirect access mode:0x%x\n", reg_value);
143 }
144 reg_value = 0x80090000 | (port_num << 20) | (reg << 25);
145 reg_write(0x701c, reg_value);
146 while (1)
147 {
148 reg_read(0x701c, &reg_value);
149 op_busy = reg_value & (1 << 31);
150 if (!op_busy) {
151 reg_value = reg_value & 0xFFFF;
152 break;
153 } else if (loop_cnt < 10)
154 loop_cnt++;
155 else {
156 printf("MDIO read opeartion timeout\n");
157 reg_value = 0;
158 break;
159 }
160 }
161 printf(" PHY Indirect Access Control(0x701c) register read value =0x%x \n", reg_value);
162 *value = reg_value;
163
164 return 0;
165}
166
167int mii_mgr_cl22_write_ioctl(unsigned int port_num, unsigned int reg, unsigned int value)
168{
169 unsigned int reg_value;
170 int loop_cnt;
171 int op_busy;
172
173 loop_cnt = 0;
174 /*Change to indirect access mode*/
175 /*if you need to use direct access mode, please change back manually by reset bit5*/
176 reg_read(0x7804, &reg_value);
177 if (((reg_value >> 5) & 0x1) == 0) {
178 reg_value |= 1 << 5;
179 reg_write(0x7804, reg_value);
180 printf("Change to indirect access mode:0x%x\n", reg_value);
181 }
182
183 reg_value = 0x80050000 | (port_num << 20) | (reg << 25) | value;
184 reg_write(0x701c, reg_value);
185 while (1)
186 {
187 reg_read(0x701c, &reg_value);
188 op_busy = reg_value & (1 << 31);
189 if (!op_busy)
190 break;
191 else if (loop_cnt < 10)
192 loop_cnt++;
193 else {
194 printf("MDIO write opeartion timeout\n");
195 break;
196 }
197 }
198
199 printf(" PHY Indirect Access Control(0x701c) register write value =0x%x \n", reg_value);
200
201 return 0;
202}
203
204int mii_mgr_cl45_read_ioctl(unsigned int port_num, unsigned int dev,
205 unsigned int reg, unsigned int *value)
206{
207 int sk, method, ret;
208 struct ifreq ifr;
209 struct ra_mii_ioctl_data mii;
210
211 if (!value)
212 return -1;
213
214 sk = socket(AF_INET, SOCK_DGRAM, 0);
215 if (sk < 0) {
216 printf("Open socket failed\n");
217
218 return -1;
219 }
220
221 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
222 ifr.ifr_data = &mii;
223
224 method = RAETH_MII_WRITE;
225 mii.phy_id = port_num;
226 mii.reg_num = 13;
227 mii.val_in = dev;
228 ret = ioctl(sk, method, &ifr);
229
230 method = RAETH_MII_WRITE;
231 mii.phy_id = port_num;
232 mii.reg_num = 14;
233 mii.val_in = reg;
234 ret = ioctl(sk, method, &ifr);
235
236 method = RAETH_MII_WRITE;
237 mii.phy_id = port_num;
238 mii.reg_num = 13;
239 mii.val_in = (0x6000 | dev);
240 ret = ioctl(sk, method, &ifr);
241
242 usleep(1000);
243
244 method = RAETH_MII_READ;
245 mii.phy_id = port_num;
246 mii.reg_num = 14;
247 ret = ioctl(sk, method, &ifr);
248
249 close(sk);
250 *value = mii.val_out;
251
252 return ret;
253}
254
255int mii_mgr_cl45_write_ioctl(unsigned int port_num, unsigned int dev,
256 unsigned int reg, unsigned int value)
257{
258 int sk, method, ret;
259 struct ifreq ifr;
260 struct ra_mii_ioctl_data mii;
261
262 sk = socket(AF_INET, SOCK_DGRAM, 0);
263 if (sk < 0) {
264 printf("Open socket failed\n");
265
266 return -1;
267 }
268
269 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
270 ifr.ifr_data = &mii;
271
272 method = RAETH_MII_WRITE;
273 mii.phy_id = port_num;
274 mii.reg_num = 13;
275 mii.val_in = dev;
276 ret = ioctl(sk, method, &ifr);
277
278 method = RAETH_MII_WRITE;
279 mii.phy_id = port_num;
280 mii.reg_num = 14;
281 mii.val_in = reg;
282 ret = ioctl(sk, method, &ifr);
283
284 method = RAETH_MII_WRITE;
285 mii.phy_id = port_num;
286 mii.reg_num = 13;
287 mii.val_in = (0x6000 | dev);
288 ret = ioctl(sk, method, &ifr);
289
290 usleep(1000);
291
292 method = RAETH_MII_WRITE;
293 mii.phy_id = port_num;
294 mii.reg_num = 14;
295 mii.val_in = value;
296 ret = ioctl(sk, method, &ifr);
297
298 close(sk);
299
300 return ret;
301}
302
303int dump_gphy(void)
304{
305 int cl22_reg[6] = {0x00, 0x01, 0x04, 0x05, 0x09, 0x0A};
306 int cl45_start_reg = 0x9B;
307 int cl45_end_reg = 0xA2;
308 unsigned int value;
309 int port_num = 5;
310 int i, j, ret;
311
312 int sk, method;
313 struct ifreq ifr;
314 struct ra_mii_ioctl_data mii;
315
316 sk = socket(AF_INET, SOCK_DGRAM, 0);
317 if (sk < 0) {
318 printf("Open socket failed\n");
319 return -1;
320 }
321
322 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
323 ifr.ifr_data = &mii;
324 /* dump CL45 reg first*/
325 for (i = 0; i < port_num; i++) {
326 printf("== Port %d ==\n", i);
327 for (j = cl45_start_reg; j < (cl45_end_reg + 1); j++) {
328 ret = mii_mgr_cl45_read_ioctl(i, 0x1E, j, &value);
329 if (ret)
330 continue;
331 printf("dev1Eh_reg%xh = 0x%x\n", j, value);
332 }
333 }
334 printf("== Global ==\n");
335 for (i = 0; i < sizeof(cl22_reg) / sizeof(cl22_reg[0]); i++) {
336 method = RAETH_MII_READ;
337 mii.phy_id = 0;
338 mii.reg_num = cl22_reg[i];
339 ret = ioctl(sk, method, &ifr);
340 printf("Reg%xh = 0x%x\n", cl22_reg[i], mii.val_out);
341 }
342
343 close(sk);
344
345 return ret;
346}