irlan_common.c 31 KB

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