patch-2.2.7 linux/net/irda/irlan/irlan_eth.c

Next file: linux/net/irda/irlan/irlan_provider.c
Previous file: linux/net/irda/irlan/irlan_common.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.6/linux/net/irda/irlan/irlan_eth.c linux/net/irda/irlan/irlan_eth.c
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Oct 15 08:37:58 1998
- * Modified at:   Mon Mar 22 17:41:59 1999
+ * Modified at:   Thu Apr 22 14:26:39 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
  *                slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
@@ -27,15 +27,150 @@
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/inetdevice.h>
 #include <linux/if_arp.h>
 #include <net/arp.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irmod.h>
 #include <net/irda/irlan_common.h>
+#include <net/irda/irlan_client.h>
+#include <net/irda/irlan_event.h>
 #include <net/irda/irlan_eth.h>
 
 /*
+ * Function irlan_eth_init (dev)
+ *
+ *    The network device initialization function.
+ *
+ */
+int irlan_eth_init(struct device *dev)
+{
+	struct irmanager_event mgr_event;
+	struct irlan_cb *self;
+
+	DEBUG(0, __FUNCTION__"()\n");
+
+	ASSERT(dev != NULL, return -1;);
+       
+	self = (struct irlan_cb *) dev->priv;
+
+	dev->open               = irlan_eth_open;
+	dev->stop               = irlan_eth_close;
+	dev->hard_start_xmit    = irlan_eth_xmit; 
+	dev->get_stats	        = irlan_eth_get_stats;
+	dev->set_multicast_list = irlan_eth_set_multicast_list;
+
+	dev->tbusy = 1;
+	
+	ether_setup(dev);
+	
+	dev->tx_queue_len = TTP_MAX_QUEUE;
+
+#if 0
+	/*  
+	 *  OK, since we are emulating an IrLAN sever we will have to give
+	 *  ourself an ethernet address!
+	 *  FIXME: this must be more dynamically
+	 */
+	dev->dev_addr[0] = 0x40;
+	dev->dev_addr[1] = 0x00;
+	dev->dev_addr[2] = 0x00;
+	dev->dev_addr[3] = 0x00;
+	dev->dev_addr[4] = 0x23;
+	dev->dev_addr[5] = 0x45;
+#endif
+	/* 
+	 * Network device has now been registered, so tell irmanager about
+	 * it, so it can be configured with network parameters
+	 */
+	mgr_event.event = EVENT_IRLAN_START;
+	sprintf(mgr_event.devname, "%s", self->ifname);
+	irmanager_notify(&mgr_event);
+
+	/* 
+	 * We set this so that we only notify once, since if 
+	 * configuration of the network device fails, the user
+	 * will have to sort it out first anyway. No need to 
+	 * try again.
+	 */
+	self->notify_irmanager = FALSE;
+
+	return 0;
+}
+
+/*
+ * Function irlan_eth_open (dev)
+ *
+ *    Network device has been opened by user
+ *
+ */
+int irlan_eth_open(struct device *dev)
+{
+	struct irlan_cb *self;
+	
+	DEBUG(0, __FUNCTION__ "()\n");
+
+	ASSERT(dev != NULL, return -1;);
+
+	self = (struct irlan_cb *) dev->priv;
+
+	ASSERT(self != NULL, return -1;);
+
+	/* Ready to play! */
+/* 	dev->tbusy = 0; */ /* Wait until data link is ready */
+	dev->interrupt = 0;
+	dev->start = 1;
+
+	self->notify_irmanager = TRUE;
+
+	/* We are now open, so time to do some work */
+	irlan_client_wakeup(self, self->saddr, self->daddr);
+
+	irlan_mod_inc_use_count();
+	
+	return 0;
+}
+
+/*
+ * Function irlan_eth_close (dev)
+ *
+ *    Stop the ether network device, his function will usually be called by
+ *    ifconfig down. We should now disconnect the link, We start the 
+ *    close timer, so that the instance will be removed if we are unable
+ *    to discover the remote device after the disconnect.
+ */
+int irlan_eth_close(struct device *dev)
+{
+	struct irlan_cb *self = (struct irlan_cb *) dev->priv;
+
+	DEBUG(0, __FUNCTION__ "()\n");
+	
+	/* Stop device */
+	dev->tbusy = 1;
+	dev->start = 0;
+
+	irlan_mod_dec_use_count();
+
+	irlan_close_data_channel(self);
+
+	irlan_close_tsaps(self);
+
+	irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
+	irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);	
+	
+	irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
+
+	/* Device closed by user! */
+	if (self->notify_irmanager)
+		self->notify_irmanager = FALSE;
+	else
+		self->notify_irmanager = TRUE;
+
+	return 0;
+}
+
+/*
  * Function irlan_eth_tx (skb)
  *
  *    Transmits ethernet frames over IrDA link.
@@ -217,6 +352,30 @@
 	memcpy(eth->h_dest, dev->dev_addr, dev->addr_len);
 
 	/* return 0; */
+}
+
+/*
+ * Function irlan_etc_send_gratuitous_arp (dev)
+ *
+ *    Send gratuitous ARP to announce that we have changed
+ *    hardware address, so that all peers updates their ARP tables
+ */
+void irlan_etc_send_gratuitous_arp(struct device *dev) 
+{
+	struct in_device *in_dev;
+
+	/* 
+	 * When we get a new MAC address do a gratuitous ARP. This
+	 * is useful if we have changed access points on the same
+	 * subnet.  
+	 */
+	DEBUG(4, "IrLAN: Sending gratuitous ARP\n");
+	in_dev = dev->ip_ptr;
+	arp_send(ARPOP_REQUEST, ETH_P_ARP, 
+		 in_dev->ifa_list->ifa_address,
+		 &dev, 
+		 in_dev->ifa_list->ifa_address,
+		 NULL, dev->dev_addr, NULL);
 }
 
 /*

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)