address.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. /*
  2. * Ultra Wide Band
  3. * Address management
  4. *
  5. * Copyright (C) 2005-2006 Intel Corporation
  6. * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License version
  10. * 2 as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  20. * 02110-1301, USA.
  21. *
  22. *
  23. * FIXME: docs
  24. */
  25. #include <linux/slab.h>
  26. #include <linux/errno.h>
  27. #include <linux/module.h>
  28. #include <linux/device.h>
  29. #include <linux/random.h>
  30. #include <linux/etherdevice.h>
  31. #include "uwb-internal.h"
  32. /** Device Address Management command */
  33. struct uwb_rc_cmd_dev_addr_mgmt {
  34. struct uwb_rccb rccb;
  35. u8 bmOperationType;
  36. u8 baAddr[6];
  37. } __attribute__((packed));
  38. /**
  39. * Low level command for setting/getting UWB radio's addresses
  40. *
  41. * @hwarc: HWA Radio Control interface instance
  42. * @bmOperationType:
  43. * Set/get, MAC/DEV (see WUSB1.0[8.6.2.2])
  44. * @baAddr: address buffer--assumed to have enough data to hold
  45. * the address type requested.
  46. * @reply: Pointer to reply buffer (can be stack allocated)
  47. * @returns: 0 if ok, < 0 errno code on error.
  48. *
  49. * @cmd has to be allocated because USB cannot grok USB or vmalloc
  50. * buffers depending on your combination of host architecture.
  51. */
  52. static
  53. int uwb_rc_dev_addr_mgmt(struct uwb_rc *rc,
  54. u8 bmOperationType, const u8 *baAddr,
  55. struct uwb_rc_evt_dev_addr_mgmt *reply)
  56. {
  57. int result;
  58. struct uwb_rc_cmd_dev_addr_mgmt *cmd;
  59. result = -ENOMEM;
  60. cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
  61. if (cmd == NULL)
  62. goto error_kzalloc;
  63. cmd->rccb.bCommandType = UWB_RC_CET_GENERAL;
  64. cmd->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_DEV_ADDR_MGMT);
  65. cmd->bmOperationType = bmOperationType;
  66. if (baAddr) {
  67. size_t size = 0;
  68. switch (bmOperationType >> 1) {
  69. case 0: size = 2; break;
  70. case 1: size = 6; break;
  71. default: BUG();
  72. }
  73. memcpy(cmd->baAddr, baAddr, size);
  74. }
  75. reply->rceb.bEventType = UWB_RC_CET_GENERAL;
  76. reply->rceb.wEvent = UWB_RC_CMD_DEV_ADDR_MGMT;
  77. result = uwb_rc_cmd(rc, "DEV-ADDR-MGMT",
  78. &cmd->rccb, sizeof(*cmd),
  79. &reply->rceb, sizeof(*reply));
  80. if (result < 0)
  81. goto error_cmd;
  82. if (result < sizeof(*reply)) {
  83. dev_err(&rc->uwb_dev.dev,
  84. "DEV-ADDR-MGMT: not enough data replied: "
  85. "%d vs %zu bytes needed\n", result, sizeof(*reply));
  86. result = -ENOMSG;
  87. } else if (reply->bResultCode != UWB_RC_RES_SUCCESS) {
  88. dev_err(&rc->uwb_dev.dev,
  89. "DEV-ADDR-MGMT: command execution failed: %s (%d)\n",
  90. uwb_rc_strerror(reply->bResultCode),
  91. reply->bResultCode);
  92. result = -EIO;
  93. } else
  94. result = 0;
  95. error_cmd:
  96. kfree(cmd);
  97. error_kzalloc:
  98. return result;
  99. }
  100. /**
  101. * Set the UWB RC MAC or device address.
  102. *
  103. * @rc: UWB Radio Controller
  104. * @_addr: Pointer to address to write [assumed to be either a
  105. * 'struct uwb_mac_addr *' or a 'struct uwb_dev_addr *'].
  106. * @type: Type of address to set (UWB_ADDR_DEV or UWB_ADDR_MAC).
  107. * @returns: 0 if ok, < 0 errno code on error.
  108. *
  109. * Some anal retentivity here: even if both 'struct
  110. * uwb_{dev,mac}_addr' have the actual byte array in the same offset
  111. * and I could just pass _addr to hwarc_cmd_dev_addr_mgmt(), I prefer
  112. * to use some syntatic sugar in case someday we decide to change the
  113. * format of the structs. The compiler will optimize it out anyway.
  114. */
  115. static int uwb_rc_addr_set(struct uwb_rc *rc,
  116. const void *_addr, enum uwb_addr_type type)
  117. {
  118. int result;
  119. u8 bmOperationType = 0x1; /* Set address */
  120. const struct uwb_dev_addr *dev_addr = _addr;
  121. const struct uwb_mac_addr *mac_addr = _addr;
  122. struct uwb_rc_evt_dev_addr_mgmt reply;
  123. const u8 *baAddr;
  124. result = -EINVAL;
  125. switch (type) {
  126. case UWB_ADDR_DEV:
  127. baAddr = dev_addr->data;
  128. break;
  129. case UWB_ADDR_MAC:
  130. baAddr = mac_addr->data;
  131. bmOperationType |= 0x2;
  132. break;
  133. default:
  134. return result;
  135. }
  136. return uwb_rc_dev_addr_mgmt(rc, bmOperationType, baAddr, &reply);
  137. }
  138. /**
  139. * Get the UWB radio's MAC or device address.
  140. *
  141. * @rc: UWB Radio Controller
  142. * @_addr: Where to write the address data [assumed to be either a
  143. * 'struct uwb_mac_addr *' or a 'struct uwb_dev_addr *'].
  144. * @type: Type of address to get (UWB_ADDR_DEV or UWB_ADDR_MAC).
  145. * @returns: 0 if ok (and *_addr set), < 0 errno code on error.
  146. *
  147. * See comment in uwb_rc_addr_set() about anal retentivity in the
  148. * type handling of the address variables.
  149. */
  150. static int uwb_rc_addr_get(struct uwb_rc *rc,
  151. void *_addr, enum uwb_addr_type type)
  152. {
  153. int result;
  154. u8 bmOperationType = 0x0; /* Get address */
  155. struct uwb_rc_evt_dev_addr_mgmt evt;
  156. struct uwb_dev_addr *dev_addr = _addr;
  157. struct uwb_mac_addr *mac_addr = _addr;
  158. u8 *baAddr;
  159. result = -EINVAL;
  160. switch (type) {
  161. case UWB_ADDR_DEV:
  162. baAddr = dev_addr->data;
  163. break;
  164. case UWB_ADDR_MAC:
  165. bmOperationType |= 0x2;
  166. baAddr = mac_addr->data;
  167. break;
  168. default:
  169. return result;
  170. }
  171. result = uwb_rc_dev_addr_mgmt(rc, bmOperationType, baAddr, &evt);
  172. if (result == 0)
  173. switch (type) {
  174. case UWB_ADDR_DEV:
  175. memcpy(&dev_addr->data, evt.baAddr,
  176. sizeof(dev_addr->data));
  177. break;
  178. case UWB_ADDR_MAC:
  179. memcpy(&mac_addr->data, evt.baAddr,
  180. sizeof(mac_addr->data));
  181. break;
  182. default: /* shut gcc up */
  183. BUG();
  184. }
  185. return result;
  186. }
  187. /** Get @rc's MAC address to @addr */
  188. int uwb_rc_mac_addr_get(struct uwb_rc *rc,
  189. struct uwb_mac_addr *addr) {
  190. return uwb_rc_addr_get(rc, addr, UWB_ADDR_MAC);
  191. }
  192. EXPORT_SYMBOL_GPL(uwb_rc_mac_addr_get);
  193. /** Get @rc's device address to @addr */
  194. int uwb_rc_dev_addr_get(struct uwb_rc *rc,
  195. struct uwb_dev_addr *addr) {
  196. return uwb_rc_addr_get(rc, addr, UWB_ADDR_DEV);
  197. }
  198. EXPORT_SYMBOL_GPL(uwb_rc_dev_addr_get);
  199. /** Set @rc's address to @addr */
  200. int uwb_rc_mac_addr_set(struct uwb_rc *rc,
  201. const struct uwb_mac_addr *addr)
  202. {
  203. int result = -EINVAL;
  204. mutex_lock(&rc->uwb_dev.mutex);
  205. result = uwb_rc_addr_set(rc, addr, UWB_ADDR_MAC);
  206. mutex_unlock(&rc->uwb_dev.mutex);
  207. return result;
  208. }
  209. /** Set @rc's address to @addr */
  210. int uwb_rc_dev_addr_set(struct uwb_rc *rc,
  211. const struct uwb_dev_addr *addr)
  212. {
  213. int result = -EINVAL;
  214. mutex_lock(&rc->uwb_dev.mutex);
  215. result = uwb_rc_addr_set(rc, addr, UWB_ADDR_DEV);
  216. rc->uwb_dev.dev_addr = *addr;
  217. mutex_unlock(&rc->uwb_dev.mutex);
  218. return result;
  219. }
  220. /* Returns !0 if given address is already assigned to device. */
  221. int __uwb_mac_addr_assigned_check(struct device *dev, void *_addr)
  222. {
  223. struct uwb_dev *uwb_dev = to_uwb_dev(dev);
  224. struct uwb_mac_addr *addr = _addr;
  225. if (!uwb_mac_addr_cmp(addr, &uwb_dev->mac_addr))
  226. return !0;
  227. return 0;
  228. }
  229. /* Returns !0 if given address is already assigned to device. */
  230. int __uwb_dev_addr_assigned_check(struct device *dev, void *_addr)
  231. {
  232. struct uwb_dev *uwb_dev = to_uwb_dev(dev);
  233. struct uwb_dev_addr *addr = _addr;
  234. if (!uwb_dev_addr_cmp(addr, &uwb_dev->dev_addr))
  235. return !0;
  236. return 0;
  237. }
  238. /**
  239. * uwb_dev_addr_assign - assigned a generated DevAddr to a radio controller
  240. * @rc: the (local) radio controller device requiring a new DevAddr
  241. *
  242. * A new DevAddr is required when:
  243. * - first setting up a radio controller
  244. * - if the hardware reports a DevAddr conflict
  245. *
  246. * The DevAddr is randomly generated in the generated DevAddr range
  247. * [0x100, 0xfeff]. The number of devices in a beacon group is limited
  248. * by mMaxBPLength (96) so this address space will never be exhausted.
  249. *
  250. * [ECMA-368] 17.1.1, 17.16.
  251. */
  252. int uwb_rc_dev_addr_assign(struct uwb_rc *rc)
  253. {
  254. struct uwb_dev_addr new_addr;
  255. do {
  256. get_random_bytes(new_addr.data, sizeof(new_addr.data));
  257. } while (new_addr.data[0] == 0x00 || new_addr.data[0] == 0xff
  258. || __uwb_dev_addr_assigned(rc, &new_addr));
  259. return uwb_rc_dev_addr_set(rc, &new_addr);
  260. }
  261. /**
  262. * uwbd_evt_handle_rc_dev_addr_conflict - handle a DEV_ADDR_CONFLICT event
  263. * @evt: the DEV_ADDR_CONFLICT notification from the radio controller
  264. *
  265. * A new (non-conflicting) DevAddr is assigned to the radio controller.
  266. *
  267. * [ECMA-368] 17.1.1.1.
  268. */
  269. int uwbd_evt_handle_rc_dev_addr_conflict(struct uwb_event *evt)
  270. {
  271. struct uwb_rc *rc = evt->rc;
  272. return uwb_rc_dev_addr_assign(rc);
  273. }
  274. /*
  275. * Print the 48-bit EUI MAC address of the radio controller when
  276. * reading /sys/class/uwb_rc/XX/mac_address
  277. */
  278. static ssize_t uwb_rc_mac_addr_show(struct device *dev,
  279. struct device_attribute *attr, char *buf)
  280. {
  281. struct uwb_dev *uwb_dev = to_uwb_dev(dev);
  282. struct uwb_rc *rc = uwb_dev->rc;
  283. struct uwb_mac_addr addr;
  284. ssize_t result;
  285. mutex_lock(&rc->uwb_dev.mutex);
  286. result = uwb_rc_addr_get(rc, &addr, UWB_ADDR_MAC);
  287. mutex_unlock(&rc->uwb_dev.mutex);
  288. if (result >= 0) {
  289. result = uwb_mac_addr_print(buf, UWB_ADDR_STRSIZE, &addr);
  290. buf[result++] = '\n';
  291. }
  292. return result;
  293. }
  294. /*
  295. * Parse a 48 bit address written to /sys/class/uwb_rc/XX/mac_address
  296. * and if correct, set it.
  297. */
  298. static ssize_t uwb_rc_mac_addr_store(struct device *dev,
  299. struct device_attribute *attr,
  300. const char *buf, size_t size)
  301. {
  302. struct uwb_dev *uwb_dev = to_uwb_dev(dev);
  303. struct uwb_rc *rc = uwb_dev->rc;
  304. struct uwb_mac_addr addr;
  305. ssize_t result;
  306. result = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\n",
  307. &addr.data[0], &addr.data[1], &addr.data[2],
  308. &addr.data[3], &addr.data[4], &addr.data[5]);
  309. if (result != 6) {
  310. result = -EINVAL;
  311. goto out;
  312. }
  313. if (is_multicast_ether_addr(addr.data)) {
  314. dev_err(&rc->uwb_dev.dev, "refusing to set multicast "
  315. "MAC address %s\n", buf);
  316. result = -EINVAL;
  317. goto out;
  318. }
  319. result = uwb_rc_mac_addr_set(rc, &addr);
  320. if (result == 0)
  321. rc->uwb_dev.mac_addr = addr;
  322. out:
  323. return result < 0 ? result : size;
  324. }
  325. DEVICE_ATTR(mac_address, S_IRUGO | S_IWUSR, uwb_rc_mac_addr_show, uwb_rc_mac_addr_store);
  326. /** Print @addr to @buf, @return bytes written */
  327. size_t __uwb_addr_print(char *buf, size_t buf_size, const unsigned char *addr,
  328. int type)
  329. {
  330. size_t result;
  331. if (type)
  332. result = scnprintf(buf, buf_size, "%pM", addr);
  333. else
  334. result = scnprintf(buf, buf_size, "%02x:%02x",
  335. addr[1], addr[0]);
  336. return result;
  337. }
  338. EXPORT_SYMBOL_GPL(__uwb_addr_print);