irlan_common.c 30 KB

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