2 * Copyright (C) 2010 B.A.T.M.A.N. contributors:
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
23 #include "bat_sysfs.h"
24 #include "translation-table.h"
25 #include "originator.h"
26 #include "hard-interface.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
,
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), \
47 #define BAT_BIN_ATTR(_name, _mode, _read, _write) \
48 struct bin_attribute bat_attr_##_name = { \
49 .attr = { .name = __stringify(_name), \
55 static ssize_t
show_aggr_ogm(struct kobject
*kobj
, struct attribute
*attr
,
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
);
74 if (((count
== 2) && (buff
[0] == '1')) ||
75 (strncmp(buff
, "enable", 6) == 0))
78 if (((count
== 2) && (buff
[0] == '0')) ||
79 (strncmp(buff
, "disable", 7) == 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",
91 if (atomic_read(&bat_priv
->aggregation_enabled
) == aggr_tmp
)
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",
99 atomic_set(&bat_priv
->aggregation_enabled
, (unsigned)aggr_tmp
);
103 static ssize_t
show_vis_mode(struct kobject
*kobj
, struct attribute
*attr
,
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
?
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
);
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
);
144 if (atomic_read(&bat_priv
->vis_mode
) == vis_mode_tmp
)
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
);
156 static ssize_t
show_orig_interval(struct kobject
*kobj
, struct attribute
*attr
,
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
;
175 ret
= strict_strtoul(buff
, 10, &orig_interval_tmp
);
177 printk(KERN_INFO
"batman-adv:Invalid parameter for 'orig_interval' setting on mesh %s received: %s\n",
178 net_dev
->name
, buff
);
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);
188 if (atomic_read(&bat_priv
->orig_interval
) == orig_interval_tmp
)
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
);
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
,
208 &bat_attr_orig_interval
,
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
,
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
;
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
,
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
);
287 for (bat_attr
= mesh_attrs
; *bat_attr
; ++bat_attr
) {
288 err
= sysfs_create_file(bat_priv
->mesh_obj
,
289 &((*bat_attr
)->attr
));
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
);
298 for (bin_attr
= mesh_bin_attrs
; *bin_attr
; ++bin_attr
) {
299 err
= sysfs_create_bin_file(bat_priv
->mesh_obj
, (*bin_attr
));
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
);
311 for (bin_attr
= mesh_bin_attrs
; *bin_attr
; ++bin_attr
)
312 sysfs_remove_bin_file(bat_priv
->mesh_obj
, (*bin_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
;
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
;