123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- #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)->ml_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, "%d\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)->ml_priv;
- struct cmd_ds_mesh_config cmd;
- uint32_t datum;
- int ret;
- memset(&cmd, 0, sizeof(cmd));
- ret = sscanf(buf, "%d", &datum);
- if ((ret != 1) || (datum > 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, "%d\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)->ml_priv;
- struct cmd_ds_mesh_config cmd;
- uint32_t datum;
- int ret;
- memset(&cmd, 0, sizeof(cmd));
- ret = sscanf(buf, "%d", &datum);
- if ((ret != 1) || (datum > 255))
- 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 channel
- */
- static ssize_t channel_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, "%d\n", le16_to_cpu(defs.channel));
- }
- /**
- * @brief Set function for sysfs attribute channel
- */
- static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
- {
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_config cmd;
- uint32_t datum;
- int ret;
- memset(&cmd, 0, sizeof(cmd));
- ret = sscanf(buf, "%d", &datum);
- if (ret != 1 || datum < 1 || datum > 11)
- return -EINVAL;
- *((__le16 *)&cmd.data[0]) = cpu_to_le16(datum);
- cmd.length = cpu_to_le16(sizeof(uint16_t));
- ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
- CMD_TYPE_MESH_SET_DEF_CHANNEL);
- 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) {
- lbs_pr_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)->ml_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->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)->ml_priv;
- uint32_t datum;
- int ret;
- memset(&cmd, 0, sizeof(cmd));
- ret = sscanf(buf, "%d", &datum);
- if ((ret != 1) || (datum > 255))
- 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)->ml_priv;
- uint32_t datum;
- int ret;
- memset(&cmd, 0, sizeof(cmd));
- ret = sscanf(buf, "%d", &datum);
- if ((ret != 1) || (datum > 255))
- 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)->ml_priv;
- uint32_t datum;
- int ret;
- memset(&cmd, 0, sizeof(cmd));
- ret = sscanf(buf, "%d", &datum);
- if ((ret != 1) || (datum > 255))
- 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(channel, 0644, channel_get, channel_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,
- &dev_attr_channel.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);
- }
|