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 BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR,
157 show_aggr_ogm, store_aggr_ogm);
158 static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
160 static struct bat_attribute *mesh_attrs[] = {
161 &bat_attr_aggregate_ogm,
166 static ssize_t transtable_local_read(struct kobject *kobj,
167 struct bin_attribute *bin_attr,
168 char *buff, loff_t off, size_t count)
170 struct device *dev = to_dev(kobj->parent);
171 struct net_device *net_dev = to_net_dev(dev);
173 return hna_local_fill_buffer_text(net_dev, buff, count, off);
176 static ssize_t transtable_global_read(struct kobject *kobj,
177 struct bin_attribute *bin_attr,
178 char *buff, loff_t off, size_t count)
180 struct device *dev = to_dev(kobj->parent);
181 struct net_device *net_dev = to_net_dev(dev);
183 return hna_global_fill_buffer_text(net_dev, buff, count, off);
186 static ssize_t originators_read(struct kobject *kobj,
187 struct bin_attribute *bin_attr,
188 char *buff, loff_t off, size_t count)
190 struct device *dev = to_dev(kobj->parent);
191 struct net_device *net_dev = to_net_dev(dev);
193 return orig_fill_buffer_text(net_dev, buff, count, off);
196 static ssize_t vis_data_read(struct kobject *kobj,
197 struct bin_attribute *bin_attr,
198 char *buff, loff_t off, size_t count)
200 struct device *dev = to_dev(kobj->parent);
201 struct net_device *net_dev = to_net_dev(dev);
203 return vis_fill_buffer_text(net_dev, buff, count, off);
206 static BAT_BIN_ATTR(transtable_local, S_IRUGO, transtable_local_read, NULL);
207 static BAT_BIN_ATTR(transtable_global, S_IRUGO, transtable_global_read, NULL);
208 static BAT_BIN_ATTR(originators, S_IRUGO, originators_read, NULL);
209 static BAT_BIN_ATTR(vis_data, S_IRUGO, vis_data_read, NULL);
211 static struct bin_attribute *mesh_bin_attrs[] = {
212 &bat_attr_transtable_local,
213 &bat_attr_transtable_global,
214 &bat_attr_originators,
219 int sysfs_add_meshif(struct net_device *dev)
221 struct kobject *batif_kobject = &dev->dev.kobj;
222 struct bat_priv *bat_priv = netdev_priv(dev);
223 struct bat_attribute **bat_attr;
224 struct bin_attribute **bin_attr;
227 /* FIXME: should be done in the general mesh setup
228 routine as soon as we have it */
229 atomic_set(&bat_priv->aggregation_enabled, 1);
230 atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
232 bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR,
234 if (!bat_priv->mesh_obj) {
235 printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n",
236 dev->name, SYSFS_IF_MESH_SUBDIR);
240 for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) {
241 err = sysfs_create_file(bat_priv->mesh_obj,
242 &((*bat_attr)->attr));
244 printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
245 dev->name, SYSFS_IF_MESH_SUBDIR,
246 ((*bat_attr)->attr).name);
251 for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) {
252 err = sysfs_create_bin_file(bat_priv->mesh_obj, (*bin_attr));
254 printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
255 dev->name, SYSFS_IF_MESH_SUBDIR,
256 ((*bin_attr)->attr).name);
264 for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr)
265 sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr));
267 for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
268 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
270 kobject_put(bat_priv->mesh_obj);
271 bat_priv->mesh_obj = NULL;
276 void sysfs_del_meshif(struct net_device *dev)
278 struct bat_priv *bat_priv = netdev_priv(dev);
279 struct bat_attribute **bat_attr;
280 struct bin_attribute **bin_attr;
282 for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr)
283 sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr));
285 for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
286 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
288 kobject_put(bat_priv->mesh_obj);
289 bat_priv->mesh_obj = NULL;