blob: ca3f15bc9c8b44a620ad039b1ef5cf5ee6c1e74c [file] [log] [blame]
developer21ea8132022-07-11 11:52:59 +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(int offset, int *value)
33{
34 struct ifreq ifr;
35 struct esw_reg reg;
36
37 struct ra_mii_ioctl_data mii;
38 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
39 ifr.ifr_data = &mii;
40
41 mii.phy_id = 0x1f;
42 mii.reg_num = offset;
43
44 if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) {
45 perror("ioctl");
46 close(esw_fd);
47 exit(0);
48 }
49 *value = mii.val_out;
50 return 0;
51}
52
53int reg_read_tr(int offset, int *value)
54{
55 struct ifreq ifr;
56 struct esw_reg reg;
57 struct ra_mii_ioctl_data mii;
58
59 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
60 ifr.ifr_data = &mii;
61
62 mii.phy_id = 0;
63 mii.reg_num = offset;
64
65 if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) {
66 perror("ioctl");
67 close(esw_fd);
68 exit(0);
69 }
70 *value = mii.val_out;
71 return 0;
72}
73
74int reg_write_ioctl(int offset, int value)
75{
76 struct ifreq ifr;
77 struct esw_reg reg;
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 esw_reg reg;
99 struct ra_mii_ioctl_data mii;
100
101 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
102 ifr.ifr_data = &mii;
103
104 mii.phy_id = 0;
105 mii.reg_num = offset;
106 mii.val_in = value;
107
108 if (-1 == ioctl(esw_fd, RAETH_MII_WRITE, &ifr)) {
109 perror("ioctl");
110 close(esw_fd);
111 exit(0);
112 }
113 return 0;
114}
115
116int phy_dump_ioctl(int phy_addr)
117{
118 struct ifreq ifr;
119 struct esw_reg reg;
120
121 reg.val = phy_addr;
122 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
123 ifr.ifr_data = &reg;
124 if (-1 == ioctl(esw_fd, RAETH_ESW_PHY_DUMP, &ifr)) {
125 perror("ioctl");
126 close(esw_fd);
127 exit(0);
128 }
129 return 0;
130}
131
132int mii_mgr_cl22_read_ioctl(unsigned int port_num, unsigned int reg, int *value)
133{
134 int reg_value;
135 int loop_cnt;
136 int op_busy;
137
138 loop_cnt = 0;
139
140 /*Change to indirect access mode*/
141 /*if you need to use direct access mode, please change back manually by reset bit5*/
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",reg_value);
147 }
148 reg_value = 0x80090000 | (port_num << 20) | (reg << 25);
149 reg_write(0x701c, reg_value);
150 while (1)
151 {
152 reg_read(0x701c, &reg_value);
153 op_busy = reg_value & (1 << 31);
154 if (!op_busy) {
155 reg_value = reg_value & 0xFFFF;
156 break;
157 } else if (loop_cnt < 10)
158 loop_cnt++;
159 else {
160 printf("MDIO read opeartion timeout\n");
161 reg_value = 0;
162 break;
163 }
164 }
165 printf(" PHY Indirect Access Control(0x701c) register read value =0x%x \n", reg_value);
166 *value = reg_value;
167 return 0;
168}
169
170int mii_mgr_cl22_write_ioctl(unsigned int port_num, unsigned int reg, unsigned int value)
171{
172 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 return 0;
204}
205
206int mii_mgr_cl45_read_ioctl(int port_num, int dev, int reg, int *value)
207{
208 int sk, method, ret, i;
209 struct ifreq ifr;
210 struct ra_mii_ioctl_data mii;
211
212 sk = socket(AF_INET, SOCK_DGRAM, 0);
213 if (sk < 0)
214 printf("Open socket failed\n");
215
216 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
217 ifr.ifr_data = &mii;
218
219 method = RAETH_MII_WRITE;
220 mii.phy_id = port_num;
221 mii.reg_num = 13;
222 mii.val_in = dev;
223 ret = ioctl(sk, method, &ifr);
224
225 method = RAETH_MII_WRITE;
226 mii.phy_id = port_num;
227 mii.reg_num = 14;
228 mii.val_in = reg;
229 ret = ioctl(sk, method, &ifr);
230
231 method = RAETH_MII_WRITE;
232 mii.phy_id = port_num;
233 mii.reg_num = 13;
234 mii.val_in = (0x6000 | dev);
235 ret = ioctl(sk, method, &ifr);
236
237 usleep(1000);
238
239 method = RAETH_MII_READ;
240 mii.phy_id = port_num;
241 mii.reg_num = 14;
242 ret = ioctl(sk, method, &ifr);
243
244 close(sk);
245 *value = mii.val_out;
246 return 0;
247}
248
249int mii_mgr_cl45_write_ioctl(int port_num, int dev, int reg, int value)
250{
251 int sk, method, ret, i;
252 struct ifreq ifr;
253 struct ra_mii_ioctl_data mii;
254
255 sk = socket(AF_INET, SOCK_DGRAM, 0);
256 if (sk < 0)
257 printf("Open socket failed\n");
258
259 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
260 ifr.ifr_data = &mii;
261
262 method = RAETH_MII_WRITE;
263 mii.phy_id = port_num;
264 mii.reg_num = 13;
265 mii.val_in = dev;
266 ret = ioctl(sk, method, &ifr);
267
268 method = RAETH_MII_WRITE;
269 mii.phy_id = port_num;
270 mii.reg_num = 14;
271 mii.val_in = reg;
272 ret = ioctl(sk, method, &ifr);
273
274 method = RAETH_MII_WRITE;
275 mii.phy_id = port_num;
276 mii.reg_num = 13;
277 mii.val_in = (0x6000 | dev);
278 ret = ioctl(sk, method, &ifr);
279
280 usleep(1000);
281
282 method = RAETH_MII_WRITE;
283 mii.phy_id = port_num;
284 mii.reg_num = 14;
285 mii.val_in = value;
286 ret = ioctl(sk, method, &ifr);
287
288 close(sk);
289
290 return ret;
291}
292
293int dump_gphy(void)
294{
295 int port_num = 5;
296 int cl45_start_reg = 0x9B;
297 int cl45_end_reg = 0xA2;
298 int cl22_reg[6] = {0x00, 0x01, 0x04, 0x05, 0x09, 0x0A};
299 int i, j, ret;
300 int *value;
301
302 int sk, method;
303 struct ifreq ifr;
304 struct ra_mii_ioctl_data mii;
305
306 sk = socket(AF_INET, SOCK_DGRAM, 0);
307 if (sk < 0)
308 printf("Open socket failed\n");
309
310 strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
311 ifr.ifr_data = &mii;
312 /* dump CL45 reg first*/
313 for (i = 0; i < 5; i++) {
314 printf("== Port %d ==\n", i);
315 for (j = cl45_start_reg; j < (cl45_end_reg + 1); j++) {
316 mii_mgr_cl45_read_ioctl(i, 0x1E, j, value);
317 printf("dev1Eh_reg%xh = 0x%x\n", j, *value);
318 }
319 }
320 printf("== Global ==\n");
321 for (i = 0; i < 6; i++) {
322 method = RAETH_MII_READ;
323 mii.phy_id = 0;
324 mii.reg_num = cl22_reg[i];
325 ret = ioctl(sk, method, &ifr);
326 printf("Reg%xh = 0x%x\n", cl22_reg[i], mii.val_out);
327 }
328
329 close(sk);
330 return 0;
331}