irlan_common.c 31 KB

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