persistcfg.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. #include <linux/moduleparam.h>
  2. #include <linux/delay.h>
  3. #include <linux/etherdevice.h>
  4. #include <linux/netdevice.h>
  5. #include <linux/if_arp.h>
  6. #include <linux/kthread.h>
  7. #include <linux/kfifo.h>
  8. #include "host.h"
  9. #include "decl.h"
  10. #include "dev.h"
  11. #include "wext.h"
  12. #include "debugfs.h"
  13. #include "scan.h"
  14. #include "assoc.h"
  15. #include "cmd.h"
  16. static int mesh_get_default_parameters(struct device *dev,
  17. struct mrvl_mesh_defaults *defs)
  18. {
  19. struct lbs_private *priv = to_net_dev(dev)->priv;
  20. struct cmd_ds_mesh_config cmd;
  21. int ret;
  22. memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
  23. ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_GET,
  24. CMD_TYPE_MESH_GET_DEFAULTS);
  25. if (ret)
  26. return -EOPNOTSUPP;
  27. memcpy(defs, &cmd.data[0], sizeof(struct mrvl_mesh_defaults));
  28. return 0;
  29. }
  30. /**
  31. * @brief Get function for sysfs attribute bootflag
  32. */
  33. static ssize_t bootflag_get(struct device *dev,
  34. struct device_attribute *attr, char *buf)
  35. {
  36. struct mrvl_mesh_defaults defs;
  37. int ret;
  38. ret = mesh_get_default_parameters(dev, &defs);
  39. if (ret)
  40. return ret;
  41. return snprintf(buf, 12, "0x%x\n", le32_to_cpu(defs.bootflag));
  42. }
  43. /**
  44. * @brief Set function for sysfs attribute bootflag
  45. */
  46. static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
  47. const char *buf, size_t count)
  48. {
  49. struct lbs_private *priv = to_net_dev(dev)->priv;
  50. struct cmd_ds_mesh_config cmd;
  51. uint32_t datum;
  52. int ret;
  53. memset(&cmd, 0, sizeof(cmd));
  54. ret = sscanf(buf, "%x", &datum);
  55. if (ret != 1)
  56. return -EINVAL;
  57. *((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum);
  58. cmd.length = cpu_to_le16(sizeof(uint32_t));
  59. ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
  60. CMD_TYPE_MESH_SET_BOOTFLAG);
  61. if (ret)
  62. return ret;
  63. return strlen(buf);
  64. }
  65. /**
  66. * @brief Get function for sysfs attribute boottime
  67. */
  68. static ssize_t boottime_get(struct device *dev,
  69. struct device_attribute *attr, char *buf)
  70. {
  71. struct mrvl_mesh_defaults defs;
  72. int ret;
  73. ret = mesh_get_default_parameters(dev, &defs);
  74. if (ret)
  75. return ret;
  76. return snprintf(buf, 12, "0x%x\n", defs.boottime);
  77. }
  78. /**
  79. * @brief Set function for sysfs attribute boottime
  80. */
  81. static ssize_t boottime_set(struct device *dev,
  82. struct device_attribute *attr, const char *buf, size_t count)
  83. {
  84. struct lbs_private *priv = to_net_dev(dev)->priv;
  85. struct cmd_ds_mesh_config cmd;
  86. uint32_t datum;
  87. int ret;
  88. memset(&cmd, 0, sizeof(cmd));
  89. ret = sscanf(buf, "%x", &datum);
  90. if (ret != 1)
  91. return -EINVAL;
  92. /* A too small boot time will result in the device booting into
  93. * standalone (no-host) mode before the host can take control of it,
  94. * so the change will be hard to revert. This may be a desired
  95. * feature (e.g to configure a very fast boot time for devices that
  96. * will not be attached to a host), but dangerous. So I'm enforcing a
  97. * lower limit of 20 seconds: remove and recompile the driver if this
  98. * does not work for you.
  99. */
  100. datum = (datum < 20) ? 20 : datum;
  101. cmd.data[0] = datum;
  102. cmd.length = cpu_to_le16(sizeof(uint8_t));
  103. ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
  104. CMD_TYPE_MESH_SET_BOOTTIME);
  105. if (ret)
  106. return ret;
  107. return strlen(buf);
  108. }
  109. /**
  110. * @brief Get function for sysfs attribute mesh_id
  111. */
  112. static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
  113. char *buf)
  114. {
  115. struct mrvl_mesh_defaults defs;
  116. int maxlen;
  117. int ret;
  118. ret = mesh_get_default_parameters(dev, &defs);
  119. if (ret)
  120. return ret;
  121. if (defs.meshie.val.mesh_id_len > IW_ESSID_MAX_SIZE) {
  122. printk(KERN_ERR "Inconsistent mesh ID length");
  123. defs.meshie.val.mesh_id_len = IW_ESSID_MAX_SIZE;
  124. }
  125. /* SSID not null terminated: reserve room for \0 + \n */
  126. maxlen = defs.meshie.val.mesh_id_len + 2;
  127. maxlen = (PAGE_SIZE > maxlen) ? maxlen : PAGE_SIZE;
  128. defs.meshie.val.mesh_id[defs.meshie.val.mesh_id_len] = '\0';
  129. return snprintf(buf, maxlen, "%s\n", defs.meshie.val.mesh_id);
  130. }
  131. /**
  132. * @brief Set function for sysfs attribute mesh_id
  133. */
  134. static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
  135. const char *buf, size_t count)
  136. {
  137. struct cmd_ds_mesh_config cmd;
  138. struct mrvl_mesh_defaults defs;
  139. struct mrvl_meshie *ie;
  140. struct lbs_private *priv = to_net_dev(dev)->priv;
  141. int len;
  142. int ret;
  143. if (count < 2 || count > IW_ESSID_MAX_SIZE + 1)
  144. return -EINVAL;
  145. memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
  146. ie = (struct mrvl_meshie *) &cmd.data[0];
  147. /* fetch all other Information Element parameters */
  148. ret = mesh_get_default_parameters(dev, &defs);
  149. cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
  150. /* transfer IE elements */
  151. memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
  152. len = count - 1;
  153. memcpy(ie->val.mesh_id, buf, len);
  154. /* SSID len */
  155. ie->val.mesh_id_len = len;
  156. /* IE len */
  157. ie->hdr.len = sizeof(struct mrvl_meshie_val) - IW_ESSID_MAX_SIZE + len;
  158. ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
  159. CMD_TYPE_MESH_SET_MESH_IE);
  160. if (ret)
  161. return ret;
  162. return strlen(buf);
  163. }
  164. /**
  165. * @brief Get function for sysfs attribute protocol_id
  166. */
  167. static ssize_t protocol_id_get(struct device *dev,
  168. struct device_attribute *attr, char *buf)
  169. {
  170. struct mrvl_mesh_defaults defs;
  171. int ret;
  172. ret = mesh_get_default_parameters(dev, &defs);
  173. if (ret)
  174. return ret;
  175. return snprintf(buf, 5, "%d\n", defs.meshie.val.active_protocol_id);
  176. }
  177. /**
  178. * @brief Set function for sysfs attribute protocol_id
  179. */
  180. static ssize_t protocol_id_set(struct device *dev,
  181. struct device_attribute *attr, const char *buf, size_t count)
  182. {
  183. struct cmd_ds_mesh_config cmd;
  184. struct mrvl_mesh_defaults defs;
  185. struct mrvl_meshie *ie;
  186. struct lbs_private *priv = to_net_dev(dev)->priv;
  187. uint32_t datum;
  188. int ret;
  189. memset(&cmd, 0, sizeof(cmd));
  190. ret = sscanf(buf, "%x", &datum);
  191. if (ret != 1)
  192. return -EINVAL;
  193. /* fetch all other Information Element parameters */
  194. ret = mesh_get_default_parameters(dev, &defs);
  195. cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
  196. /* transfer IE elements */
  197. ie = (struct mrvl_meshie *) &cmd.data[0];
  198. memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
  199. /* update protocol id */
  200. ie->val.active_protocol_id = datum;
  201. ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
  202. CMD_TYPE_MESH_SET_MESH_IE);
  203. if (ret)
  204. return ret;
  205. return strlen(buf);
  206. }
  207. /**
  208. * @brief Get function for sysfs attribute metric_id
  209. */
  210. static ssize_t metric_id_get(struct device *dev,
  211. struct device_attribute *attr, char *buf)
  212. {
  213. struct mrvl_mesh_defaults defs;
  214. int ret;
  215. ret = mesh_get_default_parameters(dev, &defs);
  216. if (ret)
  217. return ret;
  218. return snprintf(buf, 5, "%d\n", defs.meshie.val.active_metric_id);
  219. }
  220. /**
  221. * @brief Set function for sysfs attribute metric_id
  222. */
  223. static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
  224. const char *buf, size_t count)
  225. {
  226. struct cmd_ds_mesh_config cmd;
  227. struct mrvl_mesh_defaults defs;
  228. struct mrvl_meshie *ie;
  229. struct lbs_private *priv = to_net_dev(dev)->priv;
  230. uint32_t datum;
  231. int ret;
  232. memset(&cmd, 0, sizeof(cmd));
  233. ret = sscanf(buf, "%x", &datum);
  234. if (ret != 1)
  235. return -EINVAL;
  236. /* fetch all other Information Element parameters */
  237. ret = mesh_get_default_parameters(dev, &defs);
  238. cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
  239. /* transfer IE elements */
  240. ie = (struct mrvl_meshie *) &cmd.data[0];
  241. memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
  242. /* update metric id */
  243. ie->val.active_metric_id = datum;
  244. ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
  245. CMD_TYPE_MESH_SET_MESH_IE);
  246. if (ret)
  247. return ret;
  248. return strlen(buf);
  249. }
  250. /**
  251. * @brief Get function for sysfs attribute capability
  252. */
  253. static ssize_t capability_get(struct device *dev,
  254. struct device_attribute *attr, char *buf)
  255. {
  256. struct mrvl_mesh_defaults defs;
  257. int ret;
  258. ret = mesh_get_default_parameters(dev, &defs);
  259. if (ret)
  260. return ret;
  261. return snprintf(buf, 5, "%d\n", defs.meshie.val.mesh_capability);
  262. }
  263. /**
  264. * @brief Set function for sysfs attribute capability
  265. */
  266. static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
  267. const char *buf, size_t count)
  268. {
  269. struct cmd_ds_mesh_config cmd;
  270. struct mrvl_mesh_defaults defs;
  271. struct mrvl_meshie *ie;
  272. struct lbs_private *priv = to_net_dev(dev)->priv;
  273. uint32_t datum;
  274. int ret;
  275. memset(&cmd, 0, sizeof(cmd));
  276. ret = sscanf(buf, "%x", &datum);
  277. if (ret != 1)
  278. return -EINVAL;
  279. /* fetch all other Information Element parameters */
  280. ret = mesh_get_default_parameters(dev, &defs);
  281. cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
  282. /* transfer IE elements */
  283. ie = (struct mrvl_meshie *) &cmd.data[0];
  284. memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
  285. /* update value */
  286. ie->val.mesh_capability = datum;
  287. ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
  288. CMD_TYPE_MESH_SET_MESH_IE);
  289. if (ret)
  290. return ret;
  291. return strlen(buf);
  292. }
  293. static DEVICE_ATTR(bootflag, 0644, bootflag_get, bootflag_set);
  294. static DEVICE_ATTR(boottime, 0644, boottime_get, boottime_set);
  295. static DEVICE_ATTR(mesh_id, 0644, mesh_id_get, mesh_id_set);
  296. static DEVICE_ATTR(protocol_id, 0644, protocol_id_get, protocol_id_set);
  297. static DEVICE_ATTR(metric_id, 0644, metric_id_get, metric_id_set);
  298. static DEVICE_ATTR(capability, 0644, capability_get, capability_set);
  299. static struct attribute *boot_opts_attrs[] = {
  300. &dev_attr_bootflag.attr,
  301. &dev_attr_boottime.attr,
  302. NULL
  303. };
  304. static struct attribute_group boot_opts_group = {
  305. .name = "boot_options",
  306. .attrs = boot_opts_attrs,
  307. };
  308. static struct attribute *mesh_ie_attrs[] = {
  309. &dev_attr_mesh_id.attr,
  310. &dev_attr_protocol_id.attr,
  311. &dev_attr_metric_id.attr,
  312. &dev_attr_capability.attr,
  313. NULL
  314. };
  315. static struct attribute_group mesh_ie_group = {
  316. .name = "mesh_ie",
  317. .attrs = mesh_ie_attrs,
  318. };
  319. void lbs_persist_config_init(struct net_device *dev)
  320. {
  321. int ret;
  322. ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group);
  323. ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group);
  324. }
  325. void lbs_persist_config_remove(struct net_device *dev)
  326. {
  327. sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group);
  328. sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group);
  329. }