irlan_common.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200
  1. /*********************************************************************
  2. *
  3. * Filename: irlan_common.c
  4. * Version: 0.9
  5. * Description: IrDA LAN Access Protocol Implementation
  6. * Status: Experimental.
  7. * Author: Dag Brattli <dagb@cs.uit.no>
  8. * Created at: Sun Aug 31 20:14:37 1997
  9. * Modified at: Sun Dec 26 21:53:10 1999
  10. * Modified by: Dag Brattli <dagb@cs.uit.no>
  11. *
  12. * Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>,
  13. * All Rights Reserved.
  14. *
  15. * This program is free software; you can redistribute it and/or
  16. * modify it under the terms of the GNU General Public License as
  17. * published by the Free Software Foundation; either version 2 of
  18. * the License, or (at your option) any later version.
  19. *
  20. * Neither Dag Brattli nor University of Tromsø admit liability nor
  21. * provide warranty for any of this software. This material is
  22. * provided "AS-IS" and at no charge.
  23. *
  24. ********************************************************************/
  25. #include <linux/config.h>
  26. #include <linux/module.h>
  27. #include <linux/kernel.h>
  28. #include <linux/string.h>
  29. #include <linux/init.h>
  30. #include <linux/errno.h>
  31. #include <linux/proc_fs.h>
  32. #include <linux/seq_file.h>
  33. #include <linux/random.h>
  34. #include <linux/netdevice.h>
  35. #include <linux/etherdevice.h>
  36. #include <linux/rtnetlink.h>
  37. #include <linux/moduleparam.h>
  38. #include <linux/bitops.h>
  39. #include <asm/system.h>
  40. #include <asm/byteorder.h>
  41. #include <net/irda/irda.h>
  42. #include <net/irda/irttp.h>
  43. #include <net/irda/irlmp.h>
  44. #include <net/irda/iriap.h>
  45. #include <net/irda/timer.h>
  46. #include <net/irda/irlan_common.h>
  47. #include <net/irda/irlan_client.h>
  48. #include <net/irda/irlan_provider.h>
  49. #include <net/irda/irlan_eth.h>
  50. #include <net/irda/irlan_filter.h>
  51. /*
  52. * Send gratuitous ARP when connected to a new AP or not. May be a clever
  53. * thing to do, but for some reason the machine crashes if you use DHCP. So
  54. * lets not use it by default.
  55. */
  56. #undef CONFIG_IRLAN_SEND_GRATUITOUS_ARP
  57. /* extern char sysctl_devname[]; */
  58. /*
  59. * Master structure
  60. */
  61. static LIST_HEAD(irlans);
  62. static void *ckey;
  63. static void *skey;
  64. /* Module parameters */
  65. static int eth; /* Use "eth" or "irlan" name for devices */
  66. static int access = ACCESS_PEER; /* PEER, DIRECT or HOSTED */
  67. #ifdef CONFIG_PROC_FS
  68. static const char *irlan_access[] = {
  69. "UNKNOWN",
  70. "DIRECT",
  71. "PEER",
  72. "HOSTED"
  73. };
  74. static const char *irlan_media[] = {
  75. "UNKNOWN",
  76. "802.3",
  77. "802.5"
  78. };
  79. extern struct proc_dir_entry *proc_irda;
  80. static int irlan_seq_open(struct inode *inode, struct file *file);
  81. static struct file_operations irlan_fops = {
  82. .owner = THIS_MODULE,
  83. .open = irlan_seq_open,
  84. .read = seq_read,
  85. .llseek = seq_lseek,
  86. .release = seq_release,
  87. };
  88. extern struct proc_dir_entry *proc_irda;
  89. #endif /* CONFIG_PROC_FS */
  90. static struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr);
  91. static void __irlan_close(struct irlan_cb *self);
  92. static int __irlan_insert_param(struct sk_buff *skb, char *param, int type,
  93. __u8 value_byte, __u16 value_short,
  94. __u8 *value_array, __u16 value_len);
  95. static void irlan_open_unicast_addr(struct irlan_cb *self);
  96. static void irlan_get_unicast_addr(struct irlan_cb *self);
  97. void irlan_close_tsaps(struct irlan_cb *self);
  98. /*
  99. * Function irlan_init (void)
  100. *
  101. * Initialize IrLAN layer
  102. *
  103. */
  104. static int __init irlan_init(void)
  105. {
  106. struct irlan_cb *new;
  107. __u16 hints;
  108. IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
  109. #ifdef CONFIG_PROC_FS
  110. { struct proc_dir_entry *proc;
  111. proc = create_proc_entry("irlan", 0, proc_irda);
  112. if (!proc) {
  113. printk(KERN_ERR "irlan_init: can't create /proc entry!\n");
  114. return -ENODEV;
  115. }
  116. proc->proc_fops = &irlan_fops;
  117. }
  118. #endif /* CONFIG_PROC_FS */
  119. IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
  120. hints = irlmp_service_to_hint(S_LAN);
  121. /* Register with IrLMP as a client */
  122. ckey = irlmp_register_client(hints, &irlan_client_discovery_indication,
  123. NULL, NULL);
  124. /* Register with IrLMP as a service */
  125. skey = irlmp_register_service(hints);
  126. /* Start the master IrLAN instance (the only one for now) */
  127. new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY);
  128. /* The master will only open its (listen) control TSAP */
  129. irlan_provider_open_ctrl_tsap(new);
  130. /* Do some fast discovery! */
  131. irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);
  132. return 0;
  133. }
  134. static void __exit irlan_cleanup(void)
  135. {
  136. struct irlan_cb *self, *next;
  137. IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
  138. irlmp_unregister_client(ckey);
  139. irlmp_unregister_service(skey);
  140. #ifdef CONFIG_PROC_FS
  141. remove_proc_entry("irlan", proc_irda);
  142. #endif /* CONFIG_PROC_FS */
  143. /* Cleanup any leftover network devices */
  144. rtnl_lock();
  145. list_for_each_entry_safe(self, next, &irlans, dev_list) {
  146. __irlan_close(self);
  147. }
  148. rtnl_unlock();
  149. }
  150. /*
  151. * Function irlan_open (void)
  152. *
  153. * Open new instance of a client/provider, we should only register the
  154. * network device if this instance is ment for a particular client/provider
  155. */
  156. static struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr)
  157. {
  158. struct net_device *dev;
  159. struct irlan_cb *self;
  160. IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
  161. /* Create network device with irlan */
  162. dev = alloc_irlandev(eth ? "eth%d" : "irlan%d");
  163. if (!dev)
  164. return NULL;
  165. self = dev->priv;
  166. self->dev = dev;
  167. /*
  168. * Initialize local device structure
  169. */
  170. self->magic = IRLAN_MAGIC;
  171. self->saddr = saddr;
  172. self->daddr = daddr;
  173. /* Provider access can only be PEER, DIRECT, or HOSTED */
  174. self->provider.access_type = access;
  175. if (access == ACCESS_DIRECT) {
  176. /*
  177. * Since we are emulating an IrLAN sever we will have to
  178. * give ourself an ethernet address!
  179. */
  180. dev->dev_addr[0] = 0x40;
  181. dev->dev_addr[1] = 0x00;
  182. dev->dev_addr[2] = 0x00;
  183. dev->dev_addr[3] = 0x00;
  184. get_random_bytes(dev->dev_addr+4, 1);
  185. get_random_bytes(dev->dev_addr+5, 1);
  186. }
  187. self->media = MEDIA_802_3;
  188. self->disconnect_reason = LM_USER_REQUEST;
  189. init_timer(&self->watchdog_timer);
  190. init_timer(&self->client.kick_timer);
  191. init_waitqueue_head(&self->open_wait);
  192. skb_queue_head_init(&self->client.txq);
  193. irlan_next_client_state(self, IRLAN_IDLE);
  194. irlan_next_provider_state(self, IRLAN_IDLE);
  195. if (register_netdev(dev)) {
  196. IRDA_DEBUG(2, "%s(), register_netdev() failed!\n",
  197. __FUNCTION__ );
  198. self = NULL;
  199. free_netdev(dev);
  200. } else {
  201. rtnl_lock();
  202. list_add_rcu(&self->dev_list, &irlans);
  203. rtnl_unlock();
  204. }
  205. return self;
  206. }
  207. /*
  208. * Function __irlan_close (self)
  209. *
  210. * This function closes and deallocates the IrLAN client instances. Be
  211. * aware that other functions which calls client_close() must
  212. * remove self from irlans list first.
  213. */
  214. static void __irlan_close(struct irlan_cb *self)
  215. {
  216. IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
  217. ASSERT_RTNL();
  218. IRDA_ASSERT(self != NULL, return;);
  219. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  220. del_timer_sync(&self->watchdog_timer);
  221. del_timer_sync(&self->client.kick_timer);
  222. /* Close all open connections and remove TSAPs */
  223. irlan_close_tsaps(self);
  224. if (self->client.iriap)
  225. iriap_close(self->client.iriap);
  226. /* Remove frames queued on the control channel */
  227. skb_queue_purge(&self->client.txq);
  228. /* Unregister and free self via destructor */
  229. unregister_netdevice(self->dev);
  230. }
  231. /* Find any instance of irlan, used for client discovery wakeup */
  232. struct irlan_cb *irlan_get_any(void)
  233. {
  234. struct irlan_cb *self;
  235. list_for_each_entry_rcu(self, &irlans, dev_list) {
  236. return self;
  237. }
  238. return NULL;
  239. }
  240. /*
  241. * Function irlan_connect_indication (instance, sap, qos, max_sdu_size, skb)
  242. *
  243. * Here we receive the connect indication for the data channel
  244. *
  245. */
  246. static void irlan_connect_indication(void *instance, void *sap,
  247. struct qos_info *qos,
  248. __u32 max_sdu_size,
  249. __u8 max_header_size,
  250. struct sk_buff *skb)
  251. {
  252. struct irlan_cb *self;
  253. struct tsap_cb *tsap;
  254. IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
  255. self = (struct irlan_cb *) instance;
  256. tsap = (struct tsap_cb *) sap;
  257. IRDA_ASSERT(self != NULL, return;);
  258. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  259. IRDA_ASSERT(tsap == self->tsap_data,return;);
  260. self->max_sdu_size = max_sdu_size;
  261. self->max_header_size = max_header_size;
  262. IRDA_DEBUG(0, "%s: We are now connected!\n", __FUNCTION__);
  263. del_timer(&self->watchdog_timer);
  264. /* If you want to pass the skb to *both* state machines, you will
  265. * need to skb_clone() it, so that you don't free it twice.
  266. * As the state machines don't need it, git rid of it here...
  267. * Jean II */
  268. if (skb)
  269. dev_kfree_skb(skb);
  270. irlan_do_provider_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL);
  271. irlan_do_client_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL);
  272. if (self->provider.access_type == ACCESS_PEER) {
  273. /*
  274. * Data channel is open, so we are now allowed to
  275. * configure the remote filter
  276. */
  277. irlan_get_unicast_addr(self);
  278. irlan_open_unicast_addr(self);
  279. }
  280. /* Ready to transfer Ethernet frames (at last) */
  281. netif_start_queue(self->dev); /* Clear reason */
  282. }
  283. static void irlan_connect_confirm(void *instance, void *sap,
  284. struct qos_info *qos,
  285. __u32 max_sdu_size,
  286. __u8 max_header_size,
  287. struct sk_buff *skb)
  288. {
  289. struct irlan_cb *self;
  290. self = (struct irlan_cb *) instance;
  291. IRDA_ASSERT(self != NULL, return;);
  292. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  293. self->max_sdu_size = max_sdu_size;
  294. self->max_header_size = max_header_size;
  295. /* TODO: we could set the MTU depending on the max_sdu_size */
  296. IRDA_DEBUG(0, "%s: We are now connected!\n", __FUNCTION__);
  297. del_timer(&self->watchdog_timer);
  298. /*
  299. * Data channel is open, so we are now allowed to configure the remote
  300. * filter
  301. */
  302. irlan_get_unicast_addr(self);
  303. irlan_open_unicast_addr(self);
  304. /* Open broadcast and multicast filter by default */
  305. irlan_set_broadcast_filter(self, TRUE);
  306. irlan_set_multicast_filter(self, TRUE);
  307. /* Ready to transfer Ethernet frames */
  308. netif_start_queue(self->dev);
  309. self->disconnect_reason = 0; /* Clear reason */
  310. #ifdef CONFIG_IRLAN_SEND_GRATUITOUS_ARP
  311. irlan_eth_send_gratuitous_arp(&self->dev);
  312. #endif
  313. wake_up_interruptible(&self->open_wait);
  314. }
  315. /*
  316. * Function irlan_client_disconnect_indication (handle)
  317. *
  318. * Callback function for the IrTTP layer. Indicates a disconnection of
  319. * the specified connection (handle)
  320. */
  321. static void irlan_disconnect_indication(void *instance,
  322. void *sap, LM_REASON reason,
  323. struct sk_buff *userdata)
  324. {
  325. struct irlan_cb *self;
  326. struct tsap_cb *tsap;
  327. IRDA_DEBUG(0, "%s(), reason=%d\n", __FUNCTION__ , reason);
  328. self = (struct irlan_cb *) instance;
  329. tsap = (struct tsap_cb *) sap;
  330. IRDA_ASSERT(self != NULL, return;);
  331. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  332. IRDA_ASSERT(tsap != NULL, return;);
  333. IRDA_ASSERT(tsap->magic == TTP_TSAP_MAGIC, return;);
  334. IRDA_ASSERT(tsap == self->tsap_data, return;);
  335. IRDA_DEBUG(2, "IrLAN, data channel disconnected by peer!\n");
  336. /* Save reason so we know if we should try to reconnect or not */
  337. self->disconnect_reason = reason;
  338. switch (reason) {
  339. case LM_USER_REQUEST: /* User request */
  340. IRDA_DEBUG(2, "%s(), User requested\n", __FUNCTION__ );
  341. break;
  342. case LM_LAP_DISCONNECT: /* Unexpected IrLAP disconnect */
  343. IRDA_DEBUG(2, "%s(), Unexpected IrLAP disconnect\n", __FUNCTION__ );
  344. break;
  345. case LM_CONNECT_FAILURE: /* Failed to establish IrLAP connection */
  346. IRDA_DEBUG(2, "%s(), IrLAP connect failed\n", __FUNCTION__ );
  347. break;
  348. case LM_LAP_RESET: /* IrLAP reset */
  349. IRDA_DEBUG(2, "%s(), IrLAP reset\n", __FUNCTION__ );
  350. break;
  351. case LM_INIT_DISCONNECT:
  352. IRDA_DEBUG(2, "%s(), IrLMP connect failed\n", __FUNCTION__ );
  353. break;
  354. default:
  355. IRDA_ERROR("%s(), Unknown disconnect reason\n", __FUNCTION__);
  356. break;
  357. }
  358. /* If you want to pass the skb to *both* state machines, you will
  359. * need to skb_clone() it, so that you don't free it twice.
  360. * As the state machines don't need it, git rid of it here...
  361. * Jean II */
  362. if (userdata)
  363. dev_kfree_skb(userdata);
  364. irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
  365. irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);
  366. wake_up_interruptible(&self->open_wait);
  367. }
  368. void irlan_open_data_tsap(struct irlan_cb *self)
  369. {
  370. struct tsap_cb *tsap;
  371. notify_t notify;
  372. IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
  373. IRDA_ASSERT(self != NULL, return;);
  374. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  375. /* Check if already open */
  376. if (self->tsap_data)
  377. return;
  378. irda_notify_init(&notify);
  379. notify.data_indication = irlan_eth_receive;
  380. notify.udata_indication = irlan_eth_receive;
  381. notify.connect_indication = irlan_connect_indication;
  382. notify.connect_confirm = irlan_connect_confirm;
  383. notify.flow_indication = irlan_eth_flow_indication;
  384. notify.disconnect_indication = irlan_disconnect_indication;
  385. notify.instance = self;
  386. strlcpy(notify.name, "IrLAN data", sizeof(notify.name));
  387. tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, &notify);
  388. if (!tsap) {
  389. IRDA_DEBUG(2, "%s(), Got no tsap!\n", __FUNCTION__ );
  390. return;
  391. }
  392. self->tsap_data = tsap;
  393. /*
  394. * This is the data TSAP selector which we will pass to the client
  395. * when the client ask for it.
  396. */
  397. self->stsap_sel_data = self->tsap_data->stsap_sel;
  398. }
  399. void irlan_close_tsaps(struct irlan_cb *self)
  400. {
  401. IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
  402. IRDA_ASSERT(self != NULL, return;);
  403. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  404. /* Disconnect and close all open TSAP connections */
  405. if (self->tsap_data) {
  406. irttp_disconnect_request(self->tsap_data, NULL, P_NORMAL);
  407. irttp_close_tsap(self->tsap_data);
  408. self->tsap_data = NULL;
  409. }
  410. if (self->client.tsap_ctrl) {
  411. irttp_disconnect_request(self->client.tsap_ctrl, NULL,
  412. P_NORMAL);
  413. irttp_close_tsap(self->client.tsap_ctrl);
  414. self->client.tsap_ctrl = NULL;
  415. }
  416. if (self->provider.tsap_ctrl) {
  417. irttp_disconnect_request(self->provider.tsap_ctrl, NULL,
  418. P_NORMAL);
  419. irttp_close_tsap(self->provider.tsap_ctrl);
  420. self->provider.tsap_ctrl = NULL;
  421. }
  422. self->disconnect_reason = LM_USER_REQUEST;
  423. }
  424. /*
  425. * Function irlan_ias_register (self, tsap_sel)
  426. *
  427. * Register with LM-IAS
  428. *
  429. */
  430. void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel)
  431. {
  432. struct ias_object *obj;
  433. struct ias_value *new_value;
  434. IRDA_ASSERT(self != NULL, return;);
  435. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  436. /*
  437. * Check if object has already been registered by a previous provider.
  438. * If that is the case, we just change the value of the attribute
  439. */
  440. if (!irias_find_object("IrLAN")) {
  441. obj = irias_new_object("IrLAN", IAS_IRLAN_ID);
  442. irias_add_integer_attrib(obj, "IrDA:TinyTP:LsapSel", tsap_sel,
  443. IAS_KERNEL_ATTR);
  444. irias_insert_object(obj);
  445. } else {
  446. new_value = irias_new_integer_value(tsap_sel);
  447. irias_object_change_attribute("IrLAN", "IrDA:TinyTP:LsapSel",
  448. new_value);
  449. }
  450. /* Register PnP object only if not registered before */
  451. if (!irias_find_object("PnP")) {
  452. obj = irias_new_object("PnP", IAS_PNP_ID);
  453. #if 0
  454. irias_add_string_attrib(obj, "Name", sysctl_devname,
  455. IAS_KERNEL_ATTR);
  456. #else
  457. irias_add_string_attrib(obj, "Name", "Linux", IAS_KERNEL_ATTR);
  458. #endif
  459. irias_add_string_attrib(obj, "DeviceID", "HWP19F0",
  460. IAS_KERNEL_ATTR);
  461. irias_add_integer_attrib(obj, "CompCnt", 1, IAS_KERNEL_ATTR);
  462. if (self->provider.access_type == ACCESS_PEER)
  463. irias_add_string_attrib(obj, "Comp#01", "PNP8389",
  464. IAS_KERNEL_ATTR);
  465. else
  466. irias_add_string_attrib(obj, "Comp#01", "PNP8294",
  467. IAS_KERNEL_ATTR);
  468. irias_add_string_attrib(obj, "Manufacturer",
  469. "Linux-IrDA Project", IAS_KERNEL_ATTR);
  470. irias_insert_object(obj);
  471. }
  472. }
  473. /*
  474. * Function irlan_run_ctrl_tx_queue (self)
  475. *
  476. * Try to send the next command in the control transmit queue
  477. *
  478. */
  479. int irlan_run_ctrl_tx_queue(struct irlan_cb *self)
  480. {
  481. struct sk_buff *skb;
  482. IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
  483. if (irda_lock(&self->client.tx_busy) == FALSE)
  484. return -EBUSY;
  485. skb = skb_dequeue(&self->client.txq);
  486. if (!skb) {
  487. self->client.tx_busy = FALSE;
  488. return 0;
  489. }
  490. /* Check that it's really possible to send commands */
  491. if ((self->client.tsap_ctrl == NULL) ||
  492. (self->client.state == IRLAN_IDLE))
  493. {
  494. self->client.tx_busy = FALSE;
  495. dev_kfree_skb(skb);
  496. return -1;
  497. }
  498. IRDA_DEBUG(2, "%s(), sending ...\n", __FUNCTION__ );
  499. return irttp_data_request(self->client.tsap_ctrl, skb);
  500. }
  501. /*
  502. * Function irlan_ctrl_data_request (self, skb)
  503. *
  504. * This function makes sure that commands on the control channel is being
  505. * sent in a command/response fashion
  506. */
  507. static void irlan_ctrl_data_request(struct irlan_cb *self, struct sk_buff *skb)
  508. {
  509. IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
  510. /* Queue command */
  511. skb_queue_tail(&self->client.txq, skb);
  512. /* Try to send command */
  513. irlan_run_ctrl_tx_queue(self);
  514. }
  515. /*
  516. * Function irlan_get_provider_info (self)
  517. *
  518. * Send Get Provider Information command to peer IrLAN layer
  519. *
  520. */
  521. void irlan_get_provider_info(struct irlan_cb *self)
  522. {
  523. struct sk_buff *skb;
  524. __u8 *frame;
  525. IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
  526. IRDA_ASSERT(self != NULL, return;);
  527. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  528. skb = dev_alloc_skb(64);
  529. if (!skb)
  530. return;
  531. /* Reserve space for TTP, LMP, and LAP header */
  532. skb_reserve(skb, self->client.max_header_size);
  533. skb_put(skb, 2);
  534. frame = skb->data;
  535. frame[0] = CMD_GET_PROVIDER_INFO;
  536. frame[1] = 0x00; /* Zero parameters */
  537. irlan_ctrl_data_request(self, skb);
  538. }
  539. /*
  540. * Function irlan_open_data_channel (self)
  541. *
  542. * Send an Open Data Command to provider
  543. *
  544. */
  545. void irlan_open_data_channel(struct irlan_cb *self)
  546. {
  547. struct sk_buff *skb;
  548. __u8 *frame;
  549. IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
  550. IRDA_ASSERT(self != NULL, return;);
  551. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  552. skb = dev_alloc_skb(64);
  553. if (!skb)
  554. return;
  555. skb_reserve(skb, self->client.max_header_size);
  556. skb_put(skb, 2);
  557. frame = skb->data;
  558. /* Build frame */
  559. frame[0] = CMD_OPEN_DATA_CHANNEL;
  560. frame[1] = 0x02; /* Two parameters */
  561. irlan_insert_string_param(skb, "MEDIA", "802.3");
  562. irlan_insert_string_param(skb, "ACCESS_TYPE", "DIRECT");
  563. /* irlan_insert_string_param(skb, "MODE", "UNRELIABLE"); */
  564. /* self->use_udata = TRUE; */
  565. irlan_ctrl_data_request(self, skb);
  566. }
  567. void irlan_close_data_channel(struct irlan_cb *self)
  568. {
  569. struct sk_buff *skb;
  570. __u8 *frame;
  571. IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
  572. IRDA_ASSERT(self != NULL, return;);
  573. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  574. /* Check if the TSAP is still there */
  575. if (self->client.tsap_ctrl == NULL)
  576. return;
  577. skb = dev_alloc_skb(64);
  578. if (!skb)
  579. return;
  580. skb_reserve(skb, self->client.max_header_size);
  581. skb_put(skb, 2);
  582. frame = skb->data;
  583. /* Build frame */
  584. frame[0] = CMD_CLOSE_DATA_CHAN;
  585. frame[1] = 0x01; /* Two parameters */
  586. irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
  587. irlan_ctrl_data_request(self, skb);
  588. }
  589. /*
  590. * Function irlan_open_unicast_addr (self)
  591. *
  592. * Make IrLAN provider accept ethernet frames addressed to the unicast
  593. * address.
  594. *
  595. */
  596. static void irlan_open_unicast_addr(struct irlan_cb *self)
  597. {
  598. struct sk_buff *skb;
  599. __u8 *frame;
  600. IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
  601. IRDA_ASSERT(self != NULL, return;);
  602. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  603. skb = dev_alloc_skb(128);
  604. if (!skb)
  605. return;
  606. /* Reserve space for TTP, LMP, and LAP header */
  607. skb_reserve(skb, self->max_header_size);
  608. skb_put(skb, 2);
  609. frame = skb->data;
  610. frame[0] = CMD_FILTER_OPERATION;
  611. frame[1] = 0x03; /* Three parameters */
  612. irlan_insert_byte_param(skb, "DATA_CHAN" , self->dtsap_sel_data);
  613. irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
  614. irlan_insert_string_param(skb, "FILTER_MODE", "FILTER");
  615. irlan_ctrl_data_request(self, skb);
  616. }
  617. /*
  618. * Function irlan_set_broadcast_filter (self, status)
  619. *
  620. * Make IrLAN provider accept ethernet frames addressed to the broadcast
  621. * address. Be careful with the use of this one, since there may be a lot
  622. * of broadcast traffic out there. We can still function without this
  623. * one but then _we_ have to initiate all communication with other
  624. * hosts, since ARP request for this host will not be answered.
  625. */
  626. void irlan_set_broadcast_filter(struct irlan_cb *self, int status)
  627. {
  628. struct sk_buff *skb;
  629. __u8 *frame;
  630. IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
  631. IRDA_ASSERT(self != NULL, return;);
  632. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  633. skb = dev_alloc_skb(128);
  634. if (!skb)
  635. return;
  636. /* Reserve space for TTP, LMP, and LAP header */
  637. skb_reserve(skb, self->client.max_header_size);
  638. skb_put(skb, 2);
  639. frame = skb->data;
  640. frame[0] = CMD_FILTER_OPERATION;
  641. frame[1] = 0x03; /* Three parameters */
  642. irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
  643. irlan_insert_string_param(skb, "FILTER_TYPE", "BROADCAST");
  644. if (status)
  645. irlan_insert_string_param(skb, "FILTER_MODE", "FILTER");
  646. else
  647. irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
  648. irlan_ctrl_data_request(self, skb);
  649. }
  650. /*
  651. * Function irlan_set_multicast_filter (self, status)
  652. *
  653. * Make IrLAN provider accept ethernet frames addressed to the multicast
  654. * address.
  655. *
  656. */
  657. void irlan_set_multicast_filter(struct irlan_cb *self, int status)
  658. {
  659. struct sk_buff *skb;
  660. __u8 *frame;
  661. IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
  662. IRDA_ASSERT(self != NULL, return;);
  663. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  664. skb = dev_alloc_skb(128);
  665. if (!skb)
  666. return;
  667. /* Reserve space for TTP, LMP, and LAP header */
  668. skb_reserve(skb, self->client.max_header_size);
  669. skb_put(skb, 2);
  670. frame = skb->data;
  671. frame[0] = CMD_FILTER_OPERATION;
  672. frame[1] = 0x03; /* Three parameters */
  673. irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
  674. irlan_insert_string_param(skb, "FILTER_TYPE", "MULTICAST");
  675. if (status)
  676. irlan_insert_string_param(skb, "FILTER_MODE", "ALL");
  677. else
  678. irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
  679. irlan_ctrl_data_request(self, skb);
  680. }
  681. /*
  682. * Function irlan_get_unicast_addr (self)
  683. *
  684. * Retrieves the unicast address from the IrLAN provider. This address
  685. * will be inserted into the devices structure, so the ethernet layer
  686. * can construct its packets.
  687. *
  688. */
  689. static void irlan_get_unicast_addr(struct irlan_cb *self)
  690. {
  691. struct sk_buff *skb;
  692. __u8 *frame;
  693. IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
  694. IRDA_ASSERT(self != NULL, return;);
  695. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  696. skb = dev_alloc_skb(128);
  697. if (!skb)
  698. return;
  699. /* Reserve space for TTP, LMP, and LAP header */
  700. skb_reserve(skb, self->client.max_header_size);
  701. skb_put(skb, 2);
  702. frame = skb->data;
  703. frame[0] = CMD_FILTER_OPERATION;
  704. frame[1] = 0x03; /* Three parameters */
  705. irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
  706. irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
  707. irlan_insert_string_param(skb, "FILTER_OPERATION", "DYNAMIC");
  708. irlan_ctrl_data_request(self, skb);
  709. }
  710. /*
  711. * Function irlan_get_media_char (self)
  712. *
  713. *
  714. *
  715. */
  716. void irlan_get_media_char(struct irlan_cb *self)
  717. {
  718. struct sk_buff *skb;
  719. __u8 *frame;
  720. IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
  721. IRDA_ASSERT(self != NULL, return;);
  722. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  723. skb = dev_alloc_skb(64);
  724. if (!skb)
  725. return;
  726. /* Reserve space for TTP, LMP, and LAP header */
  727. skb_reserve(skb, self->client.max_header_size);
  728. skb_put(skb, 2);
  729. frame = skb->data;
  730. /* Build frame */
  731. frame[0] = CMD_GET_MEDIA_CHAR;
  732. frame[1] = 0x01; /* One parameter */
  733. irlan_insert_string_param(skb, "MEDIA", "802.3");
  734. irlan_ctrl_data_request(self, skb);
  735. }
  736. /*
  737. * Function insert_byte_param (skb, param, value)
  738. *
  739. * Insert byte parameter into frame
  740. *
  741. */
  742. int irlan_insert_byte_param(struct sk_buff *skb, char *param, __u8 value)
  743. {
  744. return __irlan_insert_param(skb, param, IRLAN_BYTE, value, 0, NULL, 0);
  745. }
  746. int irlan_insert_short_param(struct sk_buff *skb, char *param, __u16 value)
  747. {
  748. return __irlan_insert_param(skb, param, IRLAN_SHORT, 0, value, NULL, 0);
  749. }
  750. /*
  751. * Function insert_string (skb, param, value)
  752. *
  753. * Insert string parameter into frame
  754. *
  755. */
  756. int irlan_insert_string_param(struct sk_buff *skb, char *param, char *string)
  757. {
  758. int string_len = strlen(string);
  759. return __irlan_insert_param(skb, param, IRLAN_ARRAY, 0, 0, string,
  760. string_len);
  761. }
  762. /*
  763. * Function insert_array_param(skb, param, value, len_value)
  764. *
  765. * Insert array parameter into frame
  766. *
  767. */
  768. int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *array,
  769. __u16 array_len)
  770. {
  771. return __irlan_insert_param(skb, name, IRLAN_ARRAY, 0, 0, array,
  772. array_len);
  773. }
  774. /*
  775. * Function insert_param (skb, param, value, byte)
  776. *
  777. * Insert parameter at end of buffer, structure of a parameter is:
  778. *
  779. * -----------------------------------------------------------------------
  780. * | Name Length[1] | Param Name[1..255] | Val Length[2] | Value[0..1016]|
  781. * -----------------------------------------------------------------------
  782. */
  783. static int __irlan_insert_param(struct sk_buff *skb, char *param, int type,
  784. __u8 value_byte, __u16 value_short,
  785. __u8 *value_array, __u16 value_len)
  786. {
  787. __u8 *frame;
  788. __u8 param_len;
  789. __u16 tmp_le; /* Temporary value in little endian format */
  790. int n=0;
  791. if (skb == NULL) {
  792. IRDA_DEBUG(2, "%s(), Got NULL skb\n", __FUNCTION__ );
  793. return 0;
  794. }
  795. param_len = strlen(param);
  796. switch (type) {
  797. case IRLAN_BYTE:
  798. value_len = 1;
  799. break;
  800. case IRLAN_SHORT:
  801. value_len = 2;
  802. break;
  803. case IRLAN_ARRAY:
  804. IRDA_ASSERT(value_array != NULL, return 0;);
  805. IRDA_ASSERT(value_len > 0, return 0;);
  806. break;
  807. default:
  808. IRDA_DEBUG(2, "%s(), Unknown parameter type!\n", __FUNCTION__ );
  809. return 0;
  810. break;
  811. }
  812. /* Insert at end of sk-buffer */
  813. frame = skb->tail;
  814. /* Make space for data */
  815. if (skb_tailroom(skb) < (param_len+value_len+3)) {
  816. IRDA_DEBUG(2, "%s(), No more space at end of skb\n", __FUNCTION__ );
  817. return 0;
  818. }
  819. skb_put(skb, param_len+value_len+3);
  820. /* Insert parameter length */
  821. frame[n++] = param_len;
  822. /* Insert parameter */
  823. memcpy(frame+n, param, param_len); n += param_len;
  824. /* Insert value length (2 byte little endian format, LSB first) */
  825. tmp_le = cpu_to_le16(value_len);
  826. memcpy(frame+n, &tmp_le, 2); n += 2; /* To avoid alignment problems */
  827. /* Insert value */
  828. switch (type) {
  829. case IRLAN_BYTE:
  830. frame[n++] = value_byte;
  831. break;
  832. case IRLAN_SHORT:
  833. tmp_le = cpu_to_le16(value_short);
  834. memcpy(frame+n, &tmp_le, 2); n += 2;
  835. break;
  836. case IRLAN_ARRAY:
  837. memcpy(frame+n, value_array, value_len); n+=value_len;
  838. break;
  839. default:
  840. break;
  841. }
  842. IRDA_ASSERT(n == (param_len+value_len+3), return 0;);
  843. return param_len+value_len+3;
  844. }
  845. /*
  846. * Function irlan_extract_param (buf, name, value, len)
  847. *
  848. * Extracts a single parameter name/value pair from buffer and updates
  849. * the buffer pointer to point to the next name/value pair.
  850. */
  851. int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len)
  852. {
  853. __u8 name_len;
  854. __u16 val_len;
  855. int n=0;
  856. IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
  857. /* get length of parameter name (1 byte) */
  858. name_len = buf[n++];
  859. if (name_len > 254) {
  860. IRDA_DEBUG(2, "%s(), name_len > 254\n", __FUNCTION__ );
  861. return -RSP_INVALID_COMMAND_FORMAT;
  862. }
  863. /* get parameter name */
  864. memcpy(name, buf+n, name_len);
  865. name[name_len] = '\0';
  866. n+=name_len;
  867. /*
  868. * Get length of parameter value (2 bytes in little endian
  869. * format)
  870. */
  871. memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */
  872. le16_to_cpus(&val_len); n+=2;
  873. if (val_len > 1016) {
  874. IRDA_DEBUG(2, "%s(), parameter length to long\n", __FUNCTION__ );
  875. return -RSP_INVALID_COMMAND_FORMAT;
  876. }
  877. *len = val_len;
  878. /* get parameter value */
  879. memcpy(value, buf+n, val_len);
  880. value[val_len] = '\0';
  881. n+=val_len;
  882. IRDA_DEBUG(4, "Parameter: %s ", name);
  883. IRDA_DEBUG(4, "Value: %s\n", value);
  884. return n;
  885. }
  886. #ifdef CONFIG_PROC_FS
  887. /*
  888. * Start of reading /proc entries.
  889. * Return entry at pos,
  890. * or start_token to indicate print header line
  891. * or NULL if end of file
  892. */
  893. static void *irlan_seq_start(struct seq_file *seq, loff_t *pos)
  894. {
  895. int i = 1;
  896. struct irlan_cb *self;
  897. rcu_read_lock();
  898. if (*pos == 0)
  899. return SEQ_START_TOKEN;
  900. list_for_each_entry(self, &irlans, dev_list) {
  901. if (*pos == i)
  902. return self;
  903. ++i;
  904. }
  905. return NULL;
  906. }
  907. /* Return entry after v, and increment pos */
  908. static void *irlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
  909. {
  910. struct list_head *nxt;
  911. ++*pos;
  912. if (v == SEQ_START_TOKEN)
  913. nxt = irlans.next;
  914. else
  915. nxt = ((struct irlan_cb *)v)->dev_list.next;
  916. return (nxt == &irlans) ? NULL
  917. : list_entry(nxt, struct irlan_cb, dev_list);
  918. }
  919. /* End of reading /proc file */
  920. static void irlan_seq_stop(struct seq_file *seq, void *v)
  921. {
  922. rcu_read_unlock();
  923. }
  924. /*
  925. * Show one entry in /proc file.
  926. */
  927. static int irlan_seq_show(struct seq_file *seq, void *v)
  928. {
  929. if (v == SEQ_START_TOKEN)
  930. seq_puts(seq, "IrLAN instances:\n");
  931. else {
  932. struct irlan_cb *self = v;
  933. IRDA_ASSERT(self != NULL, return -1;);
  934. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
  935. seq_printf(seq,"ifname: %s,\n",
  936. self->dev->name);
  937. seq_printf(seq,"client state: %s, ",
  938. irlan_state[ self->client.state]);
  939. seq_printf(seq,"provider state: %s,\n",
  940. irlan_state[ self->provider.state]);
  941. seq_printf(seq,"saddr: %#08x, ",
  942. self->saddr);
  943. seq_printf(seq,"daddr: %#08x\n",
  944. self->daddr);
  945. seq_printf(seq,"version: %d.%d,\n",
  946. self->version[1], self->version[0]);
  947. seq_printf(seq,"access type: %s\n",
  948. irlan_access[self->client.access_type]);
  949. seq_printf(seq,"media: %s\n",
  950. irlan_media[self->media]);
  951. seq_printf(seq,"local filter:\n");
  952. seq_printf(seq,"remote filter: ");
  953. irlan_print_filter(seq, self->client.filter_type);
  954. seq_printf(seq,"tx busy: %s\n",
  955. netif_queue_stopped(self->dev) ? "TRUE" : "FALSE");
  956. seq_putc(seq,'\n');
  957. }
  958. return 0;
  959. }
  960. static struct seq_operations irlan_seq_ops = {
  961. .start = irlan_seq_start,
  962. .next = irlan_seq_next,
  963. .stop = irlan_seq_stop,
  964. .show = irlan_seq_show,
  965. };
  966. static int irlan_seq_open(struct inode *inode, struct file *file)
  967. {
  968. return seq_open(file, &irlan_seq_ops);
  969. }
  970. #endif
  971. MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
  972. MODULE_DESCRIPTION("The Linux IrDA LAN protocol");
  973. MODULE_LICENSE("GPL");
  974. module_param(eth, bool, 0);
  975. MODULE_PARM_DESC(eth, "Name devices ethX (0) or irlanX (1)");
  976. module_param(access, int, 0);
  977. MODULE_PARM_DESC(access, "Access type DIRECT=1, PEER=2, HOSTED=3");
  978. module_init(irlan_init);
  979. module_exit(irlan_cleanup);