wlp-lc.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. /*
  2. * WiMedia Logical Link Control Protocol (WLP)
  3. *
  4. * Copyright (C) 2005-2006 Intel Corporation
  5. * Reinette Chatre <reinette.chatre@intel.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License version
  9. * 2 as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19. * 02110-1301, USA.
  20. *
  21. *
  22. * FIXME: docs
  23. */
  24. #include <linux/wlp.h>
  25. #define D_LOCAL 6
  26. #include <linux/uwb/debug.h>
  27. #include "wlp-internal.h"
  28. static
  29. void wlp_neighbor_init(struct wlp_neighbor_e *neighbor)
  30. {
  31. INIT_LIST_HEAD(&neighbor->wssid);
  32. }
  33. /**
  34. * Create area for device information storage
  35. *
  36. * wlp->mutex must be held
  37. */
  38. int __wlp_alloc_device_info(struct wlp *wlp)
  39. {
  40. struct device *dev = &wlp->rc->uwb_dev.dev;
  41. BUG_ON(wlp->dev_info != NULL);
  42. wlp->dev_info = kzalloc(sizeof(struct wlp_device_info), GFP_KERNEL);
  43. if (wlp->dev_info == NULL) {
  44. dev_err(dev, "WLP: Unable to allocate memory for "
  45. "device information.\n");
  46. return -ENOMEM;
  47. }
  48. return 0;
  49. }
  50. /**
  51. * Fill in device information using function provided by driver
  52. *
  53. * wlp->mutex must be held
  54. */
  55. static
  56. void __wlp_fill_device_info(struct wlp *wlp)
  57. {
  58. struct device *dev = &wlp->rc->uwb_dev.dev;
  59. BUG_ON(wlp->fill_device_info == NULL);
  60. d_printf(6, dev, "Retrieving device information "
  61. "from device driver.\n");
  62. wlp->fill_device_info(wlp, wlp->dev_info);
  63. }
  64. /**
  65. * Setup device information
  66. *
  67. * Allocate area for device information and populate it.
  68. *
  69. * wlp->mutex must be held
  70. */
  71. int __wlp_setup_device_info(struct wlp *wlp)
  72. {
  73. int result;
  74. struct device *dev = &wlp->rc->uwb_dev.dev;
  75. result = __wlp_alloc_device_info(wlp);
  76. if (result < 0) {
  77. dev_err(dev, "WLP: Unable to allocate area for "
  78. "device information.\n");
  79. return result;
  80. }
  81. __wlp_fill_device_info(wlp);
  82. return 0;
  83. }
  84. /**
  85. * Remove information about neighbor stored temporarily
  86. *
  87. * Information learned during discovey should only be stored when the
  88. * device enrolls in the neighbor's WSS. We do need to store this
  89. * information temporarily in order to present it to the user.
  90. *
  91. * We are only interested in keeping neighbor WSS information if that
  92. * neighbor is accepting enrollment.
  93. *
  94. * should be called with wlp->nbmutex held
  95. */
  96. void wlp_remove_neighbor_tmp_info(struct wlp_neighbor_e *neighbor)
  97. {
  98. struct wlp_wssid_e *wssid_e, *next;
  99. u8 keep;
  100. if (!list_empty(&neighbor->wssid)) {
  101. list_for_each_entry_safe(wssid_e, next, &neighbor->wssid,
  102. node) {
  103. if (wssid_e->info != NULL) {
  104. keep = wssid_e->info->accept_enroll;
  105. kfree(wssid_e->info);
  106. wssid_e->info = NULL;
  107. if (!keep) {
  108. list_del(&wssid_e->node);
  109. kfree(wssid_e);
  110. }
  111. }
  112. }
  113. }
  114. if (neighbor->info != NULL) {
  115. kfree(neighbor->info);
  116. neighbor->info = NULL;
  117. }
  118. }
  119. /**
  120. * Populate WLP neighborhood cache with neighbor information
  121. *
  122. * A new neighbor is found. If it is discoverable then we add it to the
  123. * neighborhood cache.
  124. *
  125. */
  126. static
  127. int wlp_add_neighbor(struct wlp *wlp, struct uwb_dev *dev)
  128. {
  129. int result = 0;
  130. int discoverable;
  131. struct wlp_neighbor_e *neighbor;
  132. d_fnstart(6, &dev->dev, "uwb %p \n", dev);
  133. d_printf(6, &dev->dev, "Found neighbor device %02x:%02x \n",
  134. dev->dev_addr.data[1], dev->dev_addr.data[0]);
  135. /**
  136. * FIXME:
  137. * Use contents of WLP IE found in beacon cache to determine if
  138. * neighbor is discoverable.
  139. * The device does not support WLP IE yet so this still needs to be
  140. * done. Until then we assume all devices are discoverable.
  141. */
  142. discoverable = 1; /* will be changed when FIXME disappears */
  143. if (discoverable) {
  144. /* Add neighbor to cache for discovery */
  145. neighbor = kzalloc(sizeof(*neighbor), GFP_KERNEL);
  146. if (neighbor == NULL) {
  147. dev_err(&dev->dev, "Unable to create memory for "
  148. "new neighbor. \n");
  149. result = -ENOMEM;
  150. goto error_no_mem;
  151. }
  152. wlp_neighbor_init(neighbor);
  153. uwb_dev_get(dev);
  154. neighbor->uwb_dev = dev;
  155. list_add(&neighbor->node, &wlp->neighbors);
  156. }
  157. error_no_mem:
  158. d_fnend(6, &dev->dev, "uwb %p, result = %d \n", dev, result);
  159. return result;
  160. }
  161. /**
  162. * Remove one neighbor from cache
  163. */
  164. static
  165. void __wlp_neighbor_release(struct wlp_neighbor_e *neighbor)
  166. {
  167. struct wlp_wssid_e *wssid_e, *next_wssid_e;
  168. list_for_each_entry_safe(wssid_e, next_wssid_e,
  169. &neighbor->wssid, node) {
  170. list_del(&wssid_e->node);
  171. kfree(wssid_e);
  172. }
  173. uwb_dev_put(neighbor->uwb_dev);
  174. list_del(&neighbor->node);
  175. kfree(neighbor);
  176. }
  177. /**
  178. * Clear entire neighborhood cache.
  179. */
  180. static
  181. void __wlp_neighbors_release(struct wlp *wlp)
  182. {
  183. struct wlp_neighbor_e *neighbor, *next;
  184. if (list_empty(&wlp->neighbors))
  185. return;
  186. list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) {
  187. __wlp_neighbor_release(neighbor);
  188. }
  189. }
  190. static
  191. void wlp_neighbors_release(struct wlp *wlp)
  192. {
  193. mutex_lock(&wlp->nbmutex);
  194. __wlp_neighbors_release(wlp);
  195. mutex_unlock(&wlp->nbmutex);
  196. }
  197. /**
  198. * Send D1 message to neighbor, receive D2 message
  199. *
  200. * @neighbor: neighbor to which D1 message will be sent
  201. * @wss: if not NULL, it is an enrollment request for this WSS
  202. * @wssid: if wss not NULL, this is the wssid of the WSS in which we
  203. * want to enroll
  204. *
  205. * A D1/D2 exchange is done for one of two reasons: discovery or
  206. * enrollment. If done for discovery the D1 message is sent to the neighbor
  207. * and the contents of the D2 response is stored in a temporary cache.
  208. * If done for enrollment the @wss and @wssid are provided also. In this
  209. * case the D1 message is sent to the neighbor, the D2 response is parsed
  210. * for enrollment of the WSS with wssid.
  211. *
  212. * &wss->mutex is held
  213. */
  214. static
  215. int wlp_d1d2_exchange(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
  216. struct wlp_wss *wss, struct wlp_uuid *wssid)
  217. {
  218. int result;
  219. struct device *dev = &wlp->rc->uwb_dev.dev;
  220. DECLARE_COMPLETION_ONSTACK(completion);
  221. struct wlp_session session;
  222. struct sk_buff *skb;
  223. struct wlp_frame_assoc *resp;
  224. struct uwb_dev_addr *dev_addr = &neighbor->uwb_dev->dev_addr;
  225. mutex_lock(&wlp->mutex);
  226. if (!wlp_uuid_is_set(&wlp->uuid)) {
  227. dev_err(dev, "WLP: UUID is not set. Set via sysfs to "
  228. "proceed.\n");
  229. result = -ENXIO;
  230. goto out;
  231. }
  232. /* Send D1 association frame */
  233. result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_D1);
  234. if (result < 0) {
  235. dev_err(dev, "Unable to send D1 frame to neighbor "
  236. "%02x:%02x (%d)\n", dev_addr->data[1],
  237. dev_addr->data[0], result);
  238. d_printf(6, dev, "Add placeholders into buffer next to "
  239. "neighbor information we have (dev address).\n");
  240. goto out;
  241. }
  242. /* Create session, wait for response */
  243. session.exp_message = WLP_ASSOC_D2;
  244. session.cb = wlp_session_cb;
  245. session.cb_priv = &completion;
  246. session.neighbor_addr = *dev_addr;
  247. BUG_ON(wlp->session != NULL);
  248. wlp->session = &session;
  249. /* Wait for D2/F0 frame */
  250. result = wait_for_completion_interruptible_timeout(&completion,
  251. WLP_PER_MSG_TIMEOUT * HZ);
  252. if (result == 0) {
  253. result = -ETIMEDOUT;
  254. dev_err(dev, "Timeout while sending D1 to neighbor "
  255. "%02x:%02x.\n", dev_addr->data[1],
  256. dev_addr->data[0]);
  257. goto error_session;
  258. }
  259. if (result < 0) {
  260. dev_err(dev, "Unable to discover/enroll neighbor %02x:%02x.\n",
  261. dev_addr->data[1], dev_addr->data[0]);
  262. goto error_session;
  263. }
  264. /* Parse message in session->data: it will be either D2 or F0 */
  265. skb = session.data;
  266. resp = (void *) skb->data;
  267. d_printf(6, dev, "Received response to D1 frame. \n");
  268. d_dump(6, dev, skb->data, skb->len > 72 ? 72 : skb->len);
  269. if (resp->type == WLP_ASSOC_F0) {
  270. result = wlp_parse_f0(wlp, skb);
  271. if (result < 0)
  272. dev_err(dev, "WLP: Unable to parse F0 from neighbor "
  273. "%02x:%02x.\n", dev_addr->data[1],
  274. dev_addr->data[0]);
  275. result = -EINVAL;
  276. goto error_resp_parse;
  277. }
  278. if (wss == NULL) {
  279. /* Discovery */
  280. result = wlp_parse_d2_frame_to_cache(wlp, skb, neighbor);
  281. if (result < 0) {
  282. dev_err(dev, "WLP: Unable to parse D2 message from "
  283. "neighbor %02x:%02x for discovery.\n",
  284. dev_addr->data[1], dev_addr->data[0]);
  285. goto error_resp_parse;
  286. }
  287. } else {
  288. /* Enrollment */
  289. result = wlp_parse_d2_frame_to_enroll(wss, skb, neighbor,
  290. wssid);
  291. if (result < 0) {
  292. dev_err(dev, "WLP: Unable to parse D2 message from "
  293. "neighbor %02x:%02x for enrollment.\n",
  294. dev_addr->data[1], dev_addr->data[0]);
  295. goto error_resp_parse;
  296. }
  297. }
  298. error_resp_parse:
  299. kfree_skb(skb);
  300. error_session:
  301. wlp->session = NULL;
  302. out:
  303. mutex_unlock(&wlp->mutex);
  304. return result;
  305. }
  306. /**
  307. * Enroll into WSS of provided WSSID by using neighbor as registrar
  308. *
  309. * &wss->mutex is held
  310. */
  311. int wlp_enroll_neighbor(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
  312. struct wlp_wss *wss, struct wlp_uuid *wssid)
  313. {
  314. int result = 0;
  315. struct device *dev = &wlp->rc->uwb_dev.dev;
  316. char buf[WLP_WSS_UUID_STRSIZE];
  317. struct uwb_dev_addr *dev_addr = &neighbor->uwb_dev->dev_addr;
  318. wlp_wss_uuid_print(buf, sizeof(buf), wssid);
  319. d_fnstart(6, dev, "wlp %p, neighbor %p, wss %p, wssid %p (%s)\n",
  320. wlp, neighbor, wss, wssid, buf);
  321. d_printf(6, dev, "Complete me.\n");
  322. result = wlp_d1d2_exchange(wlp, neighbor, wss, wssid);
  323. if (result < 0) {
  324. dev_err(dev, "WLP: D1/D2 message exchange for enrollment "
  325. "failed. result = %d \n", result);
  326. goto out;
  327. }
  328. if (wss->state != WLP_WSS_STATE_PART_ENROLLED) {
  329. dev_err(dev, "WLP: Unable to enroll into WSS %s using "
  330. "neighbor %02x:%02x. \n", buf,
  331. dev_addr->data[1], dev_addr->data[0]);
  332. result = -EINVAL;
  333. goto out;
  334. }
  335. if (wss->secure_status == WLP_WSS_SECURE) {
  336. dev_err(dev, "FIXME: need to complete secure enrollment.\n");
  337. result = -EINVAL;
  338. goto error;
  339. } else {
  340. wss->state = WLP_WSS_STATE_ENROLLED;
  341. d_printf(2, dev, "WLP: Success Enrollment into unsecure WSS "
  342. "%s using neighbor %02x:%02x. \n", buf,
  343. dev_addr->data[1], dev_addr->data[0]);
  344. }
  345. d_fnend(6, dev, "wlp %p, neighbor %p, wss %p, wssid %p (%s)\n",
  346. wlp, neighbor, wss, wssid, buf);
  347. out:
  348. return result;
  349. error:
  350. wlp_wss_reset(wss);
  351. return result;
  352. }
  353. /**
  354. * Discover WSS information of neighbor's active WSS
  355. */
  356. static
  357. int wlp_discover_neighbor(struct wlp *wlp,
  358. struct wlp_neighbor_e *neighbor)
  359. {
  360. return wlp_d1d2_exchange(wlp, neighbor, NULL, NULL);
  361. }
  362. /**
  363. * Each neighbor in the neighborhood cache is discoverable. Discover it.
  364. *
  365. * Discovery is done through sending of D1 association frame and parsing
  366. * the D2 association frame response. Only wssid from D2 will be included
  367. * in neighbor cache, rest is just displayed to user and forgotten.
  368. *
  369. * The discovery is not done in parallel. This is simple and enables us to
  370. * maintain only one association context.
  371. *
  372. * The discovery of one neighbor does not affect the other, but if the
  373. * discovery of a neighbor fails it is removed from the neighborhood cache.
  374. */
  375. static
  376. int wlp_discover_all_neighbors(struct wlp *wlp)
  377. {
  378. int result = 0;
  379. struct device *dev = &wlp->rc->uwb_dev.dev;
  380. struct wlp_neighbor_e *neighbor, *next;
  381. list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) {
  382. result = wlp_discover_neighbor(wlp, neighbor);
  383. if (result < 0) {
  384. dev_err(dev, "WLP: Unable to discover neighbor "
  385. "%02x:%02x, removing from neighborhood. \n",
  386. neighbor->uwb_dev->dev_addr.data[1],
  387. neighbor->uwb_dev->dev_addr.data[0]);
  388. __wlp_neighbor_release(neighbor);
  389. }
  390. }
  391. return result;
  392. }
  393. static int wlp_add_neighbor_helper(struct device *dev, void *priv)
  394. {
  395. struct wlp *wlp = priv;
  396. struct uwb_dev *uwb_dev = to_uwb_dev(dev);
  397. return wlp_add_neighbor(wlp, uwb_dev);
  398. }
  399. /**
  400. * Discover WLP neighborhood
  401. *
  402. * Will send D1 association frame to all devices in beacon group that have
  403. * discoverable bit set in WLP IE. D2 frames will be received, information
  404. * displayed to user in @buf. Partial information (from D2 association
  405. * frame) will be cached to assist with future association
  406. * requests.
  407. *
  408. * The discovery of the WLP neighborhood is triggered by the user. This
  409. * should occur infrequently and we thus free current cache and re-allocate
  410. * memory if needed.
  411. *
  412. * If one neighbor fails during initial discovery (determining if it is a
  413. * neighbor or not), we fail all - note that interaction with neighbor has
  414. * not occured at this point so if a failure occurs we know something went wrong
  415. * locally. We thus undo everything.
  416. */
  417. ssize_t wlp_discover(struct wlp *wlp)
  418. {
  419. int result = 0;
  420. struct device *dev = &wlp->rc->uwb_dev.dev;
  421. d_fnstart(6, dev, "wlp %p \n", wlp);
  422. mutex_lock(&wlp->nbmutex);
  423. /* Clear current neighborhood cache. */
  424. __wlp_neighbors_release(wlp);
  425. /* Determine which devices in neighborhood. Repopulate cache. */
  426. result = uwb_dev_for_each(wlp->rc, wlp_add_neighbor_helper, wlp);
  427. if (result < 0) {
  428. /* May have partial neighbor information, release all. */
  429. __wlp_neighbors_release(wlp);
  430. goto error_dev_for_each;
  431. }
  432. /* Discover the properties of devices in neighborhood. */
  433. result = wlp_discover_all_neighbors(wlp);
  434. /* In case of failure we still print our partial results. */
  435. if (result < 0) {
  436. dev_err(dev, "Unable to fully discover neighborhood. \n");
  437. result = 0;
  438. }
  439. error_dev_for_each:
  440. mutex_unlock(&wlp->nbmutex);
  441. d_fnend(6, dev, "wlp %p \n", wlp);
  442. return result;
  443. }
  444. /**
  445. * Handle events from UWB stack
  446. *
  447. * We handle events conservatively. If a neighbor goes off the air we
  448. * remove it from the neighborhood. If an association process is in
  449. * progress this function will block waiting for the nbmutex to become
  450. * free. The association process will thus be allowed to complete before it
  451. * is removed.
  452. */
  453. static
  454. void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev,
  455. enum uwb_notifs event)
  456. {
  457. struct wlp *wlp = _wlp;
  458. struct device *dev = &wlp->rc->uwb_dev.dev;
  459. struct wlp_neighbor_e *neighbor, *next;
  460. int result;
  461. switch (event) {
  462. case UWB_NOTIF_ONAIR:
  463. d_printf(6, dev, "UWB device %02x:%02x is onair\n",
  464. uwb_dev->dev_addr.data[1],
  465. uwb_dev->dev_addr.data[0]);
  466. result = wlp_eda_create_node(&wlp->eda,
  467. uwb_dev->mac_addr.data,
  468. &uwb_dev->dev_addr);
  469. if (result < 0)
  470. dev_err(dev, "WLP: Unable to add new neighbor "
  471. "%02x:%02x to EDA cache.\n",
  472. uwb_dev->dev_addr.data[1],
  473. uwb_dev->dev_addr.data[0]);
  474. break;
  475. case UWB_NOTIF_OFFAIR:
  476. d_printf(6, dev, "UWB device %02x:%02x is offair\n",
  477. uwb_dev->dev_addr.data[1],
  478. uwb_dev->dev_addr.data[0]);
  479. wlp_eda_rm_node(&wlp->eda, &uwb_dev->dev_addr);
  480. mutex_lock(&wlp->nbmutex);
  481. list_for_each_entry_safe(neighbor, next, &wlp->neighbors,
  482. node) {
  483. if (neighbor->uwb_dev == uwb_dev) {
  484. d_printf(6, dev, "Removing device from "
  485. "neighborhood.\n");
  486. __wlp_neighbor_release(neighbor);
  487. }
  488. }
  489. mutex_unlock(&wlp->nbmutex);
  490. break;
  491. default:
  492. dev_err(dev, "don't know how to handle event %d from uwb\n",
  493. event);
  494. }
  495. }
  496. int wlp_setup(struct wlp *wlp, struct uwb_rc *rc)
  497. {
  498. struct device *dev = &rc->uwb_dev.dev;
  499. int result;
  500. d_fnstart(6, dev, "wlp %p\n", wlp);
  501. BUG_ON(wlp->fill_device_info == NULL);
  502. BUG_ON(wlp->xmit_frame == NULL);
  503. BUG_ON(wlp->stop_queue == NULL);
  504. BUG_ON(wlp->start_queue == NULL);
  505. wlp->rc = rc;
  506. wlp_eda_init(&wlp->eda);/* Set up address cache */
  507. wlp->uwb_notifs_handler.cb = wlp_uwb_notifs_cb;
  508. wlp->uwb_notifs_handler.data = wlp;
  509. uwb_notifs_register(rc, &wlp->uwb_notifs_handler);
  510. uwb_pal_init(&wlp->pal);
  511. result = uwb_pal_register(rc, &wlp->pal);
  512. if (result < 0)
  513. uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
  514. d_fnend(6, dev, "wlp %p, result = %d\n", wlp, result);
  515. return result;
  516. }
  517. EXPORT_SYMBOL_GPL(wlp_setup);
  518. void wlp_remove(struct wlp *wlp)
  519. {
  520. struct device *dev = &wlp->rc->uwb_dev.dev;
  521. d_fnstart(6, dev, "wlp %p\n", wlp);
  522. wlp_neighbors_release(wlp);
  523. uwb_pal_unregister(wlp->rc, &wlp->pal);
  524. uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
  525. wlp_eda_release(&wlp->eda);
  526. mutex_lock(&wlp->mutex);
  527. if (wlp->dev_info != NULL)
  528. kfree(wlp->dev_info);
  529. mutex_unlock(&wlp->mutex);
  530. wlp->rc = NULL;
  531. /* We have to use NULL here because this function can be called
  532. * when the device disappeared. */
  533. d_fnend(6, NULL, "wlp %p\n", wlp);
  534. }
  535. EXPORT_SYMBOL_GPL(wlp_remove);
  536. /**
  537. * wlp_reset_all - reset the WLP hardware
  538. * @wlp: the WLP device to reset.
  539. *
  540. * This schedules a full hardware reset of the WLP device. The radio
  541. * controller and any other PALs will also be reset.
  542. */
  543. void wlp_reset_all(struct wlp *wlp)
  544. {
  545. uwb_rc_reset_all(wlp->rc);
  546. }
  547. EXPORT_SYMBOL_GPL(wlp_reset_all);