]> rtime.felk.cvut.cz Git - lisovros/linux_canprio.git/blob - drivers/staging/batman-adv/bat_sysfs.c
Staging: batman-adv: remove redundant struct declaration
[lisovros/linux_canprio.git] / drivers / staging / batman-adv / bat_sysfs.c
1 /*
2  * Copyright (C) 2010 B.A.T.M.A.N. contributors:
3  *
4  * Marek Lindner
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of version 2 of the GNU General Public
8  * License as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA
19  *
20  */
21
22 #include "main.h"
23 #include "bat_sysfs.h"
24 #include "translation-table.h"
25 #include "originator.h"
26 #include "hard-interface.h"
27 #include "vis.h"
28
29 #define to_dev(obj)     container_of(obj, struct device, kobj)
30
31 #define BAT_ATTR(_name, _mode, _show, _store)   \
32 struct bat_attribute bat_attr_##_name = {       \
33         .attr = {.name = __stringify(_name),    \
34                  .mode = _mode },               \
35         .show   = _show,                        \
36         .store  = _store,                       \
37 };
38
39 #define BAT_BIN_ATTR(_name, _mode, _read, _write)       \
40 struct bin_attribute bat_attr_##_name = {               \
41         .attr = { .name = __stringify(_name),           \
42                   .mode = _mode, },                     \
43         .read = _read,                                  \
44         .write = _write,                                \
45 };
46
47 static ssize_t show_aggr_ogm(struct kobject *kobj, struct attribute *attr,
48                              char *buff)
49 {
50         struct device *dev = to_dev(kobj->parent);
51         struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
52         int aggr_status = atomic_read(&bat_priv->aggregation_enabled);
53
54         return sprintf(buff, "status: %s\ncommands: enable, disable, 0, 1\n",
55                        aggr_status == 0 ? "disabled" : "enabled");
56 }
57
58 static ssize_t store_aggr_ogm(struct kobject *kobj, struct attribute *attr,
59                               char *buff, size_t count)
60 {
61         struct device *dev = to_dev(kobj->parent);
62         struct net_device *net_dev = to_net_dev(dev);
63         struct bat_priv *bat_priv = netdev_priv(net_dev);
64         int aggr_tmp = -1;
65
66         if (((count == 2) && (buff[0] == '1')) ||
67             (strncmp(buff, "enable", 6) == 0))
68                 aggr_tmp = 1;
69
70         if (((count == 2) && (buff[0] == '0')) ||
71             (strncmp(buff, "disable", 7) == 0))
72                 aggr_tmp = 0;
73
74         if (aggr_tmp < 0) {
75                 if (buff[count - 1] == '\n')
76                         buff[count - 1] = '\0';
77
78                 printk(KERN_INFO "batman-adv:Invalid parameter for 'aggregate OGM' setting on mesh %s received: %s\n",
79                        net_dev->name, buff);
80                 return -EINVAL;
81         }
82
83         if (atomic_read(&bat_priv->aggregation_enabled) == aggr_tmp)
84                 return count;
85
86         printk(KERN_INFO "batman-adv:Changing aggregation from: %s to: %s on mesh: %s\n",
87                atomic_read(&bat_priv->aggregation_enabled) == 1 ?
88                "enabled" : "disabled", aggr_tmp == 1 ? "enabled" : "disabled",
89                net_dev->name);
90
91         atomic_set(&bat_priv->aggregation_enabled, (unsigned)aggr_tmp);
92         return count;
93 }
94
95 static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr,
96                              char *buff)
97 {
98         struct device *dev = to_dev(kobj->parent);
99         struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
100         int vis_mode = atomic_read(&bat_priv->vis_mode);
101
102         return sprintf(buff, "status: %s\ncommands: client, server, %d, %d\n",
103                        vis_mode == VIS_TYPE_CLIENT_UPDATE ?
104                                                         "client" : "server",
105                        VIS_TYPE_SERVER_SYNC, VIS_TYPE_CLIENT_UPDATE);
106 }
107
108 static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
109                               char *buff, size_t count)
110 {
111         struct device *dev = to_dev(kobj->parent);
112         struct net_device *net_dev = to_net_dev(dev);
113         struct bat_priv *bat_priv = netdev_priv(net_dev);
114         unsigned long val;
115         int ret, vis_mode_tmp = -1;
116
117         ret = strict_strtoul(buff, 10, &val);
118
119         if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) ||
120             (strncmp(buff, "client", 6) == 0))
121                 vis_mode_tmp = VIS_TYPE_CLIENT_UPDATE;
122
123         if (((count == 2) && (!ret) && (val == VIS_TYPE_SERVER_SYNC)) ||
124             (strncmp(buff, "server", 6) == 0))
125                 vis_mode_tmp = VIS_TYPE_SERVER_SYNC;
126
127         if (vis_mode_tmp < 0) {
128                 if (buff[count - 1] == '\n')
129                         buff[count - 1] = '\0';
130
131                 printk(KERN_INFO "batman-adv:Invalid parameter for 'vis mode' setting on mesh %s received: %s\n",
132                        net_dev->name, buff);
133                 return -EINVAL;
134         }
135
136         if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp)
137                 return count;
138
139         printk(KERN_INFO "batman-adv:Changing vis mode from: %s to: %s on mesh: %s\n",
140                atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ?
141                "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ?
142                "client" : "server", net_dev->name);
143
144         atomic_set(&bat_priv->vis_mode, (unsigned)vis_mode_tmp);
145         return count;
146 }
147
148 static ssize_t show_orig_interval(struct kobject *kobj, struct attribute *attr,
149                                  char *buff)
150 {
151         struct device *dev = to_dev(kobj->parent);
152         struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
153
154         return sprintf(buff, "status: %i\n",
155                        atomic_read(&bat_priv->orig_interval));
156 }
157
158 static ssize_t store_orig_interval(struct kobject *kobj, struct attribute *attr,
159                                   char *buff, size_t count)
160 {
161         struct device *dev = to_dev(kobj->parent);
162         struct net_device *net_dev = to_net_dev(dev);
163         struct bat_priv *bat_priv = netdev_priv(net_dev);
164         unsigned long orig_interval_tmp;
165         int ret;
166
167         ret = strict_strtoul(buff, 10, &orig_interval_tmp);
168         if (ret) {
169                 printk(KERN_INFO "batman-adv:Invalid parameter for 'orig_interval' setting on mesh %s received: %s\n",
170                        net_dev->name, buff);
171                 return -EINVAL;
172         }
173
174         if (orig_interval_tmp <= JITTER * 2) {
175                 printk(KERN_INFO "batman-adv:New originator interval too small: %li (min: %i)\n",
176                        orig_interval_tmp, JITTER * 2);
177                 return -EINVAL;
178         }
179
180         if (atomic_read(&bat_priv->orig_interval) == orig_interval_tmp)
181                 return count;
182
183         printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li on mesh: %s\n",
184                atomic_read(&bat_priv->orig_interval),
185                orig_interval_tmp, net_dev->name);
186
187         atomic_set(&bat_priv->orig_interval, orig_interval_tmp);
188         return count;
189 }
190
191 static BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR,
192                 show_aggr_ogm, store_aggr_ogm);
193 static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
194 static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR,
195                 show_orig_interval, store_orig_interval);
196
197 static struct bat_attribute *mesh_attrs[] = {
198         &bat_attr_aggregate_ogm,
199         &bat_attr_vis_mode,
200         &bat_attr_orig_interval,
201         NULL,
202 };
203
204 static ssize_t transtable_local_read(struct kobject *kobj,
205                                struct bin_attribute *bin_attr,
206                                char *buff, loff_t off, size_t count)
207 {
208         struct device *dev = to_dev(kobj->parent);
209         struct net_device *net_dev = to_net_dev(dev);
210
211         return hna_local_fill_buffer_text(net_dev, buff, count, off);
212 }
213
214 static ssize_t transtable_global_read(struct kobject *kobj,
215                                struct bin_attribute *bin_attr,
216                                char *buff, loff_t off, size_t count)
217 {
218         struct device *dev = to_dev(kobj->parent);
219         struct net_device *net_dev = to_net_dev(dev);
220
221         return hna_global_fill_buffer_text(net_dev, buff, count, off);
222 }
223
224 static ssize_t originators_read(struct kobject *kobj,
225                                struct bin_attribute *bin_attr,
226                                char *buff, loff_t off, size_t count)
227 {
228         struct device *dev = to_dev(kobj->parent);
229         struct net_device *net_dev = to_net_dev(dev);
230
231         return orig_fill_buffer_text(net_dev, buff, count, off);
232 }
233
234 static ssize_t vis_data_read(struct kobject *kobj,
235                              struct bin_attribute *bin_attr,
236                              char *buff, loff_t off, size_t count)
237 {
238         struct device *dev = to_dev(kobj->parent);
239         struct net_device *net_dev = to_net_dev(dev);
240
241         return vis_fill_buffer_text(net_dev, buff, count, off);
242 }
243
244 static BAT_BIN_ATTR(transtable_local, S_IRUGO, transtable_local_read, NULL);
245 static BAT_BIN_ATTR(transtable_global, S_IRUGO, transtable_global_read, NULL);
246 static BAT_BIN_ATTR(originators, S_IRUGO, originators_read, NULL);
247 static BAT_BIN_ATTR(vis_data, S_IRUGO, vis_data_read, NULL);
248
249 static struct bin_attribute *mesh_bin_attrs[] = {
250         &bat_attr_transtable_local,
251         &bat_attr_transtable_global,
252         &bat_attr_originators,
253         &bat_attr_vis_data,
254         NULL,
255 };
256
257 int sysfs_add_meshif(struct net_device *dev)
258 {
259         struct kobject *batif_kobject = &dev->dev.kobj;
260         struct bat_priv *bat_priv = netdev_priv(dev);
261         struct bat_attribute **bat_attr;
262         struct bin_attribute **bin_attr;
263         int err;
264
265         /* FIXME: should be done in the general mesh setup
266                   routine as soon as we have it */
267         atomic_set(&bat_priv->aggregation_enabled, 1);
268         atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
269         atomic_set(&bat_priv->orig_interval, 1000);
270         bat_priv->primary_if = NULL;
271         bat_priv->num_ifaces = 0;
272
273         bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR,
274                                                     batif_kobject);
275         if (!bat_priv->mesh_obj) {
276                 printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n",
277                        dev->name, SYSFS_IF_MESH_SUBDIR);
278                 goto out;
279         }
280
281         for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) {
282                 err = sysfs_create_file(bat_priv->mesh_obj,
283                                         &((*bat_attr)->attr));
284                 if (err) {
285                         printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
286                                dev->name, SYSFS_IF_MESH_SUBDIR,
287                                ((*bat_attr)->attr).name);
288                         goto rem_attr;
289                 }
290         }
291
292         for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) {
293                 err = sysfs_create_bin_file(bat_priv->mesh_obj, (*bin_attr));
294                 if (err) {
295                         printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
296                                dev->name, SYSFS_IF_MESH_SUBDIR,
297                                ((*bin_attr)->attr).name);
298                         goto rem_bin_attr;
299                 }
300         }
301
302         return 0;
303
304 rem_bin_attr:
305         for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr)
306                 sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr));
307 rem_attr:
308         for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
309                 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
310
311         kobject_put(bat_priv->mesh_obj);
312         bat_priv->mesh_obj = NULL;
313 out:
314         return -ENOMEM;
315 }
316
317 void sysfs_del_meshif(struct net_device *dev)
318 {
319         struct bat_priv *bat_priv = netdev_priv(dev);
320         struct bat_attribute **bat_attr;
321         struct bin_attribute **bin_attr;
322
323         for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr)
324                 sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr));
325
326         for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
327                 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
328
329         kobject_put(bat_priv->mesh_obj);
330         bat_priv->mesh_obj = NULL;
331 }
332
333 static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr,
334                                char *buff)
335 {
336         struct device *dev = to_dev(kobj->parent);
337         struct net_device *net_dev = to_net_dev(dev);
338         struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
339
340         if (!batman_if)
341                 return 0;
342
343         return sprintf(buff, "status: %s\ncommands: none, bat0\n",
344                        batman_if->if_status == IF_NOT_IN_USE ?
345                                                         "none" : "bat0");
346 }
347
348 static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
349                                 char *buff, size_t count)
350 {
351         struct device *dev = to_dev(kobj->parent);
352         struct net_device *net_dev = to_net_dev(dev);
353         struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
354         int status_tmp = -1;
355
356         if (!batman_if)
357                 return count;
358
359         if (strncmp(buff, "none", 4) == 0)
360                 status_tmp = IF_NOT_IN_USE;
361
362         if (strncmp(buff, "bat0", 4) == 0)
363                 status_tmp = IF_I_WANT_YOU;
364
365         if (status_tmp < 0) {
366                 if (buff[count - 1] == '\n')
367                         buff[count - 1] = '\0';
368
369                 printk(KERN_ERR "batman-adv:Invalid parameter for 'mesh_iface' setting received: %s\n",
370                        buff);
371                 return -EINVAL;
372         }
373
374         if ((batman_if->if_status == status_tmp) ||
375             ((status_tmp == IF_I_WANT_YOU) &&
376              (batman_if->if_status != IF_NOT_IN_USE)))
377                 return count;
378
379         if (status_tmp == IF_I_WANT_YOU)
380                 status_tmp = hardif_enable_interface(batman_if);
381         else
382                 hardif_disable_interface(batman_if);
383
384         return (status_tmp < 0 ? status_tmp : count);
385 }
386
387 static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr,
388                                  char *buff)
389 {
390         struct device *dev = to_dev(kobj->parent);
391         struct net_device *net_dev = to_net_dev(dev);
392         struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
393
394         if (!batman_if)
395                 return 0;
396
397         switch (batman_if->if_status) {
398         case IF_TO_BE_REMOVED:
399                 return sprintf(buff, "disabling\n");
400         case IF_INACTIVE:
401                 return sprintf(buff, "inactive\n");
402         case IF_ACTIVE:
403                 return sprintf(buff, "active\n");
404         case IF_TO_BE_ACTIVATED:
405                 return sprintf(buff, "enabling\n");
406         case IF_NOT_IN_USE:
407         default:
408                 return sprintf(buff, "not in use\n");
409         }
410 }
411
412 static BAT_ATTR(mesh_iface, S_IRUGO | S_IWUSR,
413                 show_mesh_iface, store_mesh_iface);
414 static BAT_ATTR(iface_status, S_IRUGO, show_iface_status, NULL);
415
416 static struct bat_attribute *batman_attrs[] = {
417         &bat_attr_mesh_iface,
418         &bat_attr_iface_status,
419         NULL,
420 };
421
422 int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)
423 {
424         struct kobject *hardif_kobject = &dev->dev.kobj;
425         struct bat_attribute **bat_attr;
426         int err;
427
428         *hardif_obj = kobject_create_and_add(SYSFS_IF_BAT_SUBDIR,
429                                                     hardif_kobject);
430
431         if (!*hardif_obj) {
432                 printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n",
433                        dev->name, SYSFS_IF_BAT_SUBDIR);
434                 goto out;
435         }
436
437         for (bat_attr = batman_attrs; *bat_attr; ++bat_attr) {
438                 err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr));
439                 if (err) {
440                         printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
441                                dev->name, SYSFS_IF_BAT_SUBDIR,
442                                ((*bat_attr)->attr).name);
443                         goto rem_attr;
444                 }
445         }
446
447         return 0;
448
449 rem_attr:
450         for (bat_attr = batman_attrs; *bat_attr; ++bat_attr)
451                 sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr));
452 out:
453         return -ENOMEM;
454 }
455
456 void sysfs_del_hardif(struct kobject **hardif_obj)
457 {
458         kobject_put(*hardif_obj);
459         *hardif_obj = NULL;
460 }