ie.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. /*
  2. * Ultra Wide Band
  3. * Information Element Handling
  4. *
  5. * Copyright (C) 2005-2006 Intel Corporation
  6. * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
  7. * Reinette Chatre <reinette.chatre@intel.com>
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License version
  11. * 2 as published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  21. * 02110-1301, USA.
  22. *
  23. *
  24. * FIXME: docs
  25. */
  26. #include "uwb-internal.h"
  27. #define D_LOCAL 0
  28. #include <linux/uwb/debug.h>
  29. /**
  30. * uwb_ie_next - get the next IE in a buffer
  31. * @ptr: start of the buffer containing the IE data
  32. * @len: length of the buffer
  33. *
  34. * Both @ptr and @len are updated so subsequent calls to uwb_ie_next()
  35. * will get the next IE.
  36. *
  37. * NULL is returned (and @ptr and @len will not be updated) if there
  38. * are no more IEs in the buffer or the buffer is too short.
  39. */
  40. struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len)
  41. {
  42. struct uwb_ie_hdr *hdr;
  43. size_t ie_len;
  44. if (*len < sizeof(struct uwb_ie_hdr))
  45. return NULL;
  46. hdr = *ptr;
  47. ie_len = sizeof(struct uwb_ie_hdr) + hdr->length;
  48. if (*len < ie_len)
  49. return NULL;
  50. *ptr += ie_len;
  51. *len -= ie_len;
  52. return hdr;
  53. }
  54. EXPORT_SYMBOL_GPL(uwb_ie_next);
  55. /**
  56. * Get the IEs that a radio controller is sending in its beacon
  57. *
  58. * @uwb_rc: UWB Radio Controller
  59. * @returns: Size read from the system
  60. *
  61. * We don't need to lock the uwb_rc's mutex because we don't modify
  62. * anything. Once done with the iedata buffer, call
  63. * uwb_rc_ie_release(iedata). Don't call kfree on it.
  64. */
  65. ssize_t uwb_rc_get_ie(struct uwb_rc *uwb_rc, struct uwb_rc_evt_get_ie **pget_ie)
  66. {
  67. ssize_t result;
  68. struct device *dev = &uwb_rc->uwb_dev.dev;
  69. struct uwb_rccb *cmd = NULL;
  70. struct uwb_rceb *reply = NULL;
  71. struct uwb_rc_evt_get_ie *get_ie;
  72. d_fnstart(3, dev, "(%p, %p)\n", uwb_rc, pget_ie);
  73. result = -ENOMEM;
  74. cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
  75. if (cmd == NULL)
  76. goto error_kzalloc;
  77. cmd->bCommandType = UWB_RC_CET_GENERAL;
  78. cmd->wCommand = cpu_to_le16(UWB_RC_CMD_GET_IE);
  79. result = uwb_rc_vcmd(uwb_rc, "GET_IE", cmd, sizeof(*cmd),
  80. UWB_RC_CET_GENERAL, UWB_RC_CMD_GET_IE,
  81. &reply);
  82. if (result < 0)
  83. goto error_cmd;
  84. get_ie = container_of(reply, struct uwb_rc_evt_get_ie, rceb);
  85. if (result < sizeof(*get_ie)) {
  86. dev_err(dev, "not enough data returned for decoding GET IE "
  87. "(%zu bytes received vs %zu needed)\n",
  88. result, sizeof(*get_ie));
  89. result = -EINVAL;
  90. } else if (result < sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength)) {
  91. dev_err(dev, "not enough data returned for decoding GET IE "
  92. "payload (%zu bytes received vs %zu needed)\n", result,
  93. sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength));
  94. result = -EINVAL;
  95. } else
  96. *pget_ie = get_ie;
  97. error_cmd:
  98. kfree(cmd);
  99. error_kzalloc:
  100. d_fnend(3, dev, "(%p, %p) = %d\n", uwb_rc, pget_ie, (int)result);
  101. return result;
  102. }
  103. EXPORT_SYMBOL_GPL(uwb_rc_get_ie);
  104. /*
  105. * Given a pointer to an IE, print it in ASCII/hex followed by a new line
  106. *
  107. * @ie_hdr: pointer to the IE header. Length is in there, and it is
  108. * guaranteed that the ie_hdr->length bytes following it are
  109. * safely accesible.
  110. *
  111. * @_data: context data passed from uwb_ie_for_each(), an struct output_ctx
  112. */
  113. int uwb_ie_dump_hex(struct uwb_dev *uwb_dev, const struct uwb_ie_hdr *ie_hdr,
  114. size_t offset, void *_ctx)
  115. {
  116. struct uwb_buf_ctx *ctx = _ctx;
  117. const u8 *pl = (void *)(ie_hdr + 1);
  118. u8 pl_itr;
  119. ctx->bytes += scnprintf(ctx->buf + ctx->bytes, ctx->size - ctx->bytes,
  120. "%02x %02x ", (unsigned) ie_hdr->element_id,
  121. (unsigned) ie_hdr->length);
  122. pl_itr = 0;
  123. while (pl_itr < ie_hdr->length && ctx->bytes < ctx->size)
  124. ctx->bytes += scnprintf(ctx->buf + ctx->bytes,
  125. ctx->size - ctx->bytes,
  126. "%02x ", (unsigned) pl[pl_itr++]);
  127. if (ctx->bytes < ctx->size)
  128. ctx->buf[ctx->bytes++] = '\n';
  129. return 0;
  130. }
  131. EXPORT_SYMBOL_GPL(uwb_ie_dump_hex);
  132. /**
  133. * Verify that a pointer in a buffer points to valid IE
  134. *
  135. * @start: pointer to start of buffer in which IE appears
  136. * @itr: pointer to IE inside buffer that will be verified
  137. * @top: pointer to end of buffer
  138. *
  139. * @returns: 0 if IE is valid, <0 otherwise
  140. *
  141. * Verification involves checking that the buffer can contain a
  142. * header and the amount of data reported in the IE header can be found in
  143. * the buffer.
  144. */
  145. static
  146. int uwb_rc_ie_verify(struct uwb_dev *uwb_dev, const void *start,
  147. const void *itr, const void *top)
  148. {
  149. struct device *dev = &uwb_dev->dev;
  150. const struct uwb_ie_hdr *ie_hdr;
  151. if (top - itr < sizeof(*ie_hdr)) {
  152. dev_err(dev, "Bad IE: no data to decode header "
  153. "(%zu bytes left vs %zu needed) at offset %zu\n",
  154. top - itr, sizeof(*ie_hdr), itr - start);
  155. return -EINVAL;
  156. }
  157. ie_hdr = itr;
  158. itr += sizeof(*ie_hdr);
  159. if (top - itr < ie_hdr->length) {
  160. dev_err(dev, "Bad IE: not enough data for payload "
  161. "(%zu bytes left vs %zu needed) at offset %zu\n",
  162. top - itr, (size_t)ie_hdr->length,
  163. (void *)ie_hdr - start);
  164. return -EINVAL;
  165. }
  166. return 0;
  167. }
  168. /**
  169. * Walk a buffer filled with consecutive IE's a buffer
  170. *
  171. * @uwb_dev: UWB device this IEs belong to (for err messages mainly)
  172. *
  173. * @fn: function to call with each IE; if it returns 0, we keep
  174. * traversing the buffer. If it returns !0, we'll stop and return
  175. * that value.
  176. *
  177. * @data: pointer passed to @fn
  178. *
  179. * @buf: buffer where the consecutive IEs are located
  180. *
  181. * @size: size of @buf
  182. *
  183. * Each IE is checked for basic correctness (there is space left for
  184. * the header and the payload). If that test is failed, we stop
  185. * processing. For every good IE, @fn is called.
  186. */
  187. ssize_t uwb_ie_for_each(struct uwb_dev *uwb_dev, uwb_ie_f fn, void *data,
  188. const void *buf, size_t size)
  189. {
  190. ssize_t result = 0;
  191. const struct uwb_ie_hdr *ie_hdr;
  192. const void *itr = buf, *top = itr + size;
  193. while (itr < top) {
  194. if (uwb_rc_ie_verify(uwb_dev, buf, itr, top) != 0)
  195. break;
  196. ie_hdr = itr;
  197. itr += sizeof(*ie_hdr) + ie_hdr->length;
  198. result = fn(uwb_dev, ie_hdr, itr - buf, data);
  199. if (result != 0)
  200. break;
  201. }
  202. return result;
  203. }
  204. EXPORT_SYMBOL_GPL(uwb_ie_for_each);
  205. /**
  206. * Replace all IEs currently being transmitted by a device
  207. *
  208. * @cmd: pointer to the SET-IE command with the IEs to set
  209. * @size: size of @buf
  210. */
  211. int uwb_rc_set_ie(struct uwb_rc *rc, struct uwb_rc_cmd_set_ie *cmd)
  212. {
  213. int result;
  214. struct device *dev = &rc->uwb_dev.dev;
  215. struct uwb_rc_evt_set_ie reply;
  216. reply.rceb.bEventType = UWB_RC_CET_GENERAL;
  217. reply.rceb.wEvent = UWB_RC_CMD_SET_IE;
  218. result = uwb_rc_cmd(rc, "SET-IE", &cmd->rccb,
  219. sizeof(*cmd) + le16_to_cpu(cmd->wIELength),
  220. &reply.rceb, sizeof(reply));
  221. if (result < 0)
  222. goto error_cmd;
  223. else if (result != sizeof(reply)) {
  224. dev_err(dev, "SET-IE: not enough data to decode reply "
  225. "(%d bytes received vs %zu needed)\n",
  226. result, sizeof(reply));
  227. result = -EIO;
  228. } else if (reply.bResultCode != UWB_RC_RES_SUCCESS) {
  229. dev_err(dev, "SET-IE: command execution failed: %s (%d)\n",
  230. uwb_rc_strerror(reply.bResultCode), reply.bResultCode);
  231. result = -EIO;
  232. } else
  233. result = 0;
  234. error_cmd:
  235. return result;
  236. }
  237. /**
  238. * Determine by IE id if IE is host settable
  239. * WUSB 1.0 [8.6.2.8 Table 8.85]
  240. *
  241. * EXCEPTION:
  242. * All but UWB_IE_WLP appears in Table 8.85 from WUSB 1.0. Setting this IE
  243. * is required for the WLP substack to perform association with its WSS so
  244. * we hope that the WUSB spec will be changed to reflect this.
  245. */
  246. static
  247. int uwb_rc_ie_is_host_settable(enum uwb_ie element_id)
  248. {
  249. if (element_id == UWB_PCA_AVAILABILITY ||
  250. element_id == UWB_BP_SWITCH_IE ||
  251. element_id == UWB_MAC_CAPABILITIES_IE ||
  252. element_id == UWB_PHY_CAPABILITIES_IE ||
  253. element_id == UWB_APP_SPEC_PROBE_IE ||
  254. element_id == UWB_IDENTIFICATION_IE ||
  255. element_id == UWB_MASTER_KEY_ID_IE ||
  256. element_id == UWB_IE_WLP ||
  257. element_id == UWB_APP_SPEC_IE)
  258. return 1;
  259. return 0;
  260. }
  261. /**
  262. * Extract Host Settable IEs from IE
  263. *
  264. * @ie_data: pointer to buffer containing all IEs
  265. * @size: size of buffer
  266. *
  267. * @returns: length of buffer that only includes host settable IEs
  268. *
  269. * Given a buffer of IEs we move all Host Settable IEs to front of buffer
  270. * by overwriting the IEs that are not Host Settable.
  271. * Buffer length is adjusted accordingly.
  272. */
  273. static
  274. ssize_t uwb_rc_parse_host_settable_ie(struct uwb_dev *uwb_dev,
  275. void *ie_data, size_t size)
  276. {
  277. size_t new_len = size;
  278. struct uwb_ie_hdr *ie_hdr;
  279. size_t ie_length;
  280. void *itr = ie_data, *top = itr + size;
  281. while (itr < top) {
  282. if (uwb_rc_ie_verify(uwb_dev, ie_data, itr, top) != 0)
  283. break;
  284. ie_hdr = itr;
  285. ie_length = sizeof(*ie_hdr) + ie_hdr->length;
  286. if (uwb_rc_ie_is_host_settable(ie_hdr->element_id)) {
  287. itr += ie_length;
  288. } else {
  289. memmove(itr, itr + ie_length, top - (itr + ie_length));
  290. new_len -= ie_length;
  291. top -= ie_length;
  292. }
  293. }
  294. return new_len;
  295. }
  296. /* Cleanup the whole IE management subsystem */
  297. void uwb_rc_ie_init(struct uwb_rc *uwb_rc)
  298. {
  299. mutex_init(&uwb_rc->ies_mutex);
  300. }
  301. /**
  302. * Set up cache for host settable IEs currently being transmitted
  303. *
  304. * First we just call GET-IE to get the current IEs being transmitted
  305. * (or we workaround and pretend we did) and (because the format is
  306. * the same) reuse that as the IE cache (with the command prefix, as
  307. * explained in 'struct uwb_rc').
  308. *
  309. * @returns: size of cache created
  310. */
  311. ssize_t uwb_rc_ie_setup(struct uwb_rc *uwb_rc)
  312. {
  313. struct device *dev = &uwb_rc->uwb_dev.dev;
  314. ssize_t result;
  315. size_t capacity;
  316. struct uwb_rc_evt_get_ie *ie_info;
  317. d_fnstart(3, dev, "(%p)\n", uwb_rc);
  318. mutex_lock(&uwb_rc->ies_mutex);
  319. result = uwb_rc_get_ie(uwb_rc, &ie_info);
  320. if (result < 0)
  321. goto error_get_ie;
  322. capacity = result;
  323. d_printf(5, dev, "Got IEs %zu bytes (%zu long at %p)\n", result,
  324. (size_t)le16_to_cpu(ie_info->wIELength), ie_info);
  325. /* Remove IEs that host should not set. */
  326. result = uwb_rc_parse_host_settable_ie(&uwb_rc->uwb_dev,
  327. ie_info->IEData, le16_to_cpu(ie_info->wIELength));
  328. if (result < 0)
  329. goto error_parse;
  330. d_printf(5, dev, "purged non-settable IEs to %zu bytes\n", result);
  331. uwb_rc->ies = (void *) ie_info;
  332. uwb_rc->ies->rccb.bCommandType = UWB_RC_CET_GENERAL;
  333. uwb_rc->ies->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_SET_IE);
  334. uwb_rc->ies_capacity = capacity;
  335. d_printf(5, dev, "IE cache at %p %zu bytes, %zu capacity\n",
  336. ie_info, result, capacity);
  337. result = 0;
  338. error_parse:
  339. error_get_ie:
  340. mutex_unlock(&uwb_rc->ies_mutex);
  341. d_fnend(3, dev, "(%p) = %zu\n", uwb_rc, result);
  342. return result;
  343. }
  344. /* Cleanup the whole IE management subsystem */
  345. void uwb_rc_ie_release(struct uwb_rc *uwb_rc)
  346. {
  347. kfree(uwb_rc->ies);
  348. uwb_rc->ies = NULL;
  349. uwb_rc->ies_capacity = 0;
  350. }
  351. static
  352. int __acc_size(struct uwb_dev *uwb_dev, const struct uwb_ie_hdr *ie_hdr,
  353. size_t offset, void *_ctx)
  354. {
  355. size_t *acc_size = _ctx;
  356. *acc_size += sizeof(*ie_hdr) + ie_hdr->length;
  357. d_printf(6, &uwb_dev->dev, "new acc size %zu\n", *acc_size);
  358. return 0;
  359. }
  360. /**
  361. * Add a new IE to IEs currently being transmitted by device
  362. *
  363. * @ies: the buffer containing the new IE or IEs to be added to
  364. * the device's beacon. The buffer will be verified for
  365. * consistence (meaning the headers should be right) and
  366. * consistent with the buffer size.
  367. * @size: size of @ies (in bytes, total buffer size)
  368. * @returns: 0 if ok, <0 errno code on error
  369. *
  370. * According to WHCI 0.95 [4.13.6] the driver will only receive the RCEB
  371. * after the device sent the first beacon that includes the IEs specified
  372. * in the SET IE command. We thus cannot send this command if the device is
  373. * not beaconing. Instead, a SET IE command will be sent later right after
  374. * we start beaconing.
  375. *
  376. * Setting an IE on the device will overwrite all current IEs in device. So
  377. * we take the current IEs being transmitted by the device, append the
  378. * new one, and call SET IE with all the IEs needed.
  379. *
  380. * The local IE cache will only be updated with the new IE if SET IE
  381. * completed successfully.
  382. */
  383. int uwb_rc_ie_add(struct uwb_rc *uwb_rc,
  384. const struct uwb_ie_hdr *ies, size_t size)
  385. {
  386. int result = 0;
  387. struct device *dev = &uwb_rc->uwb_dev.dev;
  388. struct uwb_rc_cmd_set_ie *new_ies;
  389. size_t ies_size, total_size, acc_size = 0;
  390. if (uwb_rc->ies == NULL)
  391. return -ESHUTDOWN;
  392. uwb_ie_for_each(&uwb_rc->uwb_dev, __acc_size, &acc_size, ies, size);
  393. if (acc_size != size) {
  394. dev_err(dev, "BUG: bad IEs, misconstructed headers "
  395. "[%zu bytes reported vs %zu calculated]\n",
  396. size, acc_size);
  397. WARN_ON(1);
  398. return -EINVAL;
  399. }
  400. mutex_lock(&uwb_rc->ies_mutex);
  401. ies_size = le16_to_cpu(uwb_rc->ies->wIELength);
  402. total_size = sizeof(*uwb_rc->ies) + ies_size;
  403. if (total_size + size > uwb_rc->ies_capacity) {
  404. d_printf(4, dev, "Reallocating IE cache from %p capacity %zu "
  405. "to capacity %zu\n", uwb_rc->ies, uwb_rc->ies_capacity,
  406. total_size + size);
  407. new_ies = kzalloc(total_size + size, GFP_KERNEL);
  408. if (new_ies == NULL) {
  409. dev_err(dev, "No memory for adding new IE\n");
  410. result = -ENOMEM;
  411. goto error_alloc;
  412. }
  413. memcpy(new_ies, uwb_rc->ies, total_size);
  414. uwb_rc->ies_capacity = total_size + size;
  415. kfree(uwb_rc->ies);
  416. uwb_rc->ies = new_ies;
  417. d_printf(4, dev, "New IE cache at %p capacity %zu\n",
  418. uwb_rc->ies, uwb_rc->ies_capacity);
  419. }
  420. memcpy((void *)uwb_rc->ies + total_size, ies, size);
  421. uwb_rc->ies->wIELength = cpu_to_le16(ies_size + size);
  422. if (uwb_rc->beaconing != -1) {
  423. result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies);
  424. if (result < 0) {
  425. dev_err(dev, "Cannot set new IE on device: %d\n",
  426. result);
  427. uwb_rc->ies->wIELength = cpu_to_le16(ies_size);
  428. } else
  429. result = 0;
  430. }
  431. d_printf(4, dev, "IEs now occupy %hu bytes of %zu capacity at %p\n",
  432. le16_to_cpu(uwb_rc->ies->wIELength), uwb_rc->ies_capacity,
  433. uwb_rc->ies);
  434. error_alloc:
  435. mutex_unlock(&uwb_rc->ies_mutex);
  436. return result;
  437. }
  438. EXPORT_SYMBOL_GPL(uwb_rc_ie_add);
  439. /*
  440. * Remove an IE from internal cache
  441. *
  442. * We are dealing with our internal IE cache so no need to verify that the
  443. * IEs are valid (it has been done already).
  444. *
  445. * Should be called with ies_mutex held
  446. *
  447. * We do not break out once an IE is found in the cache. It is currently
  448. * possible to have more than one IE with the same ID included in the
  449. * beacon. We don't reallocate, we just mark the size smaller.
  450. */
  451. static
  452. int uwb_rc_ie_cache_rm(struct uwb_rc *uwb_rc, enum uwb_ie to_remove)
  453. {
  454. struct uwb_ie_hdr *ie_hdr;
  455. size_t new_len = le16_to_cpu(uwb_rc->ies->wIELength);
  456. void *itr = uwb_rc->ies->IEData;
  457. void *top = itr + new_len;
  458. while (itr < top) {
  459. ie_hdr = itr;
  460. if (ie_hdr->element_id != to_remove) {
  461. itr += sizeof(*ie_hdr) + ie_hdr->length;
  462. } else {
  463. int ie_length;
  464. ie_length = sizeof(*ie_hdr) + ie_hdr->length;
  465. if (top - itr != ie_length)
  466. memmove(itr, itr + ie_length, top - itr + ie_length);
  467. top -= ie_length;
  468. new_len -= ie_length;
  469. }
  470. }
  471. uwb_rc->ies->wIELength = cpu_to_le16(new_len);
  472. return 0;
  473. }
  474. /**
  475. * Remove an IE currently being transmitted by device
  476. *
  477. * @element_id: id of IE to be removed from device's beacon
  478. */
  479. int uwb_rc_ie_rm(struct uwb_rc *uwb_rc, enum uwb_ie element_id)
  480. {
  481. struct device *dev = &uwb_rc->uwb_dev.dev;
  482. int result;
  483. if (uwb_rc->ies == NULL)
  484. return -ESHUTDOWN;
  485. mutex_lock(&uwb_rc->ies_mutex);
  486. result = uwb_rc_ie_cache_rm(uwb_rc, element_id);
  487. if (result < 0)
  488. dev_err(dev, "Cannot remove IE from cache.\n");
  489. if (uwb_rc->beaconing != -1) {
  490. result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies);
  491. if (result < 0)
  492. dev_err(dev, "Cannot set new IE on device.\n");
  493. }
  494. mutex_unlock(&uwb_rc->ies_mutex);
  495. return result;
  496. }
  497. EXPORT_SYMBOL_GPL(uwb_rc_ie_rm);