vserver 2.0 rc7
[linux-2.6.git] / net / irda / irlan / irlan_eth.c
1 /*********************************************************************
2  *                
3  * Filename:      irlan_eth.c
4  * Version:       
5  * Description:   
6  * Status:        Experimental.
7  * Author:        Dag Brattli <dagb@cs.uit.no>
8  * Created at:    Thu Oct 15 08:37:58 1998
9  * Modified at:   Tue Mar 21 09:06:41 2000
10  * Modified by:   Dag Brattli <dagb@cs.uit.no>
11  * Sources:       skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
12  *                slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
13  *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
14  * 
15  *     Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved.
16  *      
17  *     This program is free software; you can redistribute it and/or 
18  *     modify it under the terms of the GNU General Public License as 
19  *     published by the Free Software Foundation; either version 2 of 
20  *     the License, or (at your option) any later version.
21  *  
22  *     Neither Dag Brattli nor University of Tromsø admit liability nor
23  *     provide warranty for any of this software. This material is 
24  *     provided "AS-IS" and at no charge.
25  *     
26  ********************************************************************/
27
28 #include <linux/config.h>
29 #include <linux/netdevice.h>
30 #include <linux/etherdevice.h>
31 #include <linux/inetdevice.h>
32 #include <linux/if_arp.h>
33 #include <linux/module.h>
34 #include <net/arp.h>
35
36 #include <net/irda/irda.h>
37 #include <net/irda/irmod.h>
38 #include <net/irda/irlan_common.h>
39 #include <net/irda/irlan_client.h>
40 #include <net/irda/irlan_event.h>
41 #include <net/irda/irlan_eth.h>
42
43 static int  irlan_eth_open(struct net_device *dev);
44 static int  irlan_eth_close(struct net_device *dev);
45 static int  irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev);
46 static void irlan_eth_set_multicast_list( struct net_device *dev);
47 static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev);
48
49 /*
50  * Function irlan_eth_setup (dev)
51  *
52  *    The network device initialization function.
53  *
54  */
55 static void irlan_eth_setup(struct net_device *dev)
56 {
57         dev->open               = irlan_eth_open;
58         dev->stop               = irlan_eth_close;
59         dev->hard_start_xmit    = irlan_eth_xmit; 
60         dev->get_stats          = irlan_eth_get_stats;
61         dev->set_multicast_list = irlan_eth_set_multicast_list;
62         dev->destructor         = free_netdev;
63
64         SET_MODULE_OWNER(dev);
65
66         ether_setup(dev);
67         
68         /* 
69          * Lets do all queueing in IrTTP instead of this device driver.
70          * Queueing here as well can introduce some strange latency
71          * problems, which we will avoid by setting the queue size to 0.
72          */
73         /*
74          * The bugs in IrTTP and IrLAN that created this latency issue
75          * have now been fixed, and we can propagate flow control properly
76          * to the network layer. However, this requires a minimal queue of
77          * packets for the device.
78          * Without flow control, the Tx Queue is 14 (ttp) + 0 (dev) = 14
79          * With flow control, the Tx Queue is 7 (ttp) + 4 (dev) = 11
80          * See irlan_eth_flow_indication()...
81          * Note : this number was randomly selected and would need to
82          * be adjusted.
83          * Jean II */
84         dev->tx_queue_len = 4;
85 }
86
87 /*
88  * Function alloc_irlandev
89  *
90  *    Allocate network device and control block
91  *
92  */
93 struct net_device *alloc_irlandev(const char *name)
94 {
95         return alloc_netdev(sizeof(struct irlan_cb), name,
96                             irlan_eth_setup);
97 }
98
99 /*
100  * Function irlan_eth_open (dev)
101  *
102  *    Network device has been opened by user
103  *
104  */
105 static int irlan_eth_open(struct net_device *dev)
106 {
107         struct irlan_cb *self = netdev_priv(dev);
108         
109         IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
110
111         /* Ready to play! */
112         netif_stop_queue(dev); /* Wait until data link is ready */
113
114         /* We are now open, so time to do some work */
115         self->disconnect_reason = 0;
116         irlan_client_wakeup(self, self->saddr, self->daddr);
117
118         /* Make sure we have a hardware address before we return, 
119            so DHCP clients gets happy */
120         return wait_event_interruptible(self->open_wait,
121                                         !self->tsap_data->connected);
122 }
123
124 /*
125  * Function irlan_eth_close (dev)
126  *
127  *    Stop the ether network device, his function will usually be called by
128  *    ifconfig down. We should now disconnect the link, We start the 
129  *    close timer, so that the instance will be removed if we are unable
130  *    to discover the remote device after the disconnect.
131  */
132 static int irlan_eth_close(struct net_device *dev)
133 {
134         struct irlan_cb *self = netdev_priv(dev);
135         
136         IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
137         
138         /* Stop device */
139         netif_stop_queue(dev);
140         
141         irlan_close_data_channel(self);
142         irlan_close_tsaps(self);
143
144         irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
145         irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);      
146         
147         /* Remove frames queued on the control channel */
148         skb_queue_purge(&self->client.txq);
149
150         self->client.tx_busy = 0;
151         
152         return 0;
153 }
154
155 /*
156  * Function irlan_eth_tx (skb)
157  *
158  *    Transmits ethernet frames over IrDA link.
159  *
160  */
161 static int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev)
162 {
163         struct irlan_cb *self = netdev_priv(dev);
164         int ret;
165
166         /* skb headroom large enough to contain all IrDA-headers? */
167         if ((skb_headroom(skb) < self->max_header_size) || (skb_shared(skb))) {
168                 struct sk_buff *new_skb = 
169                         skb_realloc_headroom(skb, self->max_header_size);
170
171                 /*  We have to free the original skb anyway */
172                 dev_kfree_skb(skb);
173
174                 /* Did the realloc succeed? */
175                 if (new_skb == NULL)
176                         return 0;
177
178                 /* Use the new skb instead */
179                 skb = new_skb;
180         } 
181
182         dev->trans_start = jiffies;
183
184         /* Now queue the packet in the transport layer */
185         if (self->use_udata)
186                 ret = irttp_udata_request(self->tsap_data, skb);
187         else
188                 ret = irttp_data_request(self->tsap_data, skb);
189
190         if (ret < 0) {
191                 /*   
192                  * IrTTPs tx queue is full, so we just have to
193                  * drop the frame! You might think that we should
194                  * just return -1 and don't deallocate the frame,
195                  * but that is dangerous since it's possible that
196                  * we have replaced the original skb with a new
197                  * one with larger headroom, and that would really
198                  * confuse do_dev_queue_xmit() in dev.c! I have
199                  * tried :-) DB 
200                  */
201                 /* irttp_data_request already free the packet */
202                 self->stats.tx_dropped++;
203         } else {
204                 self->stats.tx_packets++;
205                 self->stats.tx_bytes += skb->len; 
206         }
207         
208         return 0;
209 }
210
211 /*
212  * Function irlan_eth_receive (handle, skb)
213  *
214  *    This function gets the data that is received on the data channel
215  *
216  */
217 int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb)
218 {
219         struct irlan_cb *self = instance;
220
221         if (skb == NULL) {
222                 ++self->stats.rx_dropped; 
223                 return 0;
224         }
225         if (skb->len < ETH_HLEN) {
226                 IRDA_DEBUG(0, "%s() : IrLAN frame too short (%d)\n",
227                            __FUNCTION__, skb->len);
228                 ++self->stats.rx_dropped; 
229                 dev_kfree_skb(skb);
230                 return 0;
231         }
232                 
233         /* 
234          * Adopt this frame! Important to set all these fields since they 
235          * might have been previously set by the low level IrDA network
236          * device driver 
237          */
238         skb->dev = self->dev;
239         skb->protocol=eth_type_trans(skb, skb->dev); /* Remove eth header */
240         
241         self->stats.rx_packets++;
242         self->stats.rx_bytes += skb->len; 
243
244         netif_rx(skb);   /* Eat it! */
245         
246         return 0;
247 }
248
249 /*
250  * Function irlan_eth_flow (status)
251  *
252  *    Do flow control between IP/Ethernet and IrLAN/IrTTP. This is done by 
253  *    controlling the queue stop/start.
254  *
255  * The IrDA link layer has the advantage to have flow control, and
256  * IrTTP now properly handles that. Flow controlling the higher layers
257  * prevent us to drop Tx packets in here (up to 15% for a TCP socket,
258  * more for UDP socket).
259  * Also, this allow us to reduce the overall transmit queue, which means
260  * less latency in case of mixed traffic.
261  * Jean II
262  */
263 void irlan_eth_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
264 {
265         struct irlan_cb *self;
266         struct net_device *dev;
267
268         self = (struct irlan_cb *) instance;
269
270         IRDA_ASSERT(self != NULL, return;);
271         IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
272         
273         dev = self->dev;
274
275         IRDA_ASSERT(dev != NULL, return;);
276         
277         IRDA_DEBUG(0, "%s() : flow %s ; running %d\n", __FUNCTION__,
278                    flow == FLOW_STOP ? "FLOW_STOP" : "FLOW_START",
279                    netif_running(dev));
280
281         switch (flow) {
282         case FLOW_STOP:
283                 /* IrTTP is full, stop higher layers */
284                 netif_stop_queue(dev);
285                 break;
286         case FLOW_START:
287         default:
288                 /* Tell upper layers that its time to transmit frames again */
289                 /* Schedule network layer */
290                 netif_wake_queue(dev);
291                 break;
292         }
293 }
294
295 /*
296  * Function irlan_etc_send_gratuitous_arp (dev)
297  *
298  *    Send gratuitous ARP to announce that we have changed
299  *    hardware address, so that all peers updates their ARP tables
300  */
301 void irlan_eth_send_gratuitous_arp(struct net_device *dev)
302 {
303         struct in_device *in_dev;
304
305         /* 
306          * When we get a new MAC address do a gratuitous ARP. This
307          * is useful if we have changed access points on the same
308          * subnet.  
309          */
310 #ifdef CONFIG_INET
311         IRDA_DEBUG(4, "IrLAN: Sending gratuitous ARP\n");
312         rcu_read_lock();
313         in_dev = __in_dev_get(dev);
314         if (in_dev == NULL)
315                 goto out;
316         if (in_dev->ifa_list)
317                 
318         arp_send(ARPOP_REQUEST, ETH_P_ARP, 
319                  in_dev->ifa_list->ifa_address,
320                  dev, 
321                  in_dev->ifa_list->ifa_address,
322                  NULL, dev->dev_addr, NULL);
323 out:
324         rcu_read_unlock();
325 #endif /* CONFIG_INET */
326 }
327
328 /*
329  * Function set_multicast_list (dev)
330  *
331  *    Configure the filtering of the device
332  *
333  */
334 #define HW_MAX_ADDRS 4 /* Must query to get it! */
335 static void irlan_eth_set_multicast_list(struct net_device *dev) 
336 {
337         struct irlan_cb *self = netdev_priv(dev);
338
339         IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
340
341         /* Check if data channel has been connected yet */
342         if (self->client.state != IRLAN_DATA) {
343                 IRDA_DEBUG(1, "%s(), delaying!\n", __FUNCTION__ );
344                 return;
345         }
346
347         if (dev->flags & IFF_PROMISC) {
348                 /* Enable promiscuous mode */
349                 IRDA_WARNING("Promiscous mode not implemented by IrLAN!\n");
350         } 
351         else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS) {
352                 /* Disable promiscuous mode, use normal mode. */
353                 IRDA_DEBUG(4, "%s(), Setting multicast filter\n", __FUNCTION__ );
354                 /* hardware_set_filter(NULL); */
355
356                 irlan_set_multicast_filter(self, TRUE);
357         }
358         else if (dev->mc_count) {
359                 IRDA_DEBUG(4, "%s(), Setting multicast filter\n", __FUNCTION__ );
360                 /* Walk the address list, and load the filter */
361                 /* hardware_set_filter(dev->mc_list); */
362
363                 irlan_set_multicast_filter(self, TRUE);
364         }
365         else {
366                 IRDA_DEBUG(4, "%s(), Clearing multicast filter\n", __FUNCTION__ );
367                 irlan_set_multicast_filter(self, FALSE);
368         }
369
370         if (dev->flags & IFF_BROADCAST)
371                 irlan_set_broadcast_filter(self, TRUE);
372         else
373                 irlan_set_broadcast_filter(self, FALSE);
374 }
375
376 /*
377  * Function irlan_get_stats (dev)
378  *
379  *    Get the current statistics for this device
380  *
381  */
382 static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev) 
383 {
384         struct irlan_cb *self = netdev_priv(dev);
385
386         return &self->stats;
387 }