--- /dev/null
+#include <linux/moduleparam.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/kthread.h>
+#include <linux/kfifo.h>
+
+#include "host.h"
+#include "decl.h"
+#include "dev.h"
+#include "wext.h"
+#include "debugfs.h"
+#include "scan.h"
+#include "assoc.h"
+#include "cmd.h"
+
+static int mesh_get_default_parameters(struct device *dev,
+                                      struct mrvl_mesh_defaults *defs)
+{
+       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct cmd_ds_mesh_config cmd;
+       int ret;
+
+       memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
+       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_GET,
+                                  CMD_TYPE_MESH_GET_DEFAULTS);
+
+       if (ret)
+               return -EOPNOTSUPP;
+
+       memcpy(defs, &cmd.data[0], sizeof(struct mrvl_mesh_defaults));
+
+       return 0;
+}
+
+/**
+ * @brief Get function for sysfs attribute bootflag
+ */
+static ssize_t bootflag_get(struct device *dev,
+                           struct device_attribute *attr, char *buf)
+{
+       struct mrvl_mesh_defaults defs;
+       int ret;
+
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       if (ret)
+               return ret;
+
+       return snprintf(buf, 12, "0x%x\n", le32_to_cpu(defs.bootflag));
+}
+
+/**
+ * @brief Set function for sysfs attribute bootflag
+ */
+static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
+                           const char *buf, size_t count)
+{
+       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct cmd_ds_mesh_config cmd;
+       uint32_t datum;
+       int ret;
+
+       memset(&cmd, 0, sizeof(cmd));
+       ret = sscanf(buf, "%x", &datum);
+       if (ret != 1)
+               return -EINVAL;
+
+       *((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum);
+       cmd.length = cpu_to_le16(sizeof(uint32_t));
+       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+                                  CMD_TYPE_MESH_SET_BOOTFLAG);
+       if (ret)
+               return ret;
+
+       return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute boottime
+ */
+static ssize_t boottime_get(struct device *dev,
+                           struct device_attribute *attr, char *buf)
+{
+       struct mrvl_mesh_defaults defs;
+       int ret;
+
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       if (ret)
+               return ret;
+
+       return snprintf(buf, 12, "0x%x\n", defs.boottime);
+}
+
+/**
+ * @brief Set function for sysfs attribute boottime
+ */
+static ssize_t boottime_set(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct cmd_ds_mesh_config cmd;
+       uint32_t datum;
+       int ret;
+
+       memset(&cmd, 0, sizeof(cmd));
+       ret = sscanf(buf, "%x", &datum);
+       if (ret != 1)
+               return -EINVAL;
+
+       /* A too small boot time will result in the device booting into
+        * standalone (no-host) mode before the host can take control of it,
+        * so the change will be hard to revert.  This may be a desired
+        * feature (e.g to configure a very fast boot time for devices that
+        * will not be attached to a host), but dangerous.  So I'm enforcing a
+        * lower limit of 20 seconds:  remove and recompile the driver if this
+        * does not work for you.
+        */
+       datum = (datum < 20) ? 20 : datum;
+       cmd.data[0] = datum;
+       cmd.length = cpu_to_le16(sizeof(uint8_t));
+       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+                                  CMD_TYPE_MESH_SET_BOOTTIME);
+       if (ret)
+               return ret;
+
+       return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute mesh_id
+ */
+static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
+                          char *buf)
+{
+       struct mrvl_mesh_defaults defs;
+       int maxlen;
+       int ret;
+
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       if (ret)
+               return ret;
+
+       if (defs.meshie.val.mesh_id_len > IW_ESSID_MAX_SIZE) {
+               printk(KERN_ERR "Inconsistent mesh ID length");
+               defs.meshie.val.mesh_id_len = IW_ESSID_MAX_SIZE;
+       }
+
+       /* SSID not null terminated: reserve room for \0 + \n */
+       maxlen = defs.meshie.val.mesh_id_len + 2;
+       maxlen = (PAGE_SIZE > maxlen) ? maxlen : PAGE_SIZE;
+
+       defs.meshie.val.mesh_id[defs.meshie.val.mesh_id_len] = '\0';
+
+       return snprintf(buf, maxlen, "%s\n", defs.meshie.val.mesh_id);
+}
+
+/**
+ * @brief Set function for sysfs attribute mesh_id
+ */
+static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
+{
+       struct cmd_ds_mesh_config cmd;
+       struct mrvl_mesh_defaults defs;
+       struct mrvl_meshie *ie;
+       struct lbs_private *priv = to_net_dev(dev)->priv;
+       int len;
+       int ret;
+
+       if (count < 2 || count > IW_ESSID_MAX_SIZE + 1)
+               return -EINVAL;
+
+       memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
+       ie = (struct mrvl_meshie *) &cmd.data[0];
+
+       /* fetch all other Information Element parameters */
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+       /* transfer IE elements */
+       memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+
+       len = count - 1;
+       memcpy(ie->val.mesh_id, buf, len);
+       /* SSID len */
+       ie->val.mesh_id_len = len;
+       /* IE len */
+       ie->hdr.len = sizeof(struct mrvl_meshie_val) - IW_ESSID_MAX_SIZE + len;
+
+       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+                                  CMD_TYPE_MESH_SET_MESH_IE);
+       if (ret)
+               return ret;
+
+       return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute protocol_id
+ */
+static ssize_t protocol_id_get(struct device *dev,
+                              struct device_attribute *attr, char *buf)
+{
+       struct mrvl_mesh_defaults defs;
+       int ret;
+
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       if (ret)
+               return ret;
+
+       return snprintf(buf, 5, "%d\n", defs.meshie.val.active_protocol_id);
+}
+
+/**
+ * @brief Set function for sysfs attribute protocol_id
+ */
+static ssize_t protocol_id_set(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct cmd_ds_mesh_config cmd;
+       struct mrvl_mesh_defaults defs;
+       struct mrvl_meshie *ie;
+       struct lbs_private *priv = to_net_dev(dev)->priv;
+       uint32_t datum;
+       int ret;
+
+       memset(&cmd, 0, sizeof(cmd));
+       ret = sscanf(buf, "%x", &datum);
+       if (ret != 1)
+               return -EINVAL;
+
+       /* fetch all other Information Element parameters */
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+       /* transfer IE elements */
+       ie = (struct mrvl_meshie *) &cmd.data[0];
+       memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+       /* update protocol id */
+       ie->val.active_protocol_id = datum;
+
+       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+                                  CMD_TYPE_MESH_SET_MESH_IE);
+       if (ret)
+               return ret;
+
+       return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute metric_id
+ */
+static ssize_t metric_id_get(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct mrvl_mesh_defaults defs;
+       int ret;
+
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       if (ret)
+               return ret;
+
+       return snprintf(buf, 5, "%d\n", defs.meshie.val.active_metric_id);
+}
+
+/**
+ * @brief Set function for sysfs attribute metric_id
+ */
+static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
+                            const char *buf, size_t count)
+{
+       struct cmd_ds_mesh_config cmd;
+       struct mrvl_mesh_defaults defs;
+       struct mrvl_meshie *ie;
+       struct lbs_private *priv = to_net_dev(dev)->priv;
+       uint32_t datum;
+       int ret;
+
+       memset(&cmd, 0, sizeof(cmd));
+       ret = sscanf(buf, "%x", &datum);
+       if (ret != 1)
+               return -EINVAL;
+
+       /* fetch all other Information Element parameters */
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+       /* transfer IE elements */
+       ie = (struct mrvl_meshie *) &cmd.data[0];
+       memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+       /* update metric id */
+       ie->val.active_metric_id = datum;
+
+       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+                                  CMD_TYPE_MESH_SET_MESH_IE);
+       if (ret)
+               return ret;
+
+       return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute capability
+ */
+static ssize_t capability_get(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct mrvl_mesh_defaults defs;
+       int ret;
+
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       if (ret)
+               return ret;
+
+       return snprintf(buf, 5, "%d\n", defs.meshie.val.mesh_capability);
+}
+
+/**
+ * @brief Set function for sysfs attribute capability
+ */
+static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
+                             const char *buf, size_t count)
+{
+       struct cmd_ds_mesh_config cmd;
+       struct mrvl_mesh_defaults defs;
+       struct mrvl_meshie *ie;
+       struct lbs_private *priv = to_net_dev(dev)->priv;
+       uint32_t datum;
+       int ret;
+
+       memset(&cmd, 0, sizeof(cmd));
+       ret = sscanf(buf, "%x", &datum);
+       if (ret != 1)
+               return -EINVAL;
+
+       /* fetch all other Information Element parameters */
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+       /* transfer IE elements */
+       ie = (struct mrvl_meshie *) &cmd.data[0];
+       memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+       /* update value */
+       ie->val.mesh_capability = datum;
+
+       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+                                  CMD_TYPE_MESH_SET_MESH_IE);
+       if (ret)
+               return ret;
+
+       return strlen(buf);
+}
+
+
+static DEVICE_ATTR(bootflag, 0644, bootflag_get, bootflag_set);
+static DEVICE_ATTR(boottime, 0644, boottime_get, boottime_set);
+static DEVICE_ATTR(mesh_id, 0644, mesh_id_get, mesh_id_set);
+static DEVICE_ATTR(protocol_id, 0644, protocol_id_get, protocol_id_set);
+static DEVICE_ATTR(metric_id, 0644, metric_id_get, metric_id_set);
+static DEVICE_ATTR(capability, 0644, capability_get, capability_set);
+
+static struct attribute *boot_opts_attrs[] = {
+       &dev_attr_bootflag.attr,
+       &dev_attr_boottime.attr,
+       NULL
+};
+
+static struct attribute_group boot_opts_group = {
+       .name = "boot_options",
+       .attrs = boot_opts_attrs,
+};
+
+static struct attribute *mesh_ie_attrs[] = {
+       &dev_attr_mesh_id.attr,
+       &dev_attr_protocol_id.attr,
+       &dev_attr_metric_id.attr,
+       &dev_attr_capability.attr,
+       NULL
+};
+
+static struct attribute_group mesh_ie_group = {
+       .name = "mesh_ie",
+       .attrs = mesh_ie_attrs,
+};
+
+void lbs_persist_config_init(struct net_device *dev)
+{
+       int ret;
+       ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group);
+       ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group);
+}
+
+void lbs_persist_config_remove(struct net_device *dev)
+{
+       sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group);
+       sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group);
+}