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
- Lines: 191
- Date:
Sat Apr 24 17:50:06 1999
- Orig file:
v2.2.6/linux/net/irda/irlan/irlan_eth.c
- Orig date:
Fri Apr 16 14:47:31 1999
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)