wss-lc.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055
  1. /*
  2. * WiMedia Logical Link Control Protocol (WLP)
  3. *
  4. * Copyright (C) 2007 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. * Implementation of the WLP association protocol.
  23. *
  24. * FIXME: Docs
  25. *
  26. * A UWB network interface will configure a WSS through wlp_wss_setup() after
  27. * the interface has been assigned a MAC address, typically after
  28. * "ifconfig" has been called. When the interface goes down it should call
  29. * wlp_wss_remove().
  30. *
  31. * When the WSS is ready for use the user interacts via sysfs to create,
  32. * discover, and activate WSS.
  33. *
  34. * wlp_wss_enroll_activate()
  35. *
  36. * wlp_wss_create_activate()
  37. * wlp_wss_set_wssid_hash()
  38. * wlp_wss_comp_wssid_hash()
  39. * wlp_wss_sel_bcast_addr()
  40. * wlp_wss_sysfs_add()
  41. *
  42. * Called when no more references to WSS exist:
  43. * wlp_wss_release()
  44. * wlp_wss_reset()
  45. */
  46. #include <linux/etherdevice.h> /* for is_valid_ether_addr */
  47. #include <linux/skbuff.h>
  48. #include <linux/wlp.h>
  49. #define D_LOCAL 5
  50. #include <linux/uwb/debug.h>
  51. #include "wlp-internal.h"
  52. size_t wlp_wss_key_print(char *buf, size_t bufsize, u8 *key)
  53. {
  54. size_t result;
  55. result = scnprintf(buf, bufsize,
  56. "%02x %02x %02x %02x %02x %02x "
  57. "%02x %02x %02x %02x %02x %02x "
  58. "%02x %02x %02x %02x",
  59. key[0], key[1], key[2], key[3],
  60. key[4], key[5], key[6], key[7],
  61. key[8], key[9], key[10], key[11],
  62. key[12], key[13], key[14], key[15]);
  63. return result;
  64. }
  65. /**
  66. * Compute WSSID hash
  67. * WLP Draft 0.99 [7.2.1]
  68. *
  69. * The WSSID hash for a WSSID is the result of an octet-wise exclusive-OR
  70. * of all octets in the WSSID.
  71. */
  72. static
  73. u8 wlp_wss_comp_wssid_hash(struct wlp_uuid *wssid)
  74. {
  75. return wssid->data[0] ^ wssid->data[1] ^ wssid->data[2]
  76. ^ wssid->data[3] ^ wssid->data[4] ^ wssid->data[5]
  77. ^ wssid->data[6] ^ wssid->data[7] ^ wssid->data[8]
  78. ^ wssid->data[9] ^ wssid->data[10] ^ wssid->data[11]
  79. ^ wssid->data[12] ^ wssid->data[13] ^ wssid->data[14]
  80. ^ wssid->data[15];
  81. }
  82. /**
  83. * Select a multicast EUI-48 for the WSS broadcast address.
  84. * WLP Draft 0.99 [7.2.1]
  85. *
  86. * Selected based on the WiMedia Alliance OUI, 00-13-88, within the WLP
  87. * range, [01-13-88-00-01-00, 01-13-88-00-01-FF] inclusive.
  88. *
  89. * This address is currently hardcoded.
  90. * FIXME?
  91. */
  92. static
  93. struct uwb_mac_addr wlp_wss_sel_bcast_addr(struct wlp_wss *wss)
  94. {
  95. struct uwb_mac_addr bcast = {
  96. .data = { 0x01, 0x13, 0x88, 0x00, 0x01, 0x00 }
  97. };
  98. return bcast;
  99. }
  100. /**
  101. * Clear the contents of the WSS structure - all except kobj, mutex, virtual
  102. *
  103. * We do not want to reinitialize - the internal kobj should not change as
  104. * it still points to the parent received during setup. The mutex should
  105. * remain also. We thus just reset values individually.
  106. * The virutal address assigned to WSS will remain the same for the
  107. * lifetime of the WSS. We only reset the fields that can change during its
  108. * lifetime.
  109. */
  110. void wlp_wss_reset(struct wlp_wss *wss)
  111. {
  112. struct wlp *wlp = container_of(wss, struct wlp, wss);
  113. struct device *dev = &wlp->rc->uwb_dev.dev;
  114. d_fnstart(5, dev, "wss (%p) \n", wss);
  115. memset(&wss->wssid, 0, sizeof(wss->wssid));
  116. wss->hash = 0;
  117. memset(&wss->name[0], 0, sizeof(wss->name));
  118. memset(&wss->bcast, 0, sizeof(wss->bcast));
  119. wss->secure_status = WLP_WSS_UNSECURE;
  120. memset(&wss->master_key[0], 0, sizeof(wss->master_key));
  121. wss->tag = 0;
  122. wss->state = WLP_WSS_STATE_NONE;
  123. d_fnend(5, dev, "wss (%p) \n", wss);
  124. }
  125. /**
  126. * Create sysfs infrastructure for WSS
  127. *
  128. * The WSS is configured to have the interface as parent (see wlp_wss_setup())
  129. * a new sysfs directory that includes wssid as its name is created in the
  130. * interface's sysfs directory. The group of files interacting with WSS are
  131. * created also.
  132. */
  133. static
  134. int wlp_wss_sysfs_add(struct wlp_wss *wss, char *wssid_str)
  135. {
  136. struct wlp *wlp = container_of(wss, struct wlp, wss);
  137. struct device *dev = &wlp->rc->uwb_dev.dev;
  138. int result;
  139. d_fnstart(5, dev, "wss (%p), wssid: %s\n", wss, wssid_str);
  140. result = kobject_set_name(&wss->kobj, "wss-%s", wssid_str);
  141. if (result < 0)
  142. return result;
  143. wss->kobj.ktype = &wss_ktype;
  144. result = kobject_init_and_add(&wss->kobj,
  145. &wss_ktype, wss->kobj.parent, "wlp");
  146. if (result < 0) {
  147. dev_err(dev, "WLP: Cannot register WSS kobject.\n");
  148. goto error_kobject_register;
  149. }
  150. result = sysfs_create_group(&wss->kobj, &wss_attr_group);
  151. if (result < 0) {
  152. dev_err(dev, "WLP: Cannot register WSS attributes: %d\n",
  153. result);
  154. goto error_sysfs_create_group;
  155. }
  156. d_fnend(5, dev, "Completed. result = %d \n", result);
  157. return 0;
  158. error_sysfs_create_group:
  159. kobject_put(&wss->kobj); /* will free name if needed */
  160. return result;
  161. error_kobject_register:
  162. kfree(wss->kobj.name);
  163. wss->kobj.name = NULL;
  164. wss->kobj.ktype = NULL;
  165. return result;
  166. }
  167. /**
  168. * Release WSS
  169. *
  170. * No more references exist to this WSS. We should undo everything that was
  171. * done in wlp_wss_create_activate() except removing the group. The group
  172. * is not removed because an object can be unregistered before the group is
  173. * created. We also undo any additional operations on the WSS after this
  174. * (addition of members).
  175. *
  176. * If memory was allocated for the kobject's name then it will
  177. * be freed by the kobject system during this time.
  178. *
  179. * The EDA cache is removed and reinitilized when the WSS is removed. We
  180. * thus loose knowledge of members of this WSS at that time and need not do
  181. * it here.
  182. */
  183. void wlp_wss_release(struct kobject *kobj)
  184. {
  185. struct wlp_wss *wss = container_of(kobj, struct wlp_wss, kobj);
  186. wlp_wss_reset(wss);
  187. }
  188. /**
  189. * Enroll into a WSS using provided neighbor as registrar
  190. *
  191. * First search the neighborhood information to learn which neighbor is
  192. * referred to, next proceed with enrollment.
  193. *
  194. * &wss->mutex is held
  195. */
  196. static
  197. int wlp_wss_enroll_target(struct wlp_wss *wss, struct wlp_uuid *wssid,
  198. struct uwb_dev_addr *dest)
  199. {
  200. struct wlp *wlp = container_of(wss, struct wlp, wss);
  201. struct device *dev = &wlp->rc->uwb_dev.dev;
  202. struct wlp_neighbor_e *neighbor;
  203. char buf[WLP_WSS_UUID_STRSIZE];
  204. int result = -ENXIO;
  205. struct uwb_dev_addr *dev_addr;
  206. wlp_wss_uuid_print(buf, sizeof(buf), wssid);
  207. d_fnstart(5, dev, "wss %p, wssid %s, registrar %02x:%02x \n",
  208. wss, buf, dest->data[1], dest->data[0]);
  209. mutex_lock(&wlp->nbmutex);
  210. list_for_each_entry(neighbor, &wlp->neighbors, node) {
  211. dev_addr = &neighbor->uwb_dev->dev_addr;
  212. if (!memcmp(dest, dev_addr, sizeof(*dest))) {
  213. d_printf(5, dev, "Neighbor %02x:%02x is valid, "
  214. "enrolling. \n",
  215. dev_addr->data[1], dev_addr->data[0]);
  216. result = wlp_enroll_neighbor(wlp, neighbor, wss,
  217. wssid);
  218. break;
  219. }
  220. }
  221. if (result == -ENXIO)
  222. dev_err(dev, "WLP: Cannot find neighbor %02x:%02x. \n",
  223. dest->data[1], dest->data[0]);
  224. mutex_unlock(&wlp->nbmutex);
  225. d_fnend(5, dev, "wss %p, wssid %s, registrar %02x:%02x, result %d \n",
  226. wss, buf, dest->data[1], dest->data[0], result);
  227. return result;
  228. }
  229. /**
  230. * Enroll into a WSS previously discovered
  231. *
  232. * User provides WSSID of WSS, search for neighbor that has this WSS
  233. * activated and attempt to enroll.
  234. *
  235. * &wss->mutex is held
  236. */
  237. static
  238. int wlp_wss_enroll_discovered(struct wlp_wss *wss, struct wlp_uuid *wssid)
  239. {
  240. struct wlp *wlp = container_of(wss, struct wlp, wss);
  241. struct device *dev = &wlp->rc->uwb_dev.dev;
  242. struct wlp_neighbor_e *neighbor;
  243. struct wlp_wssid_e *wssid_e;
  244. char buf[WLP_WSS_UUID_STRSIZE];
  245. int result = -ENXIO;
  246. wlp_wss_uuid_print(buf, sizeof(buf), wssid);
  247. d_fnstart(5, dev, "wss %p, wssid %s \n", wss, buf);
  248. mutex_lock(&wlp->nbmutex);
  249. list_for_each_entry(neighbor, &wlp->neighbors, node) {
  250. list_for_each_entry(wssid_e, &neighbor->wssid, node) {
  251. if (!memcmp(wssid, &wssid_e->wssid, sizeof(*wssid))) {
  252. d_printf(5, dev, "Found WSSID %s in neighbor "
  253. "%02x:%02x cache. \n", buf,
  254. neighbor->uwb_dev->dev_addr.data[1],
  255. neighbor->uwb_dev->dev_addr.data[0]);
  256. result = wlp_enroll_neighbor(wlp, neighbor,
  257. wss, wssid);
  258. if (result == 0) /* enrollment success */
  259. goto out;
  260. break;
  261. }
  262. }
  263. }
  264. out:
  265. if (result == -ENXIO)
  266. dev_err(dev, "WLP: Cannot find WSSID %s in cache. \n", buf);
  267. mutex_unlock(&wlp->nbmutex);
  268. d_fnend(5, dev, "wss %p, wssid %s, result %d \n", wss, buf, result);
  269. return result;
  270. }
  271. /**
  272. * Enroll into WSS with provided WSSID, registrar may be provided
  273. *
  274. * @wss: out WSS that will be enrolled
  275. * @wssid: wssid of neighboring WSS that we want to enroll in
  276. * @devaddr: registrar can be specified, will be broadcast (ff:ff) if any
  277. * neighbor can be used as registrar.
  278. *
  279. * &wss->mutex is held
  280. */
  281. static
  282. int wlp_wss_enroll(struct wlp_wss *wss, struct wlp_uuid *wssid,
  283. struct uwb_dev_addr *devaddr)
  284. {
  285. int result;
  286. struct wlp *wlp = container_of(wss, struct wlp, wss);
  287. struct device *dev = &wlp->rc->uwb_dev.dev;
  288. char buf[WLP_WSS_UUID_STRSIZE];
  289. struct uwb_dev_addr bcast = {.data = {0xff, 0xff} };
  290. wlp_wss_uuid_print(buf, sizeof(buf), wssid);
  291. if (wss->state != WLP_WSS_STATE_NONE) {
  292. dev_err(dev, "WLP: Already enrolled in WSS %s.\n", buf);
  293. result = -EEXIST;
  294. goto error;
  295. }
  296. if (!memcmp(&bcast, devaddr, sizeof(bcast))) {
  297. d_printf(5, dev, "Request to enroll in discovered WSS "
  298. "with WSSID %s \n", buf);
  299. result = wlp_wss_enroll_discovered(wss, wssid);
  300. } else {
  301. d_printf(5, dev, "Request to enroll in WSSID %s with "
  302. "registrar %02x:%02x\n", buf, devaddr->data[1],
  303. devaddr->data[0]);
  304. result = wlp_wss_enroll_target(wss, wssid, devaddr);
  305. }
  306. if (result < 0) {
  307. dev_err(dev, "WLP: Unable to enroll into WSS %s, result %d \n",
  308. buf, result);
  309. goto error;
  310. }
  311. d_printf(2, dev, "Successfully enrolled into WSS %s \n", buf);
  312. result = wlp_wss_sysfs_add(wss, buf);
  313. if (result < 0) {
  314. dev_err(dev, "WLP: Unable to set up sysfs for WSS kobject.\n");
  315. wlp_wss_reset(wss);
  316. }
  317. error:
  318. return result;
  319. }
  320. /**
  321. * Activate given WSS
  322. *
  323. * Prior to activation a WSS must be enrolled. To activate a WSS a device
  324. * includes the WSS hash in the WLP IE in its beacon in each superframe.
  325. * WLP 0.99 [7.2.5].
  326. *
  327. * The WSS tag is also computed at this time. We only support one activated
  328. * WSS so we can use the hash as a tag - there will never be a conflict.
  329. *
  330. * We currently only support one activated WSS so only one WSS hash is
  331. * included in the WLP IE.
  332. */
  333. static
  334. int wlp_wss_activate(struct wlp_wss *wss)
  335. {
  336. struct wlp *wlp = container_of(wss, struct wlp, wss);
  337. struct device *dev = &wlp->rc->uwb_dev.dev;
  338. struct uwb_rc *uwb_rc = wlp->rc;
  339. int result;
  340. struct {
  341. struct wlp_ie wlp_ie;
  342. u8 hash; /* only include one hash */
  343. } ie_data;
  344. d_fnstart(5, dev, "Activating WSS %p. \n", wss);
  345. BUG_ON(wss->state != WLP_WSS_STATE_ENROLLED);
  346. wss->hash = wlp_wss_comp_wssid_hash(&wss->wssid);
  347. wss->tag = wss->hash;
  348. memset(&ie_data, 0, sizeof(ie_data));
  349. ie_data.wlp_ie.hdr.element_id = UWB_IE_WLP;
  350. ie_data.wlp_ie.hdr.length = sizeof(ie_data) - sizeof(struct uwb_ie_hdr);
  351. wlp_ie_set_hash_length(&ie_data.wlp_ie, sizeof(ie_data.hash));
  352. ie_data.hash = wss->hash;
  353. result = uwb_rc_ie_add(uwb_rc, &ie_data.wlp_ie.hdr,
  354. sizeof(ie_data));
  355. if (result < 0) {
  356. dev_err(dev, "WLP: Unable to add WLP IE to beacon. "
  357. "result = %d.\n", result);
  358. goto error_wlp_ie;
  359. }
  360. wss->state = WLP_WSS_STATE_ACTIVE;
  361. result = 0;
  362. error_wlp_ie:
  363. d_fnend(5, dev, "Activating WSS %p, result = %d \n", wss, result);
  364. return result;
  365. }
  366. /**
  367. * Enroll in and activate WSS identified by provided WSSID
  368. *
  369. * The neighborhood cache should contain a list of all neighbors and the
  370. * WSS they have activated. Based on that cache we search which neighbor we
  371. * can perform the association process with. The user also has option to
  372. * specify which neighbor it prefers as registrar.
  373. * Successful enrollment is followed by activation.
  374. * Successful activation will create the sysfs directory containing
  375. * specific information regarding this WSS.
  376. */
  377. int wlp_wss_enroll_activate(struct wlp_wss *wss, struct wlp_uuid *wssid,
  378. struct uwb_dev_addr *devaddr)
  379. {
  380. struct wlp *wlp = container_of(wss, struct wlp, wss);
  381. struct device *dev = &wlp->rc->uwb_dev.dev;
  382. int result = 0;
  383. char buf[WLP_WSS_UUID_STRSIZE];
  384. d_fnstart(5, dev, "Enrollment and activation requested. \n");
  385. mutex_lock(&wss->mutex);
  386. result = wlp_wss_enroll(wss, wssid, devaddr);
  387. if (result < 0) {
  388. wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
  389. dev_err(dev, "WLP: Enrollment into WSS %s failed.\n", buf);
  390. goto error_enroll;
  391. }
  392. result = wlp_wss_activate(wss);
  393. if (result < 0) {
  394. dev_err(dev, "WLP: Unable to activate WSS. Undoing enrollment "
  395. "result = %d \n", result);
  396. /* Undo enrollment */
  397. wlp_wss_reset(wss);
  398. goto error_activate;
  399. }
  400. error_activate:
  401. error_enroll:
  402. mutex_unlock(&wss->mutex);
  403. d_fnend(5, dev, "Completed. result = %d \n", result);
  404. return result;
  405. }
  406. /**
  407. * Create, enroll, and activate a new WSS
  408. *
  409. * @wssid: new wssid provided by user
  410. * @name: WSS name requested by used.
  411. * @sec_status: security status requested by user
  412. *
  413. * A user requested the creation of a new WSS. All operations are done
  414. * locally. The new WSS will be stored locally, the hash will be included
  415. * in the WLP IE, and the sysfs infrastructure for this WSS will be
  416. * created.
  417. */
  418. int wlp_wss_create_activate(struct wlp_wss *wss, struct wlp_uuid *wssid,
  419. char *name, unsigned sec_status, unsigned accept)
  420. {
  421. struct wlp *wlp = container_of(wss, struct wlp, wss);
  422. struct device *dev = &wlp->rc->uwb_dev.dev;
  423. int result = 0;
  424. char buf[WLP_WSS_UUID_STRSIZE];
  425. d_fnstart(5, dev, "Request to create new WSS.\n");
  426. result = wlp_wss_uuid_print(buf, sizeof(buf), wssid);
  427. d_printf(5, dev, "Request to create WSS: WSSID=%s, name=%s, "
  428. "sec_status=%u, accepting enrollment=%u \n",
  429. buf, name, sec_status, accept);
  430. if (!mutex_trylock(&wss->mutex)) {
  431. dev_err(dev, "WLP: WLP association session in progress.\n");
  432. return -EBUSY;
  433. }
  434. if (wss->state != WLP_WSS_STATE_NONE) {
  435. dev_err(dev, "WLP: WSS already exists. Not creating new.\n");
  436. result = -EEXIST;
  437. goto out;
  438. }
  439. if (wss->kobj.parent == NULL) {
  440. dev_err(dev, "WLP: WSS parent not ready. Is network interface "
  441. "up?\n");
  442. result = -ENXIO;
  443. goto out;
  444. }
  445. if (sec_status == WLP_WSS_SECURE) {
  446. dev_err(dev, "WLP: FIXME Creation of secure WSS not "
  447. "supported yet.\n");
  448. result = -EINVAL;
  449. goto out;
  450. }
  451. wss->wssid = *wssid;
  452. memcpy(wss->name, name, sizeof(wss->name));
  453. wss->bcast = wlp_wss_sel_bcast_addr(wss);
  454. wss->secure_status = sec_status;
  455. wss->accept_enroll = accept;
  456. /*wss->virtual_addr is initialized in call to wlp_wss_setup*/
  457. /* sysfs infrastructure */
  458. result = wlp_wss_sysfs_add(wss, buf);
  459. if (result < 0) {
  460. dev_err(dev, "Cannot set up sysfs for WSS kobject.\n");
  461. wlp_wss_reset(wss);
  462. goto out;
  463. } else
  464. result = 0;
  465. wss->state = WLP_WSS_STATE_ENROLLED;
  466. result = wlp_wss_activate(wss);
  467. if (result < 0) {
  468. dev_err(dev, "WLP: Unable to activate WSS. Undoing "
  469. "enrollment\n");
  470. wlp_wss_reset(wss);
  471. goto out;
  472. }
  473. result = 0;
  474. out:
  475. mutex_unlock(&wss->mutex);
  476. d_fnend(5, dev, "Completed. result = %d \n", result);
  477. return result;
  478. }
  479. /**
  480. * Determine if neighbor has WSS activated
  481. *
  482. * @returns: 1 if neighbor has WSS activated, zero otherwise
  483. *
  484. * This can be done in two ways:
  485. * - send a C1 frame, parse C2/F0 response
  486. * - examine the WLP IE sent by the neighbor
  487. *
  488. * The WLP IE is not fully supported in hardware so we use the C1/C2 frame
  489. * exchange to determine if a WSS is activated. Using the WLP IE should be
  490. * faster and should be used when it becomes possible.
  491. */
  492. int wlp_wss_is_active(struct wlp *wlp, struct wlp_wss *wss,
  493. struct uwb_dev_addr *dev_addr)
  494. {
  495. int result = 0;
  496. struct device *dev = &wlp->rc->uwb_dev.dev;
  497. char buf[WLP_WSS_UUID_STRSIZE];
  498. DECLARE_COMPLETION_ONSTACK(completion);
  499. struct wlp_session session;
  500. struct sk_buff *skb;
  501. struct wlp_frame_assoc *resp;
  502. struct wlp_uuid wssid;
  503. wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
  504. d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
  505. wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
  506. mutex_lock(&wlp->mutex);
  507. /* Send C1 association frame */
  508. result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C1);
  509. if (result < 0) {
  510. dev_err(dev, "Unable to send C1 frame to neighbor "
  511. "%02x:%02x (%d)\n", dev_addr->data[1],
  512. dev_addr->data[0], result);
  513. result = 0;
  514. goto out;
  515. }
  516. /* Create session, wait for response */
  517. session.exp_message = WLP_ASSOC_C2;
  518. session.cb = wlp_session_cb;
  519. session.cb_priv = &completion;
  520. session.neighbor_addr = *dev_addr;
  521. BUG_ON(wlp->session != NULL);
  522. wlp->session = &session;
  523. /* Wait for C2/F0 frame */
  524. result = wait_for_completion_interruptible_timeout(&completion,
  525. WLP_PER_MSG_TIMEOUT * HZ);
  526. if (result == 0) {
  527. dev_err(dev, "Timeout while sending C1 to neighbor "
  528. "%02x:%02x.\n", dev_addr->data[1],
  529. dev_addr->data[0]);
  530. goto out;
  531. }
  532. if (result < 0) {
  533. dev_err(dev, "Unable to send C1 to neighbor %02x:%02x.\n",
  534. dev_addr->data[1], dev_addr->data[0]);
  535. result = 0;
  536. goto out;
  537. }
  538. /* Parse message in session->data: it will be either C2 or F0 */
  539. skb = session.data;
  540. resp = (void *) skb->data;
  541. d_printf(5, dev, "Received response to C1 frame. \n");
  542. d_dump(5, dev, skb->data, skb->len > 72 ? 72 : skb->len);
  543. if (resp->type == WLP_ASSOC_F0) {
  544. result = wlp_parse_f0(wlp, skb);
  545. if (result < 0)
  546. dev_err(dev, "WLP: unable to parse incoming F0 "
  547. "frame from neighbor %02x:%02x.\n",
  548. dev_addr->data[1], dev_addr->data[0]);
  549. result = 0;
  550. goto error_resp_parse;
  551. }
  552. /* WLP version and message type fields have already been parsed */
  553. result = wlp_get_wssid(wlp, (void *)resp + sizeof(*resp), &wssid,
  554. skb->len - sizeof(*resp));
  555. if (result < 0) {
  556. dev_err(dev, "WLP: unable to obtain WSSID from C2 frame.\n");
  557. result = 0;
  558. goto error_resp_parse;
  559. }
  560. if (!memcmp(&wssid, &wss->wssid, sizeof(wssid))) {
  561. d_printf(5, dev, "WSSID in C2 frame matches local "
  562. "active WSS.\n");
  563. result = 1;
  564. } else {
  565. dev_err(dev, "WLP: Received a C2 frame without matching "
  566. "WSSID.\n");
  567. result = 0;
  568. }
  569. error_resp_parse:
  570. kfree_skb(skb);
  571. out:
  572. wlp->session = NULL;
  573. mutex_unlock(&wlp->mutex);
  574. d_fnend(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
  575. wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
  576. return result;
  577. }
  578. /**
  579. * Activate connection with neighbor by updating EDA cache
  580. *
  581. * @wss: local WSS to which neighbor wants to connect
  582. * @dev_addr: neighbor's address
  583. * @wssid: neighbor's WSSID - must be same as our WSS's WSSID
  584. * @tag: neighbor's WSS tag used to identify frames transmitted by it
  585. * @virt_addr: neighbor's virtual EUI-48
  586. */
  587. static
  588. int wlp_wss_activate_connection(struct wlp *wlp, struct wlp_wss *wss,
  589. struct uwb_dev_addr *dev_addr,
  590. struct wlp_uuid *wssid, u8 *tag,
  591. struct uwb_mac_addr *virt_addr)
  592. {
  593. struct device *dev = &wlp->rc->uwb_dev.dev;
  594. int result = 0;
  595. char buf[WLP_WSS_UUID_STRSIZE];
  596. wlp_wss_uuid_print(buf, sizeof(buf), wssid);
  597. d_fnstart(5, dev, "wlp %p, wss %p, wssid %s, tag %u, virtual "
  598. "%02x:%02x:%02x:%02x:%02x:%02x \n", wlp, wss, buf, *tag,
  599. virt_addr->data[0], virt_addr->data[1], virt_addr->data[2],
  600. virt_addr->data[3], virt_addr->data[4], virt_addr->data[5]);
  601. if (!memcmp(wssid, &wss->wssid, sizeof(*wssid))) {
  602. d_printf(5, dev, "WSSID from neighbor frame matches local "
  603. "active WSS.\n");
  604. /* Update EDA cache */
  605. result = wlp_eda_update_node(&wlp->eda, dev_addr, wss,
  606. (void *) virt_addr->data, *tag,
  607. WLP_WSS_CONNECTED);
  608. if (result < 0)
  609. dev_err(dev, "WLP: Unable to update EDA cache "
  610. "with new connected neighbor information.\n");
  611. } else {
  612. dev_err(dev, "WLP: Neighbor does not have matching "
  613. "WSSID.\n");
  614. result = -EINVAL;
  615. }
  616. d_fnend(5, dev, "wlp %p, wss %p, wssid %s, tag %u, virtual "
  617. "%02x:%02x:%02x:%02x:%02x:%02x, result = %d \n",
  618. wlp, wss, buf, *tag,
  619. virt_addr->data[0], virt_addr->data[1], virt_addr->data[2],
  620. virt_addr->data[3], virt_addr->data[4], virt_addr->data[5],
  621. result);
  622. return result;
  623. }
  624. /**
  625. * Connect to WSS neighbor
  626. *
  627. * Use C3/C4 exchange to determine if neighbor has WSS activated and
  628. * retrieve the WSS tag and virtual EUI-48 of the neighbor.
  629. */
  630. static
  631. int wlp_wss_connect_neighbor(struct wlp *wlp, struct wlp_wss *wss,
  632. struct uwb_dev_addr *dev_addr)
  633. {
  634. int result;
  635. struct device *dev = &wlp->rc->uwb_dev.dev;
  636. char buf[WLP_WSS_UUID_STRSIZE];
  637. struct wlp_uuid wssid;
  638. u8 tag;
  639. struct uwb_mac_addr virt_addr;
  640. DECLARE_COMPLETION_ONSTACK(completion);
  641. struct wlp_session session;
  642. struct wlp_frame_assoc *resp;
  643. struct sk_buff *skb;
  644. wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
  645. d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
  646. wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
  647. mutex_lock(&wlp->mutex);
  648. /* Send C3 association frame */
  649. result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C3);
  650. if (result < 0) {
  651. dev_err(dev, "Unable to send C3 frame to neighbor "
  652. "%02x:%02x (%d)\n", dev_addr->data[1],
  653. dev_addr->data[0], result);
  654. goto out;
  655. }
  656. /* Create session, wait for response */
  657. session.exp_message = WLP_ASSOC_C4;
  658. session.cb = wlp_session_cb;
  659. session.cb_priv = &completion;
  660. session.neighbor_addr = *dev_addr;
  661. BUG_ON(wlp->session != NULL);
  662. wlp->session = &session;
  663. /* Wait for C4/F0 frame */
  664. result = wait_for_completion_interruptible_timeout(&completion,
  665. WLP_PER_MSG_TIMEOUT * HZ);
  666. if (result == 0) {
  667. dev_err(dev, "Timeout while sending C3 to neighbor "
  668. "%02x:%02x.\n", dev_addr->data[1],
  669. dev_addr->data[0]);
  670. result = -ETIMEDOUT;
  671. goto out;
  672. }
  673. if (result < 0) {
  674. dev_err(dev, "Unable to send C3 to neighbor %02x:%02x.\n",
  675. dev_addr->data[1], dev_addr->data[0]);
  676. goto out;
  677. }
  678. /* Parse message in session->data: it will be either C4 or F0 */
  679. skb = session.data;
  680. resp = (void *) skb->data;
  681. d_printf(5, dev, "Received response to C3 frame. \n");
  682. d_dump(5, dev, skb->data, skb->len > 72 ? 72 : skb->len);
  683. if (resp->type == WLP_ASSOC_F0) {
  684. result = wlp_parse_f0(wlp, skb);
  685. if (result < 0)
  686. dev_err(dev, "WLP: unable to parse incoming F0 "
  687. "frame from neighbor %02x:%02x.\n",
  688. dev_addr->data[1], dev_addr->data[0]);
  689. result = -EINVAL;
  690. goto error_resp_parse;
  691. }
  692. result = wlp_parse_c3c4_frame(wlp, skb, &wssid, &tag, &virt_addr);
  693. if (result < 0) {
  694. dev_err(dev, "WLP: Unable to parse C4 frame from neighbor.\n");
  695. goto error_resp_parse;
  696. }
  697. result = wlp_wss_activate_connection(wlp, wss, dev_addr, &wssid, &tag,
  698. &virt_addr);
  699. if (result < 0) {
  700. dev_err(dev, "WLP: Unable to activate connection to "
  701. "neighbor %02x:%02x.\n", dev_addr->data[1],
  702. dev_addr->data[0]);
  703. goto error_resp_parse;
  704. }
  705. error_resp_parse:
  706. kfree_skb(skb);
  707. out:
  708. /* Record that we unsuccessfully tried to connect to this neighbor */
  709. if (result < 0)
  710. wlp_eda_update_node_state(&wlp->eda, dev_addr,
  711. WLP_WSS_CONNECT_FAILED);
  712. wlp->session = NULL;
  713. mutex_unlock(&wlp->mutex);
  714. d_fnend(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
  715. wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
  716. return result;
  717. }
  718. /**
  719. * Connect to neighbor with common WSS, send pending frame
  720. *
  721. * This function is scheduled when a frame is destined to a neighbor with
  722. * which we do not have a connection. A copy of the EDA cache entry is
  723. * provided - not the actual cache entry (because it is protected by a
  724. * spinlock).
  725. *
  726. * First determine if neighbor has the same WSS activated, connect if it
  727. * does. The C3/C4 exchange is dual purpose to determine if neighbor has
  728. * WSS activated and proceed with the connection.
  729. *
  730. * The frame that triggered the connection setup is sent after connection
  731. * setup.
  732. *
  733. * network queue is stopped - we need to restart when done
  734. *
  735. */
  736. static
  737. void wlp_wss_connect_send(struct work_struct *ws)
  738. {
  739. struct wlp_assoc_conn_ctx *conn_ctx = container_of(ws,
  740. struct wlp_assoc_conn_ctx,
  741. ws);
  742. struct wlp *wlp = conn_ctx->wlp;
  743. struct sk_buff *skb = conn_ctx->skb;
  744. struct wlp_eda_node *eda_entry = &conn_ctx->eda_entry;
  745. struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;
  746. struct wlp_wss *wss = &wlp->wss;
  747. int result;
  748. struct device *dev = &wlp->rc->uwb_dev.dev;
  749. char buf[WLP_WSS_UUID_STRSIZE];
  750. mutex_lock(&wss->mutex);
  751. wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
  752. d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
  753. wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
  754. if (wss->state < WLP_WSS_STATE_ACTIVE) {
  755. if (printk_ratelimit())
  756. dev_err(dev, "WLP: Attempting to connect with "
  757. "WSS that is not active or connected.\n");
  758. dev_kfree_skb(skb);
  759. goto out;
  760. }
  761. /* Establish connection - send C3 rcv C4 */
  762. result = wlp_wss_connect_neighbor(wlp, wss, dev_addr);
  763. if (result < 0) {
  764. if (printk_ratelimit())
  765. dev_err(dev, "WLP: Unable to establish connection "
  766. "with neighbor %02x:%02x.\n",
  767. dev_addr->data[1], dev_addr->data[0]);
  768. dev_kfree_skb(skb);
  769. goto out;
  770. }
  771. /* EDA entry changed, update the local copy being used */
  772. result = wlp_copy_eda_node(&wlp->eda, dev_addr, eda_entry);
  773. if (result < 0) {
  774. if (printk_ratelimit())
  775. dev_err(dev, "WLP: Cannot find EDA entry for "
  776. "neighbor %02x:%02x \n",
  777. dev_addr->data[1], dev_addr->data[0]);
  778. }
  779. result = wlp_wss_prep_hdr(wlp, eda_entry, skb);
  780. if (result < 0) {
  781. if (printk_ratelimit())
  782. dev_err(dev, "WLP: Unable to prepare frame header for "
  783. "transmission (neighbor %02x:%02x). \n",
  784. dev_addr->data[1], dev_addr->data[0]);
  785. dev_kfree_skb(skb);
  786. goto out;
  787. }
  788. BUG_ON(wlp->xmit_frame == NULL);
  789. result = wlp->xmit_frame(wlp, skb, dev_addr);
  790. if (result < 0) {
  791. if (printk_ratelimit())
  792. dev_err(dev, "WLP: Unable to transmit frame: %d\n",
  793. result);
  794. if (result == -ENXIO)
  795. dev_err(dev, "WLP: Is network interface up? \n");
  796. /* We could try again ... */
  797. dev_kfree_skb(skb);/*we need to free if tx fails */
  798. }
  799. out:
  800. kfree(conn_ctx);
  801. BUG_ON(wlp->start_queue == NULL);
  802. wlp->start_queue(wlp);
  803. mutex_unlock(&wss->mutex);
  804. d_fnend(5, dev, "wlp %p, wss %p (wssid %s)\n", wlp, wss, buf);
  805. }
  806. /**
  807. * Add WLP header to outgoing skb
  808. *
  809. * @eda_entry: pointer to neighbor's entry in the EDA cache
  810. * @_skb: skb containing data destined to the neighbor
  811. */
  812. int wlp_wss_prep_hdr(struct wlp *wlp, struct wlp_eda_node *eda_entry,
  813. void *_skb)
  814. {
  815. struct device *dev = &wlp->rc->uwb_dev.dev;
  816. int result = 0;
  817. unsigned char *eth_addr = eda_entry->eth_addr;
  818. struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;
  819. struct sk_buff *skb = _skb;
  820. struct wlp_frame_std_abbrv_hdr *std_hdr;
  821. d_fnstart(6, dev, "wlp %p \n", wlp);
  822. if (eda_entry->state == WLP_WSS_CONNECTED) {
  823. /* Add WLP header */
  824. BUG_ON(skb_headroom(skb) < sizeof(*std_hdr));
  825. std_hdr = (void *) __skb_push(skb, sizeof(*std_hdr));
  826. std_hdr->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID);
  827. std_hdr->hdr.type = WLP_FRAME_STANDARD;
  828. std_hdr->tag = eda_entry->wss->tag;
  829. } else {
  830. if (printk_ratelimit())
  831. dev_err(dev, "WLP: Destination neighbor (Ethernet: "
  832. "%02x:%02x:%02x:%02x:%02x:%02x, Dev: "
  833. "%02x:%02x) is not connected. \n", eth_addr[0],
  834. eth_addr[1], eth_addr[2], eth_addr[3],
  835. eth_addr[4], eth_addr[5], dev_addr->data[1],
  836. dev_addr->data[0]);
  837. result = -EINVAL;
  838. }
  839. d_fnend(6, dev, "wlp %p \n", wlp);
  840. return result;
  841. }
  842. /**
  843. * Prepare skb for neighbor: connect if not already and prep WLP header
  844. *
  845. * This function is called in interrupt context, but it needs to sleep. We
  846. * temporarily stop the net queue to establish the WLP connection.
  847. * Setup of the WLP connection and restart of queue is scheduled
  848. * on the default work queue.
  849. *
  850. * run with eda->lock held (spinlock)
  851. */
  852. int wlp_wss_connect_prep(struct wlp *wlp, struct wlp_eda_node *eda_entry,
  853. void *_skb)
  854. {
  855. int result = 0;
  856. struct device *dev = &wlp->rc->uwb_dev.dev;
  857. struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;
  858. unsigned char *eth_addr = eda_entry->eth_addr;
  859. struct sk_buff *skb = _skb;
  860. struct wlp_assoc_conn_ctx *conn_ctx;
  861. d_fnstart(5, dev, "wlp %p\n", wlp);
  862. d_printf(5, dev, "To neighbor %02x:%02x with eth "
  863. "%02x:%02x:%02x:%02x:%02x:%02x\n", dev_addr->data[1],
  864. dev_addr->data[0], eth_addr[0], eth_addr[1], eth_addr[2],
  865. eth_addr[3], eth_addr[4], eth_addr[5]);
  866. if (eda_entry->state == WLP_WSS_UNCONNECTED) {
  867. /* We don't want any more packets while we set up connection */
  868. BUG_ON(wlp->stop_queue == NULL);
  869. wlp->stop_queue(wlp);
  870. conn_ctx = kmalloc(sizeof(*conn_ctx), GFP_ATOMIC);
  871. if (conn_ctx == NULL) {
  872. if (printk_ratelimit())
  873. dev_err(dev, "WLP: Unable to allocate memory "
  874. "for connection handling.\n");
  875. result = -ENOMEM;
  876. goto out;
  877. }
  878. conn_ctx->wlp = wlp;
  879. conn_ctx->skb = skb;
  880. conn_ctx->eda_entry = *eda_entry;
  881. INIT_WORK(&conn_ctx->ws, wlp_wss_connect_send);
  882. schedule_work(&conn_ctx->ws);
  883. result = 1;
  884. } else if (eda_entry->state == WLP_WSS_CONNECT_FAILED) {
  885. /* Previous connection attempts failed, don't retry - see
  886. * conditions for connection in WLP 0.99 [7.6.2] */
  887. if (printk_ratelimit())
  888. dev_err(dev, "Could not connect to neighbor "
  889. "previously. Not retrying. \n");
  890. result = -ENONET;
  891. goto out;
  892. } else { /* eda_entry->state == WLP_WSS_CONNECTED */
  893. d_printf(5, dev, "Neighbor is connected, preparing frame.\n");
  894. result = wlp_wss_prep_hdr(wlp, eda_entry, skb);
  895. }
  896. out:
  897. d_fnend(5, dev, "wlp %p, result = %d \n", wlp, result);
  898. return result;
  899. }
  900. /**
  901. * Emulate broadcast: copy skb, send copy to neighbor (connect if not already)
  902. *
  903. * We need to copy skbs in the case where we emulate broadcast through
  904. * unicast. We copy instead of clone because we are modifying the data of
  905. * the frame after copying ... clones share data so we cannot emulate
  906. * broadcast using clones.
  907. *
  908. * run with eda->lock held (spinlock)
  909. */
  910. int wlp_wss_send_copy(struct wlp *wlp, struct wlp_eda_node *eda_entry,
  911. void *_skb)
  912. {
  913. int result = -ENOMEM;
  914. struct device *dev = &wlp->rc->uwb_dev.dev;
  915. struct sk_buff *skb = _skb;
  916. struct sk_buff *copy;
  917. struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;
  918. d_fnstart(5, dev, "to neighbor %02x:%02x, skb (%p) \n",
  919. dev_addr->data[1], dev_addr->data[0], skb);
  920. copy = skb_copy(skb, GFP_ATOMIC);
  921. if (copy == NULL) {
  922. if (printk_ratelimit())
  923. dev_err(dev, "WLP: Unable to copy skb for "
  924. "transmission.\n");
  925. goto out;
  926. }
  927. result = wlp_wss_connect_prep(wlp, eda_entry, copy);
  928. if (result < 0) {
  929. if (printk_ratelimit())
  930. dev_err(dev, "WLP: Unable to connect/send skb "
  931. "to neighbor.\n");
  932. dev_kfree_skb_irq(copy);
  933. goto out;
  934. } else if (result == 1)
  935. /* Frame will be transmitted separately */
  936. goto out;
  937. BUG_ON(wlp->xmit_frame == NULL);
  938. result = wlp->xmit_frame(wlp, copy, dev_addr);
  939. if (result < 0) {
  940. if (printk_ratelimit())
  941. dev_err(dev, "WLP: Unable to transmit frame: %d\n",
  942. result);
  943. if ((result == -ENXIO) && printk_ratelimit())
  944. dev_err(dev, "WLP: Is network interface up? \n");
  945. /* We could try again ... */
  946. dev_kfree_skb_irq(copy);/*we need to free if tx fails */
  947. }
  948. out:
  949. d_fnend(5, dev, "to neighbor %02x:%02x \n", dev_addr->data[1],
  950. dev_addr->data[0]);
  951. return result;
  952. }
  953. /**
  954. * Setup WSS
  955. *
  956. * Should be called by network driver after the interface has been given a
  957. * MAC address.
  958. */
  959. int wlp_wss_setup(struct net_device *net_dev, struct wlp_wss *wss)
  960. {
  961. struct wlp *wlp = container_of(wss, struct wlp, wss);
  962. struct device *dev = &wlp->rc->uwb_dev.dev;
  963. int result = 0;
  964. d_fnstart(5, dev, "wss (%p) \n", wss);
  965. mutex_lock(&wss->mutex);
  966. wss->kobj.parent = &net_dev->dev.kobj;
  967. if (!is_valid_ether_addr(net_dev->dev_addr)) {
  968. dev_err(dev, "WLP: Invalid MAC address. Cannot use for"
  969. "virtual.\n");
  970. result = -EINVAL;
  971. goto out;
  972. }
  973. memcpy(wss->virtual_addr.data, net_dev->dev_addr,
  974. sizeof(wss->virtual_addr.data));
  975. out:
  976. mutex_unlock(&wss->mutex);
  977. d_fnend(5, dev, "wss (%p) \n", wss);
  978. return result;
  979. }
  980. EXPORT_SYMBOL_GPL(wlp_wss_setup);
  981. /**
  982. * Remove WSS
  983. *
  984. * Called by client that configured WSS through wlp_wss_setup(). This
  985. * function is called when client no longer needs WSS, eg. client shuts
  986. * down.
  987. *
  988. * We remove the WLP IE from the beacon before initiating local cleanup.
  989. */
  990. void wlp_wss_remove(struct wlp_wss *wss)
  991. {
  992. struct wlp *wlp = container_of(wss, struct wlp, wss);
  993. struct device *dev = &wlp->rc->uwb_dev.dev;
  994. d_fnstart(5, dev, "wss (%p) \n", wss);
  995. mutex_lock(&wss->mutex);
  996. if (wss->state == WLP_WSS_STATE_ACTIVE)
  997. uwb_rc_ie_rm(wlp->rc, UWB_IE_WLP);
  998. if (wss->state != WLP_WSS_STATE_NONE) {
  999. sysfs_remove_group(&wss->kobj, &wss_attr_group);
  1000. kobject_put(&wss->kobj);
  1001. }
  1002. wss->kobj.parent = NULL;
  1003. memset(&wss->virtual_addr, 0, sizeof(wss->virtual_addr));
  1004. /* Cleanup EDA cache */
  1005. wlp_eda_release(&wlp->eda);
  1006. wlp_eda_init(&wlp->eda);
  1007. mutex_unlock(&wss->mutex);
  1008. d_fnend(5, dev, "wss (%p) \n", wss);
  1009. }
  1010. EXPORT_SYMBOL_GPL(wlp_wss_remove);