1
2
3
4
5
6
7#include <linux/init.h>
8#include <linux/kobject.h>
9#include <linux/module.h>
10#include <linux/stat.h>
11#include <linux/string.h>
12#include <linux/sysfs.h>
13#include "xroe_framer.h"
14
15enum { XROE_SIZE_MAX = 15 };
16static int xroe_size;
17static char xroe_tmp[XROE_SIZE_MAX];
18
19
20
21
22
23
24
25
26
27
28
29
30static ssize_t version_show(struct kobject *kobj, struct kobj_attribute *attr,
31 char *buff)
32{
33 u32 major_rev;
34 u32 minor_rev;
35 u32 version_rev;
36
37 major_rev = utils_sysfs_show_wrapper(CFG_MAJOR_REVISION_ADDR,
38 CFG_MAJOR_REVISION_OFFSET,
39 CFG_MAJOR_REVISION_MASK, kobj);
40 minor_rev = utils_sysfs_show_wrapper(CFG_MINOR_REVISION_ADDR,
41 CFG_MINOR_REVISION_OFFSET,
42 CFG_MINOR_REVISION_MASK, kobj);
43 version_rev = utils_sysfs_show_wrapper(CFG_VERSION_REVISION_ADDR,
44 CFG_VERSION_REVISION_OFFSET,
45 CFG_VERSION_REVISION_MASK, kobj);
46 sprintf(buff, "%d.%d.%d\n", major_rev, minor_rev, version_rev);
47 return XROE_SIZE_MAX;
48}
49
50
51
52
53
54
55
56
57
58
59
60
61static ssize_t version_store(struct kobject *kobj, struct kobj_attribute *attr,
62 const char *buff, size_t count)
63{
64 return 0;
65}
66
67
68
69
70
71
72
73
74
75
76
77static ssize_t enable_show(struct kobject *kobj, struct kobj_attribute *attr,
78 char *buff)
79{
80 u32 enable;
81
82 enable = utils_sysfs_show_wrapper(CFG_MASTER_INT_ENABLE_ADDR,
83 CFG_MASTER_INT_ENABLE_OFFSET,
84 CFG_MASTER_INT_ENABLE_MASK, kobj);
85 if (enable)
86 sprintf(buff, "true\n");
87 else
88 sprintf(buff, "false\n");
89 return XROE_SIZE_MAX;
90}
91
92
93
94
95
96
97
98
99
100
101
102
103
104static ssize_t enable_store(struct kobject *kobj, struct kobj_attribute *attr,
105 const char *buff, size_t count)
106{
107 u32 enable = 0;
108
109 xroe_size = min_t(size_t, count, (size_t)XROE_SIZE_MAX);
110 strncpy(xroe_tmp, buff, xroe_size);
111 if (strncmp(xroe_tmp, "true", xroe_size) == 0)
112 enable = 1;
113 else if (strncmp(xroe_tmp, "false", xroe_size) == 0)
114 enable = 0;
115 utils_sysfs_store_wrapper(CFG_MASTER_INT_ENABLE_ADDR,
116 CFG_MASTER_INT_ENABLE_OFFSET,
117 CFG_MASTER_INT_ENABLE_MASK, enable, kobj);
118 return xroe_size;
119}
120
121
122
123
124
125
126
127
128
129
130
131static ssize_t framer_restart_show(struct kobject *kobj,
132 struct kobj_attribute *attr, char *buff)
133{
134 u32 restart;
135
136 restart = utils_sysfs_show_wrapper(FRAM_DISABLE_ADDR,
137 FRAM_DISABLE_OFFSET,
138 FRAM_DISABLE_MASK, kobj);
139 if (restart)
140 sprintf(buff, "true\n");
141
142 else
143 sprintf(buff, "false\n");
144
145 return XROE_SIZE_MAX;
146}
147
148
149
150
151
152
153
154
155
156
157
158
159
160static ssize_t framer_restart_store(struct kobject *kobj,
161 struct kobj_attribute *attr,
162 const char *buff, size_t count)
163{
164 u32 restart = 0;
165
166 xroe_size = min_t(size_t, count, (size_t)XROE_SIZE_MAX);
167 strncpy(xroe_tmp, buff, xroe_size);
168 if (strncmp(xroe_tmp, "true", xroe_size) == 0)
169 restart = 0x01;
170 else if (strncmp(xroe_tmp, "false", xroe_size) == 0)
171 restart = 0x00;
172 utils_sysfs_store_wrapper(FRAM_DISABLE_ADDR, FRAM_DISABLE_OFFSET,
173 FRAM_DISABLE_MASK, restart, kobj);
174 return xroe_size;
175}
176
177
178
179
180
181
182
183
184
185
186
187static ssize_t deframer_restart_show(struct kobject *kobj,
188 struct kobj_attribute *attr, char *buff)
189{
190 u32 offset = DEFM_RESTART_OFFSET;
191 u32 mask = DEFM_RESTART_MASK;
192 u32 buffer = 0;
193 u32 restart = 0;
194 void __iomem *working_address = ((u8 *)lp->base_addr
195 + DEFM_RESTART_ADDR);
196
197 buffer = ioread32(working_address);
198 restart = (buffer & mask) >> offset;
199
200 if (restart)
201 sprintf(buff, "true\n");
202
203 else
204 sprintf(buff, "false\n");
205
206 return XROE_SIZE_MAX;
207}
208
209
210
211
212
213
214
215
216
217
218
219
220
221static ssize_t deframer_restart_store(struct kobject *kobj,
222 struct kobj_attribute *attr,
223 const char *buff, size_t count)
224{
225 u32 offset = DEFM_RESTART_OFFSET;
226 u32 mask = DEFM_RESTART_MASK;
227 void __iomem *working_address = ((u8 *)lp->base_addr
228 + DEFM_RESTART_ADDR);
229 u32 restart = 0;
230
231 xroe_size = min_t(size_t, count, (size_t)XROE_SIZE_MAX);
232 strncpy(xroe_tmp, buff, xroe_size);
233 if (strncmp(xroe_tmp, "true", xroe_size) == 0) {
234 restart = 0x01;
235 utils_write32withmask(working_address, restart,
236 mask, offset);
237 } else if (strncmp(xroe_tmp, "false", xroe_size) == 0) {
238 restart = 0x00;
239 utils_write32withmask(working_address, restart,
240 mask, offset);
241 }
242
243 return xroe_size;
244}
245
246
247
248
249
250
251
252
253
254
255
256static ssize_t xxv_reset_show(struct kobject *kobj, struct kobj_attribute *attr,
257 char *buff)
258{
259 u32 offset = CFG_USER_RW_OUT_OFFSET;
260 u32 mask = CFG_USER_RW_OUT_MASK;
261 u32 buffer = 0;
262 u32 restart = 0;
263 void __iomem *working_address = ((u8 *)lp->base_addr +
264 CFG_USER_RW_OUT_ADDR);
265
266 buffer = ioread32(working_address);
267 restart = (buffer & mask) >> offset;
268 if (restart)
269 sprintf(buff, "true\n");
270 else
271 sprintf(buff, "false\n");
272 return XROE_SIZE_MAX;
273}
274
275
276
277
278
279
280
281
282
283
284
285
286
287static ssize_t xxv_reset_store(struct kobject *kobj,
288 struct kobj_attribute *attr,
289 const char *buff, size_t count)
290{
291 u32 offset = CFG_USER_RW_OUT_OFFSET;
292 u32 mask = CFG_USER_RW_OUT_MASK;
293 void __iomem *working_address = ((u8 *)lp->base_addr +
294 CFG_USER_RW_OUT_ADDR);
295 u32 restart = 0;
296
297 xroe_size = min_t(size_t, count, (size_t)XROE_SIZE_MAX);
298 strncpy(xroe_tmp, buff, xroe_size);
299
300 if (strncmp(xroe_tmp, "true", xroe_size) == 0) {
301 restart = 0x01;
302 utils_write32withmask(working_address, restart,
303 mask, offset);
304 } else if (strncmp(xroe_tmp, "false", xroe_size) == 0) {
305 restart = 0x00;
306 utils_write32withmask(working_address, restart,
307 mask, offset);
308 }
309 return xroe_size;
310}
311
312
313
314
315
316
317
318
319
320
321
322static ssize_t framing_show(struct kobject *kobj, struct kobj_attribute *attr,
323 char *buff)
324{
325 u32 offset = (DEFM_DATA_PKT_MESSAGE_TYPE_ADDR +
326 DEFM_DATA_PKT_MESSAGE_TYPE_OFFSET);
327 u8 buffer = 0;
328 u8 framing = 0xff;
329 void __iomem *working_address = ((u8 *)lp->base_addr + offset);
330
331 buffer = ioread8(working_address);
332 framing = buffer;
333 if (framing == 0)
334 sprintf(buff, "eCPRI\n");
335 else if (framing == 1)
336 sprintf(buff, "1914.3\n");
337 return XROE_SIZE_MAX;
338}
339
340
341
342
343
344
345
346
347
348
349
350
351
352static ssize_t framing_store(struct kobject *kobj, struct kobj_attribute *attr,
353 const char *buff, size_t count)
354{
355 u32 offset = (DEFM_DATA_PKT_MESSAGE_TYPE_ADDR +
356 DEFM_DATA_PKT_MESSAGE_TYPE_OFFSET);
357 void __iomem *working_address = ((u8 *)lp->base_addr + offset);
358
359 xroe_size = min_t(size_t, count, (size_t)XROE_SIZE_MAX);
360 strncpy(xroe_tmp, buff, xroe_size);
361 if (strncmp(xroe_tmp, "eCPRI", xroe_size) == 0)
362 iowrite8(0, working_address);
363 else if (strncmp(xroe_tmp, "1914.3", xroe_size) == 0)
364 iowrite8(1, working_address);
365 return xroe_size;
366}
367
368
369
370static struct kobj_attribute version_attribute =
371 __ATTR(version, 0444, version_show, version_store);
372
373static struct kobj_attribute enable_attribute =
374 __ATTR(enable, 0660, enable_show, enable_store);
375
376static struct kobj_attribute framer_restart =
377 __ATTR(framer_restart, 0660, framer_restart_show, framer_restart_store);
378
379static struct kobj_attribute deframer_restart =
380 __ATTR(deframer_restart, 0660, deframer_restart_show,
381 deframer_restart_store);
382
383static struct kobj_attribute xxv_reset =
384 __ATTR(xxv_reset, 0660, xxv_reset_show, xxv_reset_store);
385
386static struct kobj_attribute framing_attribute =
387 __ATTR(framing, 0660, framing_show, framing_store);
388
389static struct attribute *attrs[] = {
390 &version_attribute.attr,
391 &enable_attribute.attr,
392 &framer_restart.attr,
393 &deframer_restart.attr,
394 &xxv_reset.attr,
395 &framing_attribute.attr,
396 NULL,
397};
398
399static struct attribute_group attr_group = {
400 .attrs = attrs,
401};
402
403struct kobject *root_xroe_kobj;
404
405
406
407
408
409
410
411
412
413
414int xroe_sysfs_init(void)
415{
416 int ret;
417
418 root_xroe_kobj = kobject_create_and_add("xroe", kernel_kobj);
419 if (!root_xroe_kobj)
420 return -ENOMEM;
421 ret = sysfs_create_group(root_xroe_kobj, &attr_group);
422 if (ret)
423 kobject_put(root_xroe_kobj);
424 ret = xroe_sysfs_ipv4_init();
425 if (ret)
426 return ret;
427 ret = xroe_sysfs_ipv6_init();
428 if (ret)
429 return ret;
430 ret = xroe_sysfs_udp_init();
431 if (ret)
432 return ret;
433 ret = xroe_sysfs_stats_init();
434 return ret;
435}
436
437
438
439
440
441
442
443
444void xroe_sysfs_exit(void)
445{
446 int i;
447
448 xroe_sysfs_ipv4_exit();
449 xroe_sysfs_ipv6_exit();
450 xroe_sysfs_udp_exit();
451 xroe_sysfs_stats_exit();
452 for (i = 0; i < MAX_NUM_ETH_PORTS; i++)
453 kobject_put(kobj_eth_ports[i]);
454 kobject_put(kobj_framer);
455 kobject_put(root_xroe_kobj);
456}
457
458
459
460
461
462
463
464
465
466
467
468
469int utils_write32withmask(void __iomem *working_address, u32 value,
470 u32 mask, u32 offset)
471{
472 u32 read_register_value = 0;
473 u32 register_value_to_write = 0;
474 u32 delta = 0, buffer = 0;
475
476 read_register_value = ioread32(working_address);
477 buffer = (value << offset);
478 register_value_to_write = read_register_value & ~mask;
479 delta = buffer & mask;
480 register_value_to_write |= delta;
481 iowrite32(register_value_to_write, working_address);
482 return 0;
483}
484
485
486
487
488
489
490
491
492
493
494static int utils_sysfs_path_to_eth_port_num(struct kobject *kobj)
495{
496 char *current_path = NULL;
497 int port;
498 int ret;
499
500 current_path = kobject_get_path(kobj, GFP_KERNEL);
501 ret = sscanf(current_path, "/kernel/xroe/framer/eth_port_%d/", &port);
502
503
504
505 if (ret == 0)
506 port = 0;
507
508 kfree(current_path);
509 return port;
510}
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525void utils_sysfs_store_wrapper(u32 address, u32 offset, u32 mask, u32 value,
526 struct kobject *kobj)
527{
528 int port;
529 void __iomem *working_address;
530
531 port = utils_sysfs_path_to_eth_port_num(kobj);
532 working_address = (void __iomem *)(lp->base_addr +
533 (address + (0x100 * port)));
534 utils_write32withmask(working_address, value, mask, offset);
535}
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550u32 utils_sysfs_show_wrapper(u32 address, u32 offset, u32 mask,
551 struct kobject *kobj)
552{
553 int port;
554 void __iomem *working_address;
555 u32 buffer;
556
557 port = utils_sysfs_path_to_eth_port_num(kobj);
558 working_address = (void __iomem *)(lp->base_addr +
559 (address + (0x100 * port)));
560 buffer = ioread32(working_address);
561 return (buffer & mask) >> offset;
562}
563