File: /usr/src/linux/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/random.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 /*
44 * Function irlan_eth_init (dev)
45 *
46 * The network device initialization function.
47 *
48 */
49 int irlan_eth_init(struct net_device *dev)
50 {
51 struct irlan_cb *self;
52
53 IRDA_DEBUG(2, __FUNCTION__"()\n");
54
55 ASSERT(dev != NULL, return -1;);
56
57 self = (struct irlan_cb *) dev->priv;
58
59 dev->open = irlan_eth_open;
60 dev->stop = irlan_eth_close;
61 dev->hard_start_xmit = irlan_eth_xmit;
62 dev->get_stats = irlan_eth_get_stats;
63 dev->set_multicast_list = irlan_eth_set_multicast_list;
64 dev->features |= NETIF_F_DYNALLOC;
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 dev->tx_queue_len = 0;
74
75 if (self->provider.access_type == ACCESS_DIRECT) {
76 /*
77 * Since we are emulating an IrLAN sever we will have to
78 * give ourself an ethernet address!
79 */
80 dev->dev_addr[0] = 0x40;
81 dev->dev_addr[1] = 0x00;
82 dev->dev_addr[2] = 0x00;
83 dev->dev_addr[3] = 0x00;
84 get_random_bytes(dev->dev_addr+4, 1);
85 get_random_bytes(dev->dev_addr+5, 1);
86 }
87
88 return 0;
89 }
90
91 /*
92 * Function irlan_eth_open (dev)
93 *
94 * Network device has been opened by user
95 *
96 */
97 int irlan_eth_open(struct net_device *dev)
98 {
99 struct irlan_cb *self;
100
101 IRDA_DEBUG(2, __FUNCTION__ "()\n");
102
103 ASSERT(dev != NULL, return -1;);
104
105 self = (struct irlan_cb *) dev->priv;
106
107 ASSERT(self != NULL, return -1;);
108
109 /* Ready to play! */
110 netif_stop_queue(dev); /* Wait until data link is ready */
111
112 /* We are now open, so time to do some work */
113 self->disconnect_reason = 0;
114 irlan_client_wakeup(self, self->saddr, self->daddr);
115
116 irlan_mod_inc_use_count();
117
118 /* Make sure we have a hardware address before we return, so DHCP clients gets happy */
119 interruptible_sleep_on(&self->open_wait);
120
121 return 0;
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 int irlan_eth_close(struct net_device *dev)
133 {
134 struct irlan_cb *self = (struct irlan_cb *) dev->priv;
135 struct sk_buff *skb;
136
137 IRDA_DEBUG(2, __FUNCTION__ "()\n");
138
139 /* Stop device */
140 netif_stop_queue(dev);
141
142 irlan_mod_dec_use_count();
143
144 irlan_close_data_channel(self);
145 irlan_close_tsaps(self);
146
147 irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
148 irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);
149
150 /* Remove frames queued on the control channel */
151 while ((skb = skb_dequeue(&self->client.txq)))
152 dev_kfree_skb(skb);
153
154 self->client.tx_busy = 0;
155
156 return 0;
157 }
158
159 /*
160 * Function irlan_eth_tx (skb)
161 *
162 * Transmits ethernet frames over IrDA link.
163 *
164 */
165 int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev)
166 {
167 struct irlan_cb *self;
168 int ret;
169
170 self = (struct irlan_cb *) dev->priv;
171
172 ASSERT(self != NULL, return 0;);
173 ASSERT(self->magic == IRLAN_MAGIC, return 0;);
174
175 /* skb headroom large enough to contain all IrDA-headers? */
176 if ((skb_headroom(skb) < self->max_header_size) || (skb_shared(skb))) {
177 struct sk_buff *new_skb =
178 skb_realloc_headroom(skb, self->max_header_size);
179
180 /* We have to free the original skb anyway */
181 dev_kfree_skb(skb);
182
183 /* Did the realloc succeed? */
184 if (new_skb == NULL)
185 return 0;
186
187 /* Use the new skb instead */
188 skb = new_skb;
189 }
190
191 dev->trans_start = jiffies;
192
193 /* Now queue the packet in the transport layer */
194 if (self->use_udata)
195 ret = irttp_udata_request(self->tsap_data, skb);
196 else
197 ret = irttp_data_request(self->tsap_data, skb);
198
199 if (ret < 0) {
200 /*
201 * IrTTPs tx queue is full, so we just have to
202 * drop the frame! You might think that we should
203 * just return -1 and don't deallocate the frame,
204 * but that is dangerous since it's possible that
205 * we have replaced the original skb with a new
206 * one with larger headroom, and that would really
207 * confuse do_dev_queue_xmit() in dev.c! I have
208 * tried :-) DB
209 */
210 dev_kfree_skb(skb);
211 self->stats.tx_dropped++;
212 } else {
213 self->stats.tx_packets++;
214 self->stats.tx_bytes += skb->len;
215 }
216
217 return 0;
218 }
219
220 /*
221 * Function irlan_eth_receive (handle, skb)
222 *
223 * This function gets the data that is received on the data channel
224 *
225 */
226 int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb)
227 {
228 struct irlan_cb *self;
229
230 self = (struct irlan_cb *) instance;
231
232 if (skb == NULL) {
233 ++self->stats.rx_dropped;
234 return 0;
235 }
236 ASSERT(skb->len > 1, return 0;);
237
238 /*
239 * Adopt this frame! Important to set all these fields since they
240 * might have been previously set by the low level IrDA network
241 * device driver
242 */
243 skb->dev = &self->dev;
244 skb->protocol=eth_type_trans(skb, skb->dev); /* Remove eth header */
245
246 self->stats.rx_packets++;
247 self->stats.rx_bytes += skb->len;
248
249 netif_rx(skb); /* Eat it! */
250
251 return 0;
252 }
253
254 /*
255 * Function irlan_eth_flow (status)
256 *
257 * Do flow control between IP/Ethernet and IrLAN/IrTTP. This is done by
258 * controlling the queue stop/start.
259 */
260 void irlan_eth_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
261 {
262 struct irlan_cb *self;
263 struct net_device *dev;
264
265 self = (struct irlan_cb *) instance;
266
267 ASSERT(self != NULL, return;);
268 ASSERT(self->magic == IRLAN_MAGIC, return;);
269
270 dev = &self->dev;
271
272 ASSERT(dev != NULL, return;);
273
274 switch (flow) {
275 case FLOW_STOP:
276 netif_stop_queue(dev);
277 break;
278 case FLOW_START:
279 default:
280 /* Tell upper layers that its time to transmit frames again */
281 /* Schedule network layer */
282 netif_start_queue(dev);
283 break;
284 }
285 }
286
287 /*
288 * Function irlan_eth_rebuild_header (buff, dev, dest, skb)
289 *
290 * If we don't want to use ARP. Currently not used!!
291 *
292 */
293 void irlan_eth_rebuild_header(void *buff, struct net_device *dev,
294 unsigned long dest, struct sk_buff *skb)
295 {
296 struct ethhdr *eth = (struct ethhdr *) buff;
297
298 memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
299 memcpy(eth->h_dest, dev->dev_addr, dev->addr_len);
300
301 /* return 0; */
302 }
303
304 /*
305 * Function irlan_etc_send_gratuitous_arp (dev)
306 *
307 * Send gratuitous ARP to announce that we have changed
308 * hardware address, so that all peers updates their ARP tables
309 */
310 void irlan_eth_send_gratuitous_arp(struct net_device *dev)
311 {
312 struct in_device *in_dev;
313
314 /*
315 * When we get a new MAC address do a gratuitous ARP. This
316 * is useful if we have changed access points on the same
317 * subnet.
318 */
319 #ifdef CONFIG_INET
320 IRDA_DEBUG(4, "IrLAN: Sending gratuitous ARP\n");
321 in_dev = in_dev_get(dev);
322 if (in_dev == NULL)
323 return;
324 read_lock(&in_dev->lock);
325 if (in_dev->ifa_list)
326
327 arp_send(ARPOP_REQUEST, ETH_P_ARP,
328 in_dev->ifa_list->ifa_address,
329 dev,
330 in_dev->ifa_list->ifa_address,
331 NULL, dev->dev_addr, NULL);
332 read_unlock(&in_dev->lock);
333 in_dev_put(in_dev);
334 #endif /* CONFIG_INET */
335 }
336
337 /*
338 * Function set_multicast_list (dev)
339 *
340 * Configure the filtering of the device
341 *
342 */
343 #define HW_MAX_ADDRS 4 /* Must query to get it! */
344 void irlan_eth_set_multicast_list(struct net_device *dev)
345 {
346 struct irlan_cb *self;
347
348 self = dev->priv;
349
350 IRDA_DEBUG(2, __FUNCTION__ "()\n");
351
352 ASSERT(self != NULL, return;);
353 ASSERT(self->magic == IRLAN_MAGIC, return;);
354
355 /* Check if data channel has been connected yet */
356 if (self->client.state != IRLAN_DATA) {
357 IRDA_DEBUG(1, __FUNCTION__ "(), delaying!\n");
358 return;
359 }
360
361 if (dev->flags & IFF_PROMISC) {
362 /* Enable promiscuous mode */
363 WARNING("Promiscous mode not implemented by IrLAN!\n");
364 }
365 else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS) {
366 /* Disable promiscuous mode, use normal mode. */
367 IRDA_DEBUG(4, __FUNCTION__ "(), Setting multicast filter\n");
368 /* hardware_set_filter(NULL); */
369
370 irlan_set_multicast_filter(self, TRUE);
371 }
372 else if (dev->mc_count) {
373 IRDA_DEBUG(4, __FUNCTION__ "(), Setting multicast filter\n");
374 /* Walk the address list, and load the filter */
375 /* hardware_set_filter(dev->mc_list); */
376
377 irlan_set_multicast_filter(self, TRUE);
378 }
379 else {
380 IRDA_DEBUG(4, __FUNCTION__ "(), Clearing multicast filter\n");
381 irlan_set_multicast_filter(self, FALSE);
382 }
383
384 if (dev->flags & IFF_BROADCAST)
385 irlan_set_broadcast_filter(self, TRUE);
386 else
387 irlan_set_broadcast_filter(self, FALSE);
388 }
389
390 /*
391 * Function irlan_get_stats (dev)
392 *
393 * Get the current statistics for this device
394 *
395 */
396 struct net_device_stats *irlan_eth_get_stats(struct net_device *dev)
397 {
398 struct irlan_cb *self = (struct irlan_cb *) dev->priv;
399
400 ASSERT(self != NULL, return NULL;);
401 ASSERT(self->magic == IRLAN_MAGIC, return NULL;);
402
403 return &self->stats;
404 }
405