summaryrefslogtreecommitdiffstats
path: root/net/batman-adv/sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/sysfs.c')
-rw-r--r--net/batman-adv/sysfs.c142
1 files changed, 136 insertions, 6 deletions
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index ab4382ba3855..e7cf51333a36 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -216,7 +216,7 @@ ssize_t batadv_store_vlan_##_name(struct kobject *kobj, \
attr, &vlan->_name, \
bat_priv->soft_iface); \
\
- batadv_softif_vlan_free_ref(vlan); \
+ batadv_softif_vlan_put(vlan); \
return res; \
}
@@ -231,7 +231,7 @@ ssize_t batadv_show_vlan_##_name(struct kobject *kobj, \
atomic_read(&vlan->_name) == 0 ? \
"disabled" : "enabled"); \
\
- batadv_softif_vlan_free_ref(vlan); \
+ batadv_softif_vlan_put(vlan); \
return res; \
}
@@ -242,6 +242,55 @@ ssize_t batadv_show_vlan_##_name(struct kobject *kobj, \
static BATADV_ATTR_VLAN(_name, _mode, batadv_show_vlan_##_name, \
batadv_store_vlan_##_name)
+#define BATADV_ATTR_HIF_STORE_UINT(_name, _var, _min, _max, _post_func) \
+ssize_t batadv_store_##_name(struct kobject *kobj, \
+ struct attribute *attr, char *buff, \
+ size_t count) \
+{ \
+ struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
+ struct batadv_hard_iface *hard_iface; \
+ ssize_t length; \
+ \
+ hard_iface = batadv_hardif_get_by_netdev(net_dev); \
+ if (!hard_iface) \
+ return 0; \
+ \
+ length = __batadv_store_uint_attr(buff, count, _min, _max, \
+ _post_func, attr, \
+ &hard_iface->_var, net_dev); \
+ \
+ batadv_hardif_put(hard_iface); \
+ return length; \
+}
+
+#define BATADV_ATTR_HIF_SHOW_UINT(_name, _var) \
+ssize_t batadv_show_##_name(struct kobject *kobj, \
+ struct attribute *attr, char *buff) \
+{ \
+ struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
+ struct batadv_hard_iface *hard_iface; \
+ ssize_t length; \
+ \
+ hard_iface = batadv_hardif_get_by_netdev(net_dev); \
+ if (!hard_iface) \
+ return 0; \
+ \
+ length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_var)); \
+ \
+ batadv_hardif_put(hard_iface); \
+ return length; \
+}
+
+/* Use this, if you are going to set [name] in hard_iface to an
+ * unsigned integer value
+ */
+#define BATADV_ATTR_HIF_UINT(_name, _var, _mode, _min, _max, _post_func)\
+ static BATADV_ATTR_HIF_STORE_UINT(_name, _var, _min, \
+ _max, _post_func) \
+ static BATADV_ATTR_HIF_SHOW_UINT(_name, _var) \
+ static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
+ batadv_store_##_name)
+
static int batadv_store_bool_attr(char *buff, size_t count,
struct net_device *net_dev,
const char *attr_name, atomic_t *attr,
@@ -771,7 +820,7 @@ static ssize_t batadv_show_mesh_iface(struct kobject *kobj,
length = sprintf(buff, "%s\n", ifname);
- batadv_hardif_free_ref(hard_iface);
+ batadv_hardif_put(hard_iface);
return length;
}
@@ -795,7 +844,7 @@ static ssize_t batadv_store_mesh_iface(struct kobject *kobj,
if (strlen(buff) >= IFNAMSIZ) {
pr_err("Invalid parameter for 'mesh_iface' setting received: interface name too long '%s'\n",
buff);
- batadv_hardif_free_ref(hard_iface);
+ batadv_hardif_put(hard_iface);
return -EINVAL;
}
@@ -829,7 +878,7 @@ static ssize_t batadv_store_mesh_iface(struct kobject *kobj,
unlock:
rtnl_unlock();
out:
- batadv_hardif_free_ref(hard_iface);
+ batadv_hardif_put(hard_iface);
return ret;
}
@@ -863,18 +912,99 @@ static ssize_t batadv_show_iface_status(struct kobject *kobj,
break;
}
- batadv_hardif_free_ref(hard_iface);
+ batadv_hardif_put(hard_iface);
return length;
}
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+
+/**
+ * batadv_store_throughput_override - parse and store throughput override
+ * entered by the user
+ * @kobj: kobject representing the private mesh sysfs directory
+ * @attr: the batman-adv attribute the user is interacting with
+ * @buff: the buffer containing the user data
+ * @count: number of bytes in the buffer
+ *
+ * Return: 'count' on success or a negative error code in case of failure
+ */
+static ssize_t batadv_store_throughput_override(struct kobject *kobj,
+ struct attribute *attr,
+ char *buff, size_t count)
+{
+ struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
+ struct batadv_hard_iface *hard_iface;
+ u32 tp_override;
+ u32 old_tp_override;
+ bool ret;
+
+ hard_iface = batadv_hardif_get_by_netdev(net_dev);
+ if (!hard_iface)
+ return -EINVAL;
+
+ if (buff[count - 1] == '\n')
+ buff[count - 1] = '\0';
+
+ ret = batadv_parse_throughput(net_dev, buff, "throughput_override",
+ &tp_override);
+ if (!ret)
+ return count;
+
+ old_tp_override = atomic_read(&hard_iface->bat_v.throughput_override);
+ if (old_tp_override == tp_override)
+ goto out;
+
+ batadv_info(net_dev, "%s: Changing from: %u.%u MBit to: %u.%u MBit\n",
+ "throughput_override",
+ old_tp_override / 10, old_tp_override % 10,
+ tp_override / 10, tp_override % 10);
+
+ atomic_set(&hard_iface->bat_v.throughput_override, tp_override);
+
+out:
+ batadv_hardif_put(hard_iface);
+ return count;
+}
+
+static ssize_t batadv_show_throughput_override(struct kobject *kobj,
+ struct attribute *attr,
+ char *buff)
+{
+ struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
+ struct batadv_hard_iface *hard_iface;
+ u32 tp_override;
+
+ hard_iface = batadv_hardif_get_by_netdev(net_dev);
+ if (!hard_iface)
+ return -EINVAL;
+
+ tp_override = atomic_read(&hard_iface->bat_v.throughput_override);
+
+ return sprintf(buff, "%u.%u MBit\n", tp_override / 10,
+ tp_override % 10);
+}
+
+#endif
+
static BATADV_ATTR(mesh_iface, S_IRUGO | S_IWUSR, batadv_show_mesh_iface,
batadv_store_mesh_iface);
static BATADV_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL);
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+BATADV_ATTR_HIF_UINT(elp_interval, bat_v.elp_interval, S_IRUGO | S_IWUSR,
+ 2 * BATADV_JITTER, INT_MAX, NULL);
+static BATADV_ATTR(throughput_override, S_IRUGO | S_IWUSR,
+ batadv_show_throughput_override,
+ batadv_store_throughput_override);
+#endif
static struct batadv_attribute *batadv_batman_attrs[] = {
&batadv_attr_mesh_iface,
&batadv_attr_iface_status,
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+ &batadv_attr_elp_interval,
+ &batadv_attr_throughput_override,
+#endif
NULL,
};