irlan_common.c 30 KB

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