irlan_common.c 30 KB

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