Staging: batman-adv: move originator interval setting from /proc to /sys
[linux-2.6.git] / drivers / staging / batman-adv / bat_sysfs.c
blobea7ce775009a8a095689f1bec280d724a21ea7a4
1 /*
2 * Copyright (C) 2010 B.A.T.M.A.N. contributors:
4 * Marek Lindner
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.
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.
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
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"
29 #define to_dev(obj) container_of(obj, struct device, kobj)
31 struct bat_attribute {
32 struct attribute attr;
33 ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
34 char *buf);
35 ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
36 char *buf, size_t count);
39 #define BAT_ATTR(_name, _mode, _show, _store) \
40 struct bat_attribute bat_attr_##_name = { \
41 .attr = {.name = __stringify(_name), \
42 .mode = _mode }, \
43 .show = _show, \
44 .store = _store, \
47 #define BAT_BIN_ATTR(_name, _mode, _read, _write) \
48 struct bin_attribute bat_attr_##_name = { \
49 .attr = { .name = __stringify(_name), \
50 .mode = _mode, }, \
51 .read = _read, \
52 .write = _write, \
55 static ssize_t show_aggr_ogm(struct kobject *kobj, struct attribute *attr,
56 char *buff)
58 struct device *dev = to_dev(kobj->parent);
59 struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
60 int aggr_status = atomic_read(&bat_priv->aggregation_enabled);
62 return sprintf(buff, "status: %s\ncommands: enable, disable, 0, 1 \n",
63 aggr_status == 0 ? "disabled" : "enabled");
66 static ssize_t store_aggr_ogm(struct kobject *kobj, struct attribute *attr,
67 char *buff, size_t count)
69 struct device *dev = to_dev(kobj->parent);
70 struct net_device *net_dev = to_net_dev(dev);
71 struct bat_priv *bat_priv = netdev_priv(net_dev);
72 int aggr_tmp = -1;
74 if (((count == 2) && (buff[0] == '1')) ||
75 (strncmp(buff, "enable", 6) == 0))
76 aggr_tmp = 1;
78 if (((count == 2) && (buff[0] == '0')) ||
79 (strncmp(buff, "disable", 7) == 0))
80 aggr_tmp = 0;
82 if (aggr_tmp < 0) {
83 if (buff[count - 1] == '\n')
84 buff[count - 1] = '\0';
86 printk(KERN_INFO "batman-adv:Invalid parameter for 'aggregate OGM' setting on mesh %s received: %s\n",
87 net_dev->name, buff);
88 return -EINVAL;
91 if (atomic_read(&bat_priv->aggregation_enabled) == aggr_tmp)
92 return count;
94 printk(KERN_INFO "batman-adv:Changing aggregation from: %s to: %s on mesh: %s\n",
95 atomic_read(&bat_priv->aggregation_enabled) == 1 ?
96 "enabled" : "disabled", aggr_tmp == 1 ? "enabled" : "disabled",
97 net_dev->name);
99 atomic_set(&bat_priv->aggregation_enabled, (unsigned)aggr_tmp);
100 return count;
103 static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr,
104 char *buff)
106 struct device *dev = to_dev(kobj->parent);
107 struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
108 int vis_mode = atomic_read(&bat_priv->vis_mode);
110 return sprintf(buff, "status: %s\ncommands: client, server, %d, %d \n",
111 vis_mode == VIS_TYPE_CLIENT_UPDATE ?
112 "client" : "server",
113 VIS_TYPE_SERVER_SYNC, VIS_TYPE_CLIENT_UPDATE);
116 static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
117 char *buff, size_t count)
119 struct device *dev = to_dev(kobj->parent);
120 struct net_device *net_dev = to_net_dev(dev);
121 struct bat_priv *bat_priv = netdev_priv(net_dev);
122 unsigned long val;
123 int ret, vis_mode_tmp = -1;
125 ret = strict_strtoul(buff, 10, &val);
127 if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) ||
128 (strncmp(buff, "client", 6) == 0))
129 vis_mode_tmp = VIS_TYPE_CLIENT_UPDATE;
131 if (((count == 2) && (!ret) && (val == VIS_TYPE_SERVER_SYNC)) ||
132 (strncmp(buff, "server", 6) == 0))
133 vis_mode_tmp = VIS_TYPE_SERVER_SYNC;
135 if (vis_mode_tmp < 0) {
136 if (buff[count - 1] == '\n')
137 buff[count - 1] = '\0';
139 printk(KERN_INFO "batman-adv:Invalid parameter for 'vis mode' setting on mesh %s received: %s\n",
140 net_dev->name, buff);
141 return -EINVAL;
144 if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp)
145 return count;
147 printk(KERN_INFO "batman-adv:Changing vis mode from: %s to: %s on mesh: %s\n",
148 atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ?
149 "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ?
150 "client" : "server", net_dev->name);
152 atomic_set(&bat_priv->vis_mode, (unsigned)vis_mode_tmp);
153 return count;
156 static ssize_t show_orig_interval(struct kobject *kobj, struct attribute *attr,
157 char *buff)
159 struct device *dev = to_dev(kobj->parent);
160 struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
162 return sprintf(buff, "status: %i\n",
163 atomic_read(&bat_priv->orig_interval));
166 static ssize_t store_orig_interval(struct kobject *kobj, struct attribute *attr,
167 char *buff, size_t count)
169 struct device *dev = to_dev(kobj->parent);
170 struct net_device *net_dev = to_net_dev(dev);
171 struct bat_priv *bat_priv = netdev_priv(net_dev);
172 unsigned long orig_interval_tmp;
173 int ret;
175 ret = strict_strtoul(buff, 10, &orig_interval_tmp);
176 if (ret) {
177 printk(KERN_INFO "batman-adv:Invalid parameter for 'orig_interval' setting on mesh %s received: %s\n",
178 net_dev->name, buff);
179 return -EINVAL;
182 if (orig_interval_tmp <= JITTER * 2) {
183 printk(KERN_INFO "batman-adv:New originator interval too small: %li (min: %i)\n",
184 orig_interval_tmp, JITTER * 2);
185 return -EINVAL;
188 if (atomic_read(&bat_priv->orig_interval) == orig_interval_tmp)
189 return count;
191 printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li on mesh: %s\n",
192 atomic_read(&bat_priv->orig_interval),
193 orig_interval_tmp, net_dev->name);
195 atomic_set(&bat_priv->orig_interval, orig_interval_tmp);
196 return count;
199 static BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR,
200 show_aggr_ogm, store_aggr_ogm);
201 static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
202 static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR,
203 show_orig_interval, store_orig_interval);
205 static struct bat_attribute *mesh_attrs[] = {
206 &bat_attr_aggregate_ogm,
207 &bat_attr_vis_mode,
208 &bat_attr_orig_interval,
209 NULL,
212 static ssize_t transtable_local_read(struct kobject *kobj,
213 struct bin_attribute *bin_attr,
214 char *buff, loff_t off, size_t count)
216 struct device *dev = to_dev(kobj->parent);
217 struct net_device *net_dev = to_net_dev(dev);
219 return hna_local_fill_buffer_text(net_dev, buff, count, off);
222 static ssize_t transtable_global_read(struct kobject *kobj,
223 struct bin_attribute *bin_attr,
224 char *buff, loff_t off, size_t count)
226 struct device *dev = to_dev(kobj->parent);
227 struct net_device *net_dev = to_net_dev(dev);
229 return hna_global_fill_buffer_text(net_dev, buff, count, off);
232 static ssize_t originators_read(struct kobject *kobj,
233 struct bin_attribute *bin_attr,
234 char *buff, loff_t off, size_t count)
236 struct device *dev = to_dev(kobj->parent);
237 struct net_device *net_dev = to_net_dev(dev);
239 return orig_fill_buffer_text(net_dev, buff, count, off);
242 static ssize_t vis_data_read(struct kobject *kobj,
243 struct bin_attribute *bin_attr,
244 char *buff, loff_t off, size_t count)
246 struct device *dev = to_dev(kobj->parent);
247 struct net_device *net_dev = to_net_dev(dev);
249 return vis_fill_buffer_text(net_dev, buff, count, off);
252 static BAT_BIN_ATTR(transtable_local, S_IRUGO, transtable_local_read, NULL);
253 static BAT_BIN_ATTR(transtable_global, S_IRUGO, transtable_global_read, NULL);
254 static BAT_BIN_ATTR(originators, S_IRUGO, originators_read, NULL);
255 static BAT_BIN_ATTR(vis_data, S_IRUGO, vis_data_read, NULL);
257 static struct bin_attribute *mesh_bin_attrs[] = {
258 &bat_attr_transtable_local,
259 &bat_attr_transtable_global,
260 &bat_attr_originators,
261 &bat_attr_vis_data,
262 NULL,
265 int sysfs_add_meshif(struct net_device *dev)
267 struct kobject *batif_kobject = &dev->dev.kobj;
268 struct bat_priv *bat_priv = netdev_priv(dev);
269 struct bat_attribute **bat_attr;
270 struct bin_attribute **bin_attr;
271 int err;
273 /* FIXME: should be done in the general mesh setup
274 routine as soon as we have it */
275 atomic_set(&bat_priv->aggregation_enabled, 1);
276 atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
277 atomic_set(&bat_priv->orig_interval, 1000);
279 bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR,
280 batif_kobject);
281 if (!bat_priv->mesh_obj) {
282 printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n",
283 dev->name, SYSFS_IF_MESH_SUBDIR);
284 goto out;
287 for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) {
288 err = sysfs_create_file(bat_priv->mesh_obj,
289 &((*bat_attr)->attr));
290 if (err) {
291 printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
292 dev->name, SYSFS_IF_MESH_SUBDIR,
293 ((*bat_attr)->attr).name);
294 goto rem_attr;
298 for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) {
299 err = sysfs_create_bin_file(bat_priv->mesh_obj, (*bin_attr));
300 if (err) {
301 printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
302 dev->name, SYSFS_IF_MESH_SUBDIR,
303 ((*bin_attr)->attr).name);
304 goto rem_bin_attr;
308 return 0;
310 rem_bin_attr:
311 for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr)
312 sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr));
313 rem_attr:
314 for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
315 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
317 kobject_put(bat_priv->mesh_obj);
318 bat_priv->mesh_obj = NULL;
319 out:
320 return -ENOMEM;
323 void sysfs_del_meshif(struct net_device *dev)
325 struct bat_priv *bat_priv = netdev_priv(dev);
326 struct bat_attribute **bat_attr;
327 struct bin_attribute **bin_attr;
329 for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr)
330 sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr));
332 for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
333 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
335 kobject_put(bat_priv->mesh_obj);
336 bat_priv->mesh_obj = NULL;