aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm/lec.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /net/atm/lec.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'net/atm/lec.c')
-rw-r--r--net/atm/lec.c2538
1 files changed, 2538 insertions, 0 deletions
diff --git a/net/atm/lec.c b/net/atm/lec.c
new file mode 100644
index 000000000000..a0752487026d
--- /dev/null
+++ b/net/atm/lec.c
@@ -0,0 +1,2538 @@
1/*
2 * lec.c: Lan Emulation driver
3 * Marko Kiiskila mkiiskila@yahoo.com
4 *
5 */
6
7#include <linux/config.h>
8#include <linux/kernel.h>
9#include <linux/bitops.h>
10
11/* We are ethernet device */
12#include <linux/if_ether.h>
13#include <linux/netdevice.h>
14#include <linux/etherdevice.h>
15#include <net/sock.h>
16#include <linux/skbuff.h>
17#include <linux/ip.h>
18#include <asm/byteorder.h>
19#include <asm/uaccess.h>
20#include <net/arp.h>
21#include <net/dst.h>
22#include <linux/proc_fs.h>
23#include <linux/spinlock.h>
24#include <linux/proc_fs.h>
25#include <linux/seq_file.h>
26
27/* TokenRing if needed */
28#ifdef CONFIG_TR
29#include <linux/trdevice.h>
30#endif
31
32/* And atm device */
33#include <linux/atmdev.h>
34#include <linux/atmlec.h>
35
36/* Proxy LEC knows about bridging */
37#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
38#include <linux/if_bridge.h>
39#include "../bridge/br_private.h"
40
41static unsigned char bridge_ula_lec[] = {0x01, 0x80, 0xc2, 0x00, 0x00};
42#endif
43
44/* Modular too */
45#include <linux/module.h>
46#include <linux/init.h>
47
48#include "lec.h"
49#include "lec_arpc.h"
50#include "resources.h"
51
52#if 0
53#define DPRINTK printk
54#else
55#define DPRINTK(format,args...)
56#endif
57
58#define DUMP_PACKETS 0 /* 0 = None,
59 * 1 = 30 first bytes
60 * 2 = Whole packet
61 */
62
63#define LEC_UNRES_QUE_LEN 8 /* number of tx packets to queue for a
64 single destination while waiting for SVC */
65
66static int lec_open(struct net_device *dev);
67static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev);
68static int lec_close(struct net_device *dev);
69static struct net_device_stats *lec_get_stats(struct net_device *dev);
70static void lec_init(struct net_device *dev);
71static struct lec_arp_table* lec_arp_find(struct lec_priv *priv,
72 unsigned char *mac_addr);
73static int lec_arp_remove(struct lec_priv *priv,
74 struct lec_arp_table *to_remove);
75/* LANE2 functions */
76static void lane2_associate_ind (struct net_device *dev, u8 *mac_address,
77 u8 *tlvs, u32 sizeoftlvs);
78static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
79 u8 **tlvs, u32 *sizeoftlvs);
80static int lane2_associate_req (struct net_device *dev, u8 *lan_dst,
81 u8 *tlvs, u32 sizeoftlvs);
82
83static int lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
84 unsigned long permanent);
85static void lec_arp_check_empties(struct lec_priv *priv,
86 struct atm_vcc *vcc, struct sk_buff *skb);
87static void lec_arp_destroy(struct lec_priv *priv);
88static void lec_arp_init(struct lec_priv *priv);
89static struct atm_vcc* lec_arp_resolve(struct lec_priv *priv,
90 unsigned char *mac_to_find,
91 int is_rdesc,
92 struct lec_arp_table **ret_entry);
93static void lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
94 unsigned char *atm_addr, unsigned long remoteflag,
95 unsigned int targetless_le_arp);
96static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id);
97static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc);
98static void lec_set_flush_tran_id(struct lec_priv *priv,
99 unsigned char *atm_addr,
100 unsigned long tran_id);
101static void lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
102 struct atm_vcc *vcc,
103 void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb));
104static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc);
105
106static struct lane2_ops lane2_ops = {
107 lane2_resolve, /* resolve, spec 3.1.3 */
108 lane2_associate_req, /* associate_req, spec 3.1.4 */
109 NULL /* associate indicator, spec 3.1.5 */
110};
111
112static unsigned char bus_mac[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
113
114/* Device structures */
115static struct net_device *dev_lec[MAX_LEC_ITF];
116
117#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
118static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
119{
120 struct ethhdr *eth;
121 char *buff;
122 struct lec_priv *priv;
123
124 /* Check if this is a BPDU. If so, ask zeppelin to send
125 * LE_TOPOLOGY_REQUEST with the same value of Topology Change bit
126 * as the Config BPDU has */
127 eth = (struct ethhdr *)skb->data;
128 buff = skb->data + skb->dev->hard_header_len;
129 if (*buff++ == 0x42 && *buff++ == 0x42 && *buff++ == 0x03) {
130 struct sock *sk;
131 struct sk_buff *skb2;
132 struct atmlec_msg *mesg;
133
134 skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
135 if (skb2 == NULL) return;
136 skb2->len = sizeof(struct atmlec_msg);
137 mesg = (struct atmlec_msg *)skb2->data;
138 mesg->type = l_topology_change;
139 buff += 4;
140 mesg->content.normal.flag = *buff & 0x01; /* 0x01 is topology change */
141
142 priv = (struct lec_priv *)dev->priv;
143 atm_force_charge(priv->lecd, skb2->truesize);
144 sk = sk_atm(priv->lecd);
145 skb_queue_tail(&sk->sk_receive_queue, skb2);
146 sk->sk_data_ready(sk, skb2->len);
147 }
148
149 return;
150}
151#endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */
152
153/*
154 * Modelled after tr_type_trans
155 * All multicast and ARE or STE frames go to BUS.
156 * Non source routed frames go by destination address.
157 * Last hop source routed frames go by destination address.
158 * Not last hop source routed frames go by _next_ route descriptor.
159 * Returns pointer to destination MAC address or fills in rdesc
160 * and returns NULL.
161 */
162#ifdef CONFIG_TR
163static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc)
164{
165 struct trh_hdr *trh;
166 int riflen, num_rdsc;
167
168 trh = (struct trh_hdr *)packet;
169 if (trh->daddr[0] & (uint8_t)0x80)
170 return bus_mac; /* multicast */
171
172 if (trh->saddr[0] & TR_RII) {
173 riflen = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
174 if ((ntohs(trh->rcf) >> 13) != 0)
175 return bus_mac; /* ARE or STE */
176 }
177 else
178 return trh->daddr; /* not source routed */
179
180 if (riflen < 6)
181 return trh->daddr; /* last hop, source routed */
182
183 /* riflen is 6 or more, packet has more than one route descriptor */
184 num_rdsc = (riflen/2) - 1;
185 memset(rdesc, 0, ETH_ALEN);
186 /* offset 4 comes from LAN destination field in LE control frames */
187 if (trh->rcf & htons((uint16_t)TR_RCF_DIR_BIT))
188 memcpy(&rdesc[4], &trh->rseg[num_rdsc-2], sizeof(uint16_t));
189 else {
190 memcpy(&rdesc[4], &trh->rseg[1], sizeof(uint16_t));
191 rdesc[5] = ((ntohs(trh->rseg[0]) & 0x000f) | (rdesc[5] & 0xf0));
192 }
193
194 return NULL;
195}
196#endif /* CONFIG_TR */
197
198/*
199 * Open/initialize the netdevice. This is called (in the current kernel)
200 * sometime after booting when the 'ifconfig' program is run.
201 *
202 * This routine should set everything up anew at each open, even
203 * registers that "should" only need to be set once at boot, so that
204 * there is non-reboot way to recover if something goes wrong.
205 */
206
207static int
208lec_open(struct net_device *dev)
209{
210 struct lec_priv *priv = (struct lec_priv *)dev->priv;
211
212 netif_start_queue(dev);
213 memset(&priv->stats,0,sizeof(struct net_device_stats));
214
215 return 0;
216}
217
218static __inline__ void
219lec_send(struct atm_vcc *vcc, struct sk_buff *skb, struct lec_priv *priv)
220{
221 ATM_SKB(skb)->vcc = vcc;
222 ATM_SKB(skb)->atm_options = vcc->atm_options;
223
224 atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
225 if (vcc->send(vcc, skb) < 0) {
226 priv->stats.tx_dropped++;
227 return;
228 }
229
230 priv->stats.tx_packets++;
231 priv->stats.tx_bytes += skb->len;
232}
233
234static void
235lec_tx_timeout(struct net_device *dev)
236{
237 printk(KERN_INFO "%s: tx timeout\n", dev->name);
238 dev->trans_start = jiffies;
239 netif_wake_queue(dev);
240}
241
242static int
243lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
244{
245 struct sk_buff *skb2;
246 struct lec_priv *priv = (struct lec_priv *)dev->priv;
247 struct lecdatahdr_8023 *lec_h;
248 struct atm_vcc *vcc;
249 struct lec_arp_table *entry;
250 unsigned char *dst;
251 int min_frame_size;
252#ifdef CONFIG_TR
253 unsigned char rdesc[ETH_ALEN]; /* Token Ring route descriptor */
254#endif
255 int is_rdesc;
256#if DUMP_PACKETS > 0
257 char buf[300];
258 int i=0;
259#endif /* DUMP_PACKETS >0 */
260
261 DPRINTK("lec_start_xmit called\n");
262 if (!priv->lecd) {
263 printk("%s:No lecd attached\n",dev->name);
264 priv->stats.tx_errors++;
265 netif_stop_queue(dev);
266 return -EUNATCH;
267 }
268
269 DPRINTK("skbuff head:%lx data:%lx tail:%lx end:%lx\n",
270 (long)skb->head, (long)skb->data, (long)skb->tail,
271 (long)skb->end);
272#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
273 if (memcmp(skb->data, bridge_ula_lec, sizeof(bridge_ula_lec)) == 0)
274 lec_handle_bridge(skb, dev);
275#endif
276
277 /* Make sure we have room for lec_id */
278 if (skb_headroom(skb) < 2) {
279
280 DPRINTK("lec_start_xmit: reallocating skb\n");
281 skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
282 kfree_skb(skb);
283 if (skb2 == NULL) return 0;
284 skb = skb2;
285 }
286 skb_push(skb, 2);
287
288 /* Put le header to place, works for TokenRing too */
289 lec_h = (struct lecdatahdr_8023*)skb->data;
290 lec_h->le_header = htons(priv->lecid);
291
292#ifdef CONFIG_TR
293 /* Ugly. Use this to realign Token Ring packets for
294 * e.g. PCA-200E driver. */
295 if (priv->is_trdev) {
296 skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
297 kfree_skb(skb);
298 if (skb2 == NULL) return 0;
299 skb = skb2;
300 }
301#endif
302
303#if DUMP_PACKETS > 0
304 printk("%s: send datalen:%ld lecid:%4.4x\n", dev->name,
305 skb->len, priv->lecid);
306#if DUMP_PACKETS >= 2
307 for(i=0;i<skb->len && i <99;i++) {
308 sprintf(buf+i*3,"%2.2x ",0xff&skb->data[i]);
309 }
310#elif DUMP_PACKETS >= 1
311 for(i=0;i<skb->len && i < 30;i++) {
312 sprintf(buf+i*3,"%2.2x ", 0xff&skb->data[i]);
313 }
314#endif /* DUMP_PACKETS >= 1 */
315 if (i==skb->len)
316 printk("%s\n",buf);
317 else
318 printk("%s...\n",buf);
319#endif /* DUMP_PACKETS > 0 */
320
321 /* Minimum ethernet-frame size */
322#ifdef CONFIG_TR
323 if (priv->is_trdev)
324 min_frame_size = LEC_MINIMUM_8025_SIZE;
325 else
326#endif
327 min_frame_size = LEC_MINIMUM_8023_SIZE;
328 if (skb->len < min_frame_size) {
329 if ((skb->len + skb_tailroom(skb)) < min_frame_size) {
330 skb2 = skb_copy_expand(skb, 0,
331 min_frame_size - skb->truesize, GFP_ATOMIC);
332 dev_kfree_skb(skb);
333 if (skb2 == NULL) {
334 priv->stats.tx_dropped++;
335 return 0;
336 }
337 skb = skb2;
338 }
339 skb_put(skb, min_frame_size - skb->len);
340 }
341
342 /* Send to right vcc */
343 is_rdesc = 0;
344 dst = lec_h->h_dest;
345#ifdef CONFIG_TR
346 if (priv->is_trdev) {
347 dst = get_tr_dst(skb->data+2, rdesc);
348 if (dst == NULL) {
349 dst = rdesc;
350 is_rdesc = 1;
351 }
352 }
353#endif
354 entry = NULL;
355 vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry);
356 DPRINTK("%s:vcc:%p vcc_flags:%x, entry:%p\n", dev->name,
357 vcc, vcc?vcc->flags:0, entry);
358 if (!vcc || !test_bit(ATM_VF_READY,&vcc->flags)) {
359 if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) {
360 DPRINTK("%s:lec_start_xmit: queuing packet, ", dev->name);
361 DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
362 lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
363 lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
364 skb_queue_tail(&entry->tx_wait, skb);
365 } else {
366 DPRINTK("%s:lec_start_xmit: tx queue full or no arp entry, dropping, ", dev->name);
367 DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
368 lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
369 lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
370 priv->stats.tx_dropped++;
371 dev_kfree_skb(skb);
372 }
373 return 0;
374 }
375
376#if DUMP_PACKETS > 0
377 printk("%s:sending to vpi:%d vci:%d\n", dev->name,
378 vcc->vpi, vcc->vci);
379#endif /* DUMP_PACKETS > 0 */
380
381 while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
382 DPRINTK("lec.c: emptying tx queue, ");
383 DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
384 lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
385 lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
386 lec_send(vcc, skb2, priv);
387 }
388
389 lec_send(vcc, skb, priv);
390
391 if (!atm_may_send(vcc, 0)) {
392 struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
393
394 vpriv->xoff = 1;
395 netif_stop_queue(dev);
396
397 /*
398 * vcc->pop() might have occurred in between, making
399 * the vcc usuable again. Since xmit is serialized,
400 * this is the only situation we have to re-test.
401 */
402
403 if (atm_may_send(vcc, 0))
404 netif_wake_queue(dev);
405 }
406
407 dev->trans_start = jiffies;
408 return 0;
409}
410
411/* The inverse routine to net_open(). */
412static int
413lec_close(struct net_device *dev)
414{
415 netif_stop_queue(dev);
416 return 0;
417}
418
419/*
420 * Get the current statistics.
421 * This may be called with the card open or closed.
422 */
423static struct net_device_stats *
424lec_get_stats(struct net_device *dev)
425{
426 return &((struct lec_priv *)dev->priv)->stats;
427}
428
429static int
430lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
431{
432 unsigned long flags;
433 struct net_device *dev = (struct net_device*)vcc->proto_data;
434 struct lec_priv *priv = (struct lec_priv*)dev->priv;
435 struct atmlec_msg *mesg;
436 struct lec_arp_table *entry;
437 int i;
438 char *tmp; /* FIXME */
439
440 atomic_sub(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
441 mesg = (struct atmlec_msg *)skb->data;
442 tmp = skb->data;
443 tmp += sizeof(struct atmlec_msg);
444 DPRINTK("%s: msg from zeppelin:%d\n", dev->name, mesg->type);
445 switch(mesg->type) {
446 case l_set_mac_addr:
447 for (i=0;i<6;i++) {
448 dev->dev_addr[i] = mesg->content.normal.mac_addr[i];
449 }
450 break;
451 case l_del_mac_addr:
452 for(i=0;i<6;i++) {
453 dev->dev_addr[i] = 0;
454 }
455 break;
456 case l_addr_delete:
457 lec_addr_delete(priv, mesg->content.normal.atm_addr,
458 mesg->content.normal.flag);
459 break;
460 case l_topology_change:
461 priv->topology_change = mesg->content.normal.flag;
462 break;
463 case l_flush_complete:
464 lec_flush_complete(priv, mesg->content.normal.flag);
465 break;
466 case l_narp_req: /* LANE2: see 7.1.35 in the lane2 spec */
467 spin_lock_irqsave(&priv->lec_arp_lock, flags);
468 entry = lec_arp_find(priv, mesg->content.normal.mac_addr);
469 lec_arp_remove(priv, entry);
470 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
471
472 if (mesg->content.normal.no_source_le_narp)
473 break;
474 /* FALL THROUGH */
475 case l_arp_update:
476 lec_arp_update(priv, mesg->content.normal.mac_addr,
477 mesg->content.normal.atm_addr,
478 mesg->content.normal.flag,
479 mesg->content.normal.targetless_le_arp);
480 DPRINTK("lec: in l_arp_update\n");
481 if (mesg->sizeoftlvs != 0) { /* LANE2 3.1.5 */
482 DPRINTK("lec: LANE2 3.1.5, got tlvs, size %d\n", mesg->sizeoftlvs);
483 lane2_associate_ind(dev,
484 mesg->content.normal.mac_addr,
485 tmp, mesg->sizeoftlvs);
486 }
487 break;
488 case l_config:
489 priv->maximum_unknown_frame_count =
490 mesg->content.config.maximum_unknown_frame_count;
491 priv->max_unknown_frame_time =
492 (mesg->content.config.max_unknown_frame_time*HZ);
493 priv->max_retry_count =
494 mesg->content.config.max_retry_count;
495 priv->aging_time = (mesg->content.config.aging_time*HZ);
496 priv->forward_delay_time =
497 (mesg->content.config.forward_delay_time*HZ);
498 priv->arp_response_time =
499 (mesg->content.config.arp_response_time*HZ);
500 priv->flush_timeout = (mesg->content.config.flush_timeout*HZ);
501 priv->path_switching_delay =
502 (mesg->content.config.path_switching_delay*HZ);
503 priv->lane_version = mesg->content.config.lane_version; /* LANE2 */
504 priv->lane2_ops = NULL;
505 if (priv->lane_version > 1)
506 priv->lane2_ops = &lane2_ops;
507 if (dev->change_mtu(dev, mesg->content.config.mtu))
508 printk("%s: change_mtu to %d failed\n", dev->name,
509 mesg->content.config.mtu);
510 priv->is_proxy = mesg->content.config.is_proxy;
511 break;
512 case l_flush_tran_id:
513 lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr,
514 mesg->content.normal.flag);
515 break;
516 case l_set_lecid:
517 priv->lecid=(unsigned short)(0xffff&mesg->content.normal.flag);
518 break;
519 case l_should_bridge: {
520#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
521 struct net_bridge_fdb_entry *f;
522
523 DPRINTK("%s: bridge zeppelin asks about 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
524 dev->name,
525 mesg->content.proxy.mac_addr[0], mesg->content.proxy.mac_addr[1],
526 mesg->content.proxy.mac_addr[2], mesg->content.proxy.mac_addr[3],
527 mesg->content.proxy.mac_addr[4], mesg->content.proxy.mac_addr[5]);
528
529 if (br_fdb_get_hook == NULL || dev->br_port == NULL)
530 break;
531
532 f = br_fdb_get_hook(dev->br_port->br, mesg->content.proxy.mac_addr);
533 if (f != NULL &&
534 f->dst->dev != dev &&
535 f->dst->state == BR_STATE_FORWARDING) {
536 /* hit from bridge table, send LE_ARP_RESPONSE */
537 struct sk_buff *skb2;
538 struct sock *sk;
539
540 DPRINTK("%s: entry found, responding to zeppelin\n", dev->name);
541 skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
542 if (skb2 == NULL) {
543 br_fdb_put_hook(f);
544 break;
545 }
546 skb2->len = sizeof(struct atmlec_msg);
547 memcpy(skb2->data, mesg, sizeof(struct atmlec_msg));
548 atm_force_charge(priv->lecd, skb2->truesize);
549 sk = sk_atm(priv->lecd);
550 skb_queue_tail(&sk->sk_receive_queue, skb2);
551 sk->sk_data_ready(sk, skb2->len);
552 }
553 if (f != NULL) br_fdb_put_hook(f);
554#endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */
555 }
556 break;
557 default:
558 printk("%s: Unknown message type %d\n", dev->name, mesg->type);
559 dev_kfree_skb(skb);
560 return -EINVAL;
561 }
562 dev_kfree_skb(skb);
563 return 0;
564}
565
566static void
567lec_atm_close(struct atm_vcc *vcc)
568{
569 struct sk_buff *skb;
570 struct net_device *dev = (struct net_device *)vcc->proto_data;
571 struct lec_priv *priv = (struct lec_priv *)dev->priv;
572
573 priv->lecd = NULL;
574 /* Do something needful? */
575
576 netif_stop_queue(dev);
577 lec_arp_destroy(priv);
578
579 if (skb_peek(&sk_atm(vcc)->sk_receive_queue))
580 printk("%s lec_atm_close: closing with messages pending\n",
581 dev->name);
582 while ((skb = skb_dequeue(&sk_atm(vcc)->sk_receive_queue)) != NULL) {
583 atm_return(vcc, skb->truesize);
584 dev_kfree_skb(skb);
585 }
586
587 printk("%s: Shut down!\n", dev->name);
588 module_put(THIS_MODULE);
589}
590
591static struct atmdev_ops lecdev_ops = {
592 .close = lec_atm_close,
593 .send = lec_atm_send
594};
595
596static struct atm_dev lecatm_dev = {
597 .ops = &lecdev_ops,
598 .type = "lec",
599 .number = 999, /* dummy device number */
600 .lock = SPIN_LOCK_UNLOCKED
601};
602
603/*
604 * LANE2: new argument struct sk_buff *data contains
605 * the LE_ARP based TLVs introduced in the LANE2 spec
606 */
607static int
608send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,
609 unsigned char *mac_addr, unsigned char *atm_addr,
610 struct sk_buff *data)
611{
612 struct sock *sk;
613 struct sk_buff *skb;
614 struct atmlec_msg *mesg;
615
616 if (!priv || !priv->lecd) {
617 return -1;
618 }
619 skb = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
620 if (!skb)
621 return -1;
622 skb->len = sizeof(struct atmlec_msg);
623 mesg = (struct atmlec_msg *)skb->data;
624 memset(mesg, 0, sizeof(struct atmlec_msg));
625 mesg->type = type;
626 if (data != NULL)
627 mesg->sizeoftlvs = data->len;
628 if (mac_addr)
629 memcpy(&mesg->content.normal.mac_addr, mac_addr, ETH_ALEN);
630 else
631 mesg->content.normal.targetless_le_arp = 1;
632 if (atm_addr)
633 memcpy(&mesg->content.normal.atm_addr, atm_addr, ATM_ESA_LEN);
634
635 atm_force_charge(priv->lecd, skb->truesize);
636 sk = sk_atm(priv->lecd);
637 skb_queue_tail(&sk->sk_receive_queue, skb);
638 sk->sk_data_ready(sk, skb->len);
639
640 if (data != NULL) {
641 DPRINTK("lec: about to send %d bytes of data\n", data->len);
642 atm_force_charge(priv->lecd, data->truesize);
643 skb_queue_tail(&sk->sk_receive_queue, data);
644 sk->sk_data_ready(sk, skb->len);
645 }
646
647 return 0;
648}
649
650/* shamelessly stolen from drivers/net/net_init.c */
651static int lec_change_mtu(struct net_device *dev, int new_mtu)
652{
653 if ((new_mtu < 68) || (new_mtu > 18190))
654 return -EINVAL;
655 dev->mtu = new_mtu;
656 return 0;
657}
658
659static void lec_set_multicast_list(struct net_device *dev)
660{
661 /* by default, all multicast frames arrive over the bus.
662 * eventually support selective multicast service
663 */
664 return;
665}
666
667static void
668lec_init(struct net_device *dev)
669{
670 dev->change_mtu = lec_change_mtu;
671 dev->open = lec_open;
672 dev->stop = lec_close;
673 dev->hard_start_xmit = lec_start_xmit;
674 dev->tx_timeout = lec_tx_timeout;
675
676 dev->get_stats = lec_get_stats;
677 dev->set_multicast_list = lec_set_multicast_list;
678 dev->do_ioctl = NULL;
679 printk("%s: Initialized!\n",dev->name);
680 return;
681}
682
683static unsigned char lec_ctrl_magic[] = {
684 0xff,
685 0x00,
686 0x01,
687 0x01 };
688
689static void
690lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
691{
692 struct net_device *dev = (struct net_device *)vcc->proto_data;
693 struct lec_priv *priv = (struct lec_priv *)dev->priv;
694
695#if DUMP_PACKETS >0
696 int i=0;
697 char buf[300];
698
699 printk("%s: lec_push vcc vpi:%d vci:%d\n", dev->name,
700 vcc->vpi, vcc->vci);
701#endif
702 if (!skb) {
703 DPRINTK("%s: null skb\n",dev->name);
704 lec_vcc_close(priv, vcc);
705 return;
706 }
707#if DUMP_PACKETS > 0
708 printk("%s: rcv datalen:%ld lecid:%4.4x\n", dev->name,
709 skb->len, priv->lecid);
710#if DUMP_PACKETS >= 2
711 for(i=0;i<skb->len && i <99;i++) {
712 sprintf(buf+i*3,"%2.2x ",0xff&skb->data[i]);
713 }
714#elif DUMP_PACKETS >= 1
715 for(i=0;i<skb->len && i < 30;i++) {
716 sprintf(buf+i*3,"%2.2x ", 0xff&skb->data[i]);
717 }
718#endif /* DUMP_PACKETS >= 1 */
719 if (i==skb->len)
720 printk("%s\n",buf);
721 else
722 printk("%s...\n",buf);
723#endif /* DUMP_PACKETS > 0 */
724 if (memcmp(skb->data, lec_ctrl_magic, 4) ==0) { /* Control frame, to daemon*/
725 struct sock *sk = sk_atm(vcc);
726
727 DPRINTK("%s: To daemon\n",dev->name);
728 skb_queue_tail(&sk->sk_receive_queue, skb);
729 sk->sk_data_ready(sk, skb->len);
730 } else { /* Data frame, queue to protocol handlers */
731 unsigned char *dst;
732
733 atm_return(vcc,skb->truesize);
734 if (*(uint16_t *)skb->data == htons(priv->lecid) ||
735 !priv->lecd ||
736 !(dev->flags & IFF_UP)) {
737 /* Probably looping back, or if lecd is missing,
738 lecd has gone down */
739 DPRINTK("Ignoring frame...\n");
740 dev_kfree_skb(skb);
741 return;
742 }
743#ifdef CONFIG_TR
744 if (priv->is_trdev) dst = ((struct lecdatahdr_8025 *)skb->data)->h_dest;
745 else
746#endif
747 dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest;
748
749 if (!(dst[0]&0x01) && /* Never filter Multi/Broadcast */
750 !priv->is_proxy && /* Proxy wants all the packets */
751 memcmp(dst, dev->dev_addr, dev->addr_len)) {
752 dev_kfree_skb(skb);
753 return;
754 }
755 if (priv->lec_arp_empty_ones) {
756 lec_arp_check_empties(priv, vcc, skb);
757 }
758 skb->dev = dev;
759 skb_pull(skb, 2); /* skip lec_id */
760#ifdef CONFIG_TR
761 if (priv->is_trdev) skb->protocol = tr_type_trans(skb, dev);
762 else
763#endif
764 skb->protocol = eth_type_trans(skb, dev);
765 priv->stats.rx_packets++;
766 priv->stats.rx_bytes += skb->len;
767 memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
768 netif_rx(skb);
769 }
770}
771
772static void
773lec_pop(struct atm_vcc *vcc, struct sk_buff *skb)
774{
775 struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
776 struct net_device *dev = skb->dev;
777
778 if (vpriv == NULL) {
779 printk("lec_pop(): vpriv = NULL!?!?!?\n");
780 return;
781 }
782
783 vpriv->old_pop(vcc, skb);
784
785 if (vpriv->xoff && atm_may_send(vcc, 0)) {
786 vpriv->xoff = 0;
787 if (netif_running(dev) && netif_queue_stopped(dev))
788 netif_wake_queue(dev);
789 }
790}
791
792static int
793lec_vcc_attach(struct atm_vcc *vcc, void __user *arg)
794{
795 struct lec_vcc_priv *vpriv;
796 int bytes_left;
797 struct atmlec_ioc ioc_data;
798
799 /* Lecd must be up in this case */
800 bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc));
801 if (bytes_left != 0) {
802 printk("lec: lec_vcc_attach, copy from user failed for %d bytes\n",
803 bytes_left);
804 }
805 if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF ||
806 !dev_lec[ioc_data.dev_num])
807 return -EINVAL;
808 if (!(vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL)))
809 return -ENOMEM;
810 vpriv->xoff = 0;
811 vpriv->old_pop = vcc->pop;
812 vcc->user_back = vpriv;
813 vcc->pop = lec_pop;
814 lec_vcc_added(dev_lec[ioc_data.dev_num]->priv,
815 &ioc_data, vcc, vcc->push);
816 vcc->proto_data = dev_lec[ioc_data.dev_num];
817 vcc->push = lec_push;
818 return 0;
819}
820
821static int
822lec_mcast_attach(struct atm_vcc *vcc, int arg)
823{
824 if (arg <0 || arg >= MAX_LEC_ITF || !dev_lec[arg])
825 return -EINVAL;
826 vcc->proto_data = dev_lec[arg];
827 return (lec_mcast_make((struct lec_priv*)dev_lec[arg]->priv, vcc));
828}
829
830/* Initialize device. */
831static int
832lecd_attach(struct atm_vcc *vcc, int arg)
833{
834 int i;
835 struct lec_priv *priv;
836
837 if (arg<0)
838 i = 0;
839 else
840 i = arg;
841#ifdef CONFIG_TR
842 if (arg >= MAX_LEC_ITF)
843 return -EINVAL;
844#else /* Reserve the top NUM_TR_DEVS for TR */
845 if (arg >= (MAX_LEC_ITF-NUM_TR_DEVS))
846 return -EINVAL;
847#endif
848 if (!dev_lec[i]) {
849 int is_trdev, size;
850
851 is_trdev = 0;
852 if (i >= (MAX_LEC_ITF - NUM_TR_DEVS))
853 is_trdev = 1;
854
855 size = sizeof(struct lec_priv);
856#ifdef CONFIG_TR
857 if (is_trdev)
858 dev_lec[i] = alloc_trdev(size);
859 else
860#endif
861 dev_lec[i] = alloc_etherdev(size);
862 if (!dev_lec[i])
863 return -ENOMEM;
864 snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i);
865 if (register_netdev(dev_lec[i])) {
866 free_netdev(dev_lec[i]);
867 return -EINVAL;
868 }
869
870 priv = dev_lec[i]->priv;
871 priv->is_trdev = is_trdev;
872 lec_init(dev_lec[i]);
873 } else {
874 priv = dev_lec[i]->priv;
875 if (priv->lecd)
876 return -EADDRINUSE;
877 }
878 lec_arp_init(priv);
879 priv->itfnum = i; /* LANE2 addition */
880 priv->lecd = vcc;
881 vcc->dev = &lecatm_dev;
882 vcc_insert_socket(sk_atm(vcc));
883
884 vcc->proto_data = dev_lec[i];
885 set_bit(ATM_VF_META,&vcc->flags);
886 set_bit(ATM_VF_READY,&vcc->flags);
887
888 /* Set default values to these variables */
889 priv->maximum_unknown_frame_count = 1;
890 priv->max_unknown_frame_time = (1*HZ);
891 priv->vcc_timeout_period = (1200*HZ);
892 priv->max_retry_count = 1;
893 priv->aging_time = (300*HZ);
894 priv->forward_delay_time = (15*HZ);
895 priv->topology_change = 0;
896 priv->arp_response_time = (1*HZ);
897 priv->flush_timeout = (4*HZ);
898 priv->path_switching_delay = (6*HZ);
899
900 if (dev_lec[i]->flags & IFF_UP) {
901 netif_start_queue(dev_lec[i]);
902 }
903 __module_get(THIS_MODULE);
904 return i;
905}
906
907#ifdef CONFIG_PROC_FS
908static char* lec_arp_get_status_string(unsigned char status)
909{
910 static char *lec_arp_status_string[] = {
911 "ESI_UNKNOWN ",
912 "ESI_ARP_PENDING ",
913 "ESI_VC_PENDING ",
914 "<Undefined> ",
915 "ESI_FLUSH_PENDING ",
916 "ESI_FORWARD_DIRECT"
917 };
918
919 if (status > ESI_FORWARD_DIRECT)
920 status = 3; /* ESI_UNDEFINED */
921 return lec_arp_status_string[status];
922}
923
924static void lec_info(struct seq_file *seq, struct lec_arp_table *entry)
925{
926 int i;
927
928 for (i = 0; i < ETH_ALEN; i++)
929 seq_printf(seq, "%2.2x", entry->mac_addr[i] & 0xff);
930 seq_printf(seq, " ");
931 for (i = 0; i < ATM_ESA_LEN; i++)
932 seq_printf(seq, "%2.2x", entry->atm_addr[i] & 0xff);
933 seq_printf(seq, " %s %4.4x", lec_arp_get_status_string(entry->status),
934 entry->flags & 0xffff);
935 if (entry->vcc)
936 seq_printf(seq, "%3d %3d ", entry->vcc->vpi, entry->vcc->vci);
937 else
938 seq_printf(seq, " ");
939 if (entry->recv_vcc) {
940 seq_printf(seq, " %3d %3d", entry->recv_vcc->vpi,
941 entry->recv_vcc->vci);
942 }
943 seq_putc(seq, '\n');
944}
945
946
947struct lec_state {
948 unsigned long flags;
949 struct lec_priv *locked;
950 struct lec_arp_table *entry;
951 struct net_device *dev;
952 int itf;
953 int arp_table;
954 int misc_table;
955};
956
957static void *lec_tbl_walk(struct lec_state *state, struct lec_arp_table *tbl,
958 loff_t *l)
959{
960 struct lec_arp_table *e = state->entry;
961
962 if (!e)
963 e = tbl;
964 if (e == (void *)1) {
965 e = tbl;
966 --*l;
967 }
968 for (; e; e = e->next) {
969 if (--*l < 0)
970 break;
971 }
972 state->entry = e;
973 return (*l < 0) ? state : NULL;
974}
975
976static void *lec_arp_walk(struct lec_state *state, loff_t *l,
977 struct lec_priv *priv)
978{
979 void *v = NULL;
980 int p;
981
982 for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) {
983 v = lec_tbl_walk(state, priv->lec_arp_tables[p], l);
984 if (v)
985 break;
986 }
987 state->arp_table = p;
988 return v;
989}
990
991static void *lec_misc_walk(struct lec_state *state, loff_t *l,
992 struct lec_priv *priv)
993{
994 struct lec_arp_table *lec_misc_tables[] = {
995 priv->lec_arp_empty_ones,
996 priv->lec_no_forward,
997 priv->mcast_fwds
998 };
999 void *v = NULL;
1000 int q;
1001
1002 for (q = state->misc_table; q < ARRAY_SIZE(lec_misc_tables); q++) {
1003 v = lec_tbl_walk(state, lec_misc_tables[q], l);
1004 if (v)
1005 break;
1006 }
1007 state->misc_table = q;
1008 return v;
1009}
1010
1011static void *lec_priv_walk(struct lec_state *state, loff_t *l,
1012 struct lec_priv *priv)
1013{
1014 if (!state->locked) {
1015 state->locked = priv;
1016 spin_lock_irqsave(&priv->lec_arp_lock, state->flags);
1017 }
1018 if (!lec_arp_walk(state, l, priv) &&
1019 !lec_misc_walk(state, l, priv)) {
1020 spin_unlock_irqrestore(&priv->lec_arp_lock, state->flags);
1021 state->locked = NULL;
1022 /* Partial state reset for the next time we get called */
1023 state->arp_table = state->misc_table = 0;
1024 }
1025 return state->locked;
1026}
1027
1028static void *lec_itf_walk(struct lec_state *state, loff_t *l)
1029{
1030 struct net_device *dev;
1031 void *v;
1032
1033 dev = state->dev ? state->dev : dev_lec[state->itf];
1034 v = (dev && dev->priv) ? lec_priv_walk(state, l, dev->priv) : NULL;
1035 if (!v && dev) {
1036 dev_put(dev);
1037 /* Partial state reset for the next time we get called */
1038 dev = NULL;
1039 }
1040 state->dev = dev;
1041 return v;
1042}
1043
1044static void *lec_get_idx(struct lec_state *state, loff_t l)
1045{
1046 void *v = NULL;
1047
1048 for (; state->itf < MAX_LEC_ITF; state->itf++) {
1049 v = lec_itf_walk(state, &l);
1050 if (v)
1051 break;
1052 }
1053 return v;
1054}
1055
1056static void *lec_seq_start(struct seq_file *seq, loff_t *pos)
1057{
1058 struct lec_state *state = seq->private;
1059
1060 state->itf = 0;
1061 state->dev = NULL;
1062 state->locked = NULL;
1063 state->arp_table = 0;
1064 state->misc_table = 0;
1065 state->entry = (void *)1;
1066
1067 return *pos ? lec_get_idx(state, *pos) : (void*)1;
1068}
1069
1070static void lec_seq_stop(struct seq_file *seq, void *v)
1071{
1072 struct lec_state *state = seq->private;
1073
1074 if (state->dev) {
1075 spin_unlock_irqrestore(&state->locked->lec_arp_lock,
1076 state->flags);
1077 dev_put(state->dev);
1078 }
1079}
1080
1081static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1082{
1083 struct lec_state *state = seq->private;
1084
1085 v = lec_get_idx(state, 1);
1086 *pos += !!PTR_ERR(v);
1087 return v;
1088}
1089
1090static int lec_seq_show(struct seq_file *seq, void *v)
1091{
1092 static char lec_banner[] = "Itf MAC ATM destination"
1093 " Status Flags "
1094 "VPI/VCI Recv VPI/VCI\n";
1095
1096 if (v == (void *)1)
1097 seq_puts(seq, lec_banner);
1098 else {
1099 struct lec_state *state = seq->private;
1100 struct net_device *dev = state->dev;
1101
1102 seq_printf(seq, "%s ", dev->name);
1103 lec_info(seq, state->entry);
1104 }
1105 return 0;
1106}
1107
1108static struct seq_operations lec_seq_ops = {
1109 .start = lec_seq_start,
1110 .next = lec_seq_next,
1111 .stop = lec_seq_stop,
1112 .show = lec_seq_show,
1113};
1114
1115static int lec_seq_open(struct inode *inode, struct file *file)
1116{
1117 struct lec_state *state;
1118 struct seq_file *seq;
1119 int rc = -EAGAIN;
1120
1121 state = kmalloc(sizeof(*state), GFP_KERNEL);
1122 if (!state) {
1123 rc = -ENOMEM;
1124 goto out;
1125 }
1126
1127 rc = seq_open(file, &lec_seq_ops);
1128 if (rc)
1129 goto out_kfree;
1130 seq = file->private_data;
1131 seq->private = state;
1132out:
1133 return rc;
1134
1135out_kfree:
1136 kfree(state);
1137 goto out;
1138}
1139
1140static int lec_seq_release(struct inode *inode, struct file *file)
1141{
1142 return seq_release_private(inode, file);
1143}
1144
1145static struct file_operations lec_seq_fops = {
1146 .owner = THIS_MODULE,
1147 .open = lec_seq_open,
1148 .read = seq_read,
1149 .llseek = seq_lseek,
1150 .release = lec_seq_release,
1151};
1152#endif
1153
1154static int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1155{
1156 struct atm_vcc *vcc = ATM_SD(sock);
1157 int err = 0;
1158
1159 switch (cmd) {
1160 case ATMLEC_CTRL:
1161 case ATMLEC_MCAST:
1162 case ATMLEC_DATA:
1163 if (!capable(CAP_NET_ADMIN))
1164 return -EPERM;
1165 break;
1166 default:
1167 return -ENOIOCTLCMD;
1168 }
1169
1170 switch (cmd) {
1171 case ATMLEC_CTRL:
1172 err = lecd_attach(vcc, (int) arg);
1173 if (err >= 0)
1174 sock->state = SS_CONNECTED;
1175 break;
1176 case ATMLEC_MCAST:
1177 err = lec_mcast_attach(vcc, (int) arg);
1178 break;
1179 case ATMLEC_DATA:
1180 err = lec_vcc_attach(vcc, (void __user *) arg);
1181 break;
1182 }
1183
1184 return err;
1185}
1186
1187static struct atm_ioctl lane_ioctl_ops = {
1188 .owner = THIS_MODULE,
1189 .ioctl = lane_ioctl,
1190};
1191
1192static int __init lane_module_init(void)
1193{
1194#ifdef CONFIG_PROC_FS
1195 struct proc_dir_entry *p;
1196
1197 p = create_proc_entry("lec", S_IRUGO, atm_proc_root);
1198 if (p)
1199 p->proc_fops = &lec_seq_fops;
1200#endif
1201
1202 register_atm_ioctl(&lane_ioctl_ops);
1203 printk("lec.c: " __DATE__ " " __TIME__ " initialized\n");
1204 return 0;
1205}
1206
1207static void __exit lane_module_cleanup(void)
1208{
1209 int i;
1210 struct lec_priv *priv;
1211
1212 remove_proc_entry("lec", atm_proc_root);
1213
1214 deregister_atm_ioctl(&lane_ioctl_ops);
1215
1216 for (i = 0; i < MAX_LEC_ITF; i++) {
1217 if (dev_lec[i] != NULL) {
1218 priv = (struct lec_priv *)dev_lec[i]->priv;
1219 unregister_netdev(dev_lec[i]);
1220 free_netdev(dev_lec[i]);
1221 dev_lec[i] = NULL;
1222 }
1223 }
1224
1225 return;
1226}
1227
1228module_init(lane_module_init);
1229module_exit(lane_module_cleanup);
1230
1231/*
1232 * LANE2: 3.1.3, LE_RESOLVE.request
1233 * Non force allocates memory and fills in *tlvs, fills in *sizeoftlvs.
1234 * If sizeoftlvs == NULL the default TLVs associated with with this
1235 * lec will be used.
1236 * If dst_mac == NULL, targetless LE_ARP will be sent
1237 */
1238static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
1239 u8 **tlvs, u32 *sizeoftlvs)
1240{
1241 unsigned long flags;
1242 struct lec_priv *priv = (struct lec_priv *)dev->priv;
1243 struct lec_arp_table *table;
1244 struct sk_buff *skb;
1245 int retval;
1246
1247 if (force == 0) {
1248 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1249 table = lec_arp_find(priv, dst_mac);
1250 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1251 if(table == NULL)
1252 return -1;
1253
1254 *tlvs = kmalloc(table->sizeoftlvs, GFP_ATOMIC);
1255 if (*tlvs == NULL)
1256 return -1;
1257
1258 memcpy(*tlvs, table->tlvs, table->sizeoftlvs);
1259 *sizeoftlvs = table->sizeoftlvs;
1260
1261 return 0;
1262 }
1263
1264 if (sizeoftlvs == NULL)
1265 retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, NULL);
1266
1267 else {
1268 skb = alloc_skb(*sizeoftlvs, GFP_ATOMIC);
1269 if (skb == NULL)
1270 return -1;
1271 skb->len = *sizeoftlvs;
1272 memcpy(skb->data, *tlvs, *sizeoftlvs);
1273 retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, skb);
1274 }
1275 return retval;
1276}
1277
1278
1279/*
1280 * LANE2: 3.1.4, LE_ASSOCIATE.request
1281 * Associate the *tlvs with the *lan_dst address.
1282 * Will overwrite any previous association
1283 * Returns 1 for success, 0 for failure (out of memory)
1284 *
1285 */
1286static int lane2_associate_req (struct net_device *dev, u8 *lan_dst,
1287 u8 *tlvs, u32 sizeoftlvs)
1288{
1289 int retval;
1290 struct sk_buff *skb;
1291 struct lec_priv *priv = (struct lec_priv*)dev->priv;
1292
1293 if ( memcmp(lan_dst, dev->dev_addr, ETH_ALEN) != 0 )
1294 return (0); /* not our mac address */
1295
1296 kfree(priv->tlvs); /* NULL if there was no previous association */
1297
1298 priv->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);
1299 if (priv->tlvs == NULL)
1300 return (0);
1301 priv->sizeoftlvs = sizeoftlvs;
1302 memcpy(priv->tlvs, tlvs, sizeoftlvs);
1303
1304 skb = alloc_skb(sizeoftlvs, GFP_ATOMIC);
1305 if (skb == NULL)
1306 return 0;
1307 skb->len = sizeoftlvs;
1308 memcpy(skb->data, tlvs, sizeoftlvs);
1309 retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb);
1310 if (retval != 0)
1311 printk("lec.c: lane2_associate_req() failed\n");
1312 /* If the previous association has changed we must
1313 * somehow notify other LANE entities about the change
1314 */
1315 return (1);
1316}
1317
1318/*
1319 * LANE2: 3.1.5, LE_ASSOCIATE.indication
1320 *
1321 */
1322static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr,
1323 u8 *tlvs, u32 sizeoftlvs)
1324{
1325#if 0
1326 int i = 0;
1327#endif
1328 struct lec_priv *priv = (struct lec_priv *)dev->priv;
1329#if 0 /* Why have the TLVs in LE_ARP entries since we do not use them? When you
1330 uncomment this code, make sure the TLVs get freed when entry is killed */
1331 struct lec_arp_table *entry = lec_arp_find(priv, mac_addr);
1332
1333 if (entry == NULL)
1334 return; /* should not happen */
1335
1336 kfree(entry->tlvs);
1337
1338 entry->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);
1339 if (entry->tlvs == NULL)
1340 return;
1341
1342 entry->sizeoftlvs = sizeoftlvs;
1343 memcpy(entry->tlvs, tlvs, sizeoftlvs);
1344#endif
1345#if 0
1346 printk("lec.c: lane2_associate_ind()\n");
1347 printk("dump of tlvs, sizeoftlvs=%d\n", sizeoftlvs);
1348 while (i < sizeoftlvs)
1349 printk("%02x ", tlvs[i++]);
1350
1351 printk("\n");
1352#endif
1353
1354 /* tell MPOA about the TLVs we saw */
1355 if (priv->lane2_ops && priv->lane2_ops->associate_indicator) {
1356 priv->lane2_ops->associate_indicator(dev, mac_addr,
1357 tlvs, sizeoftlvs);
1358 }
1359 return;
1360}
1361
1362/*
1363 * Here starts what used to lec_arpc.c
1364 *
1365 * lec_arpc.c was added here when making
1366 * lane client modular. October 1997
1367 *
1368 */
1369
1370#include <linux/types.h>
1371#include <linux/sched.h>
1372#include <linux/timer.h>
1373#include <asm/param.h>
1374#include <asm/atomic.h>
1375#include <linux/inetdevice.h>
1376#include <net/route.h>
1377
1378
1379#if 0
1380#define DPRINTK(format,args...)
1381/*
1382#define DPRINTK printk
1383*/
1384#endif
1385#define DEBUG_ARP_TABLE 0
1386
1387#define LEC_ARP_REFRESH_INTERVAL (3*HZ)
1388
1389static void lec_arp_check_expire(unsigned long data);
1390static void lec_arp_expire_arp(unsigned long data);
1391
1392/*
1393 * Arp table funcs
1394 */
1395
1396#define HASH(ch) (ch & (LEC_ARP_TABLE_SIZE -1))
1397
1398/*
1399 * Initialization of arp-cache
1400 */
1401static void
1402lec_arp_init(struct lec_priv *priv)
1403{
1404 unsigned short i;
1405
1406 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1407 priv->lec_arp_tables[i] = NULL;
1408 }
1409 spin_lock_init(&priv->lec_arp_lock);
1410 init_timer(&priv->lec_arp_timer);
1411 priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL;
1412 priv->lec_arp_timer.data = (unsigned long)priv;
1413 priv->lec_arp_timer.function = lec_arp_check_expire;
1414 add_timer(&priv->lec_arp_timer);
1415}
1416
1417static void
1418lec_arp_clear_vccs(struct lec_arp_table *entry)
1419{
1420 if (entry->vcc) {
1421 struct atm_vcc *vcc = entry->vcc;
1422 struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
1423 struct net_device *dev = (struct net_device*) vcc->proto_data;
1424
1425 vcc->pop = vpriv->old_pop;
1426 if (vpriv->xoff)
1427 netif_wake_queue(dev);
1428 kfree(vpriv);
1429 vcc->user_back = NULL;
1430 vcc->push = entry->old_push;
1431 vcc_release_async(vcc, -EPIPE);
1432 vcc = NULL;
1433 }
1434 if (entry->recv_vcc) {
1435 entry->recv_vcc->push = entry->old_recv_push;
1436 vcc_release_async(entry->recv_vcc, -EPIPE);
1437 entry->recv_vcc = NULL;
1438 }
1439}
1440
1441/*
1442 * Insert entry to lec_arp_table
1443 * LANE2: Add to the end of the list to satisfy 8.1.13
1444 */
1445static inline void
1446lec_arp_add(struct lec_priv *priv, struct lec_arp_table *to_add)
1447{
1448 unsigned short place;
1449 struct lec_arp_table *tmp;
1450
1451 place = HASH(to_add->mac_addr[ETH_ALEN-1]);
1452 tmp = priv->lec_arp_tables[place];
1453 to_add->next = NULL;
1454 if (tmp == NULL)
1455 priv->lec_arp_tables[place] = to_add;
1456
1457 else { /* add to the end */
1458 while (tmp->next)
1459 tmp = tmp->next;
1460 tmp->next = to_add;
1461 }
1462
1463 DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
1464 0xff&to_add->mac_addr[0], 0xff&to_add->mac_addr[1],
1465 0xff&to_add->mac_addr[2], 0xff&to_add->mac_addr[3],
1466 0xff&to_add->mac_addr[4], 0xff&to_add->mac_addr[5]);
1467}
1468
1469/*
1470 * Remove entry from lec_arp_table
1471 */
1472static int
1473lec_arp_remove(struct lec_priv *priv,
1474 struct lec_arp_table *to_remove)
1475{
1476 unsigned short place;
1477 struct lec_arp_table *tmp;
1478 int remove_vcc=1;
1479
1480 if (!to_remove) {
1481 return -1;
1482 }
1483 place = HASH(to_remove->mac_addr[ETH_ALEN-1]);
1484 tmp = priv->lec_arp_tables[place];
1485 if (tmp == to_remove) {
1486 priv->lec_arp_tables[place] = tmp->next;
1487 } else {
1488 while(tmp && tmp->next != to_remove) {
1489 tmp = tmp->next;
1490 }
1491 if (!tmp) {/* Entry was not found */
1492 return -1;
1493 }
1494 }
1495 tmp->next = to_remove->next;
1496 del_timer(&to_remove->timer);
1497
1498 /* If this is the only MAC connected to this VCC, also tear down
1499 the VCC */
1500 if (to_remove->status >= ESI_FLUSH_PENDING) {
1501 /*
1502 * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT
1503 */
1504 for(place = 0; place < LEC_ARP_TABLE_SIZE; place++) {
1505 for(tmp = priv->lec_arp_tables[place]; tmp != NULL; tmp = tmp->next) {
1506 if (memcmp(tmp->atm_addr, to_remove->atm_addr,
1507 ATM_ESA_LEN)==0) {
1508 remove_vcc=0;
1509 break;
1510 }
1511 }
1512 }
1513 if (remove_vcc)
1514 lec_arp_clear_vccs(to_remove);
1515 }
1516 skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */
1517
1518 DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
1519 0xff&to_remove->mac_addr[0], 0xff&to_remove->mac_addr[1],
1520 0xff&to_remove->mac_addr[2], 0xff&to_remove->mac_addr[3],
1521 0xff&to_remove->mac_addr[4], 0xff&to_remove->mac_addr[5]);
1522 return 0;
1523}
1524
1525#if DEBUG_ARP_TABLE
1526static char*
1527get_status_string(unsigned char st)
1528{
1529 switch(st) {
1530 case ESI_UNKNOWN:
1531 return "ESI_UNKNOWN";
1532 case ESI_ARP_PENDING:
1533 return "ESI_ARP_PENDING";
1534 case ESI_VC_PENDING:
1535 return "ESI_VC_PENDING";
1536 case ESI_FLUSH_PENDING:
1537 return "ESI_FLUSH_PENDING";
1538 case ESI_FORWARD_DIRECT:
1539 return "ESI_FORWARD_DIRECT";
1540 default:
1541 return "<UNKNOWN>";
1542 }
1543}
1544#endif
1545
1546static void
1547dump_arp_table(struct lec_priv *priv)
1548{
1549#if DEBUG_ARP_TABLE
1550 int i,j, offset;
1551 struct lec_arp_table *rulla;
1552 char buf[1024];
1553 struct lec_arp_table **lec_arp_tables =
1554 (struct lec_arp_table **)priv->lec_arp_tables;
1555 struct lec_arp_table *lec_arp_empty_ones =
1556 (struct lec_arp_table *)priv->lec_arp_empty_ones;
1557 struct lec_arp_table *lec_no_forward =
1558 (struct lec_arp_table *)priv->lec_no_forward;
1559 struct lec_arp_table *mcast_fwds = priv->mcast_fwds;
1560
1561
1562 printk("Dump %p:\n",priv);
1563 for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {
1564 rulla = lec_arp_tables[i];
1565 offset = 0;
1566 offset += sprintf(buf,"%d: %p\n",i, rulla);
1567 while (rulla) {
1568 offset += sprintf(buf+offset,"Mac:");
1569 for(j=0;j<ETH_ALEN;j++) {
1570 offset+=sprintf(buf+offset,
1571 "%2.2x ",
1572 rulla->mac_addr[j]&0xff);
1573 }
1574 offset +=sprintf(buf+offset,"Atm:");
1575 for(j=0;j<ATM_ESA_LEN;j++) {
1576 offset+=sprintf(buf+offset,
1577 "%2.2x ",
1578 rulla->atm_addr[j]&0xff);
1579 }
1580 offset+=sprintf(buf+offset,
1581 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
1582 rulla->vcc?rulla->vcc->vpi:0,
1583 rulla->vcc?rulla->vcc->vci:0,
1584 rulla->recv_vcc?rulla->recv_vcc->vpi:0,
1585 rulla->recv_vcc?rulla->recv_vcc->vci:0,
1586 rulla->last_used,
1587 rulla->timestamp, rulla->no_tries);
1588 offset+=sprintf(buf+offset,
1589 "Flags:%x, Packets_flooded:%x, Status: %s ",
1590 rulla->flags, rulla->packets_flooded,
1591 get_status_string(rulla->status));
1592 offset+=sprintf(buf+offset,"->%p\n",rulla->next);
1593 rulla = rulla->next;
1594 }
1595 printk("%s",buf);
1596 }
1597 rulla = lec_no_forward;
1598 if (rulla)
1599 printk("No forward\n");
1600 while(rulla) {
1601 offset=0;
1602 offset += sprintf(buf+offset,"Mac:");
1603 for(j=0;j<ETH_ALEN;j++) {
1604 offset+=sprintf(buf+offset,"%2.2x ",
1605 rulla->mac_addr[j]&0xff);
1606 }
1607 offset +=sprintf(buf+offset,"Atm:");
1608 for(j=0;j<ATM_ESA_LEN;j++) {
1609 offset+=sprintf(buf+offset,"%2.2x ",
1610 rulla->atm_addr[j]&0xff);
1611 }
1612 offset+=sprintf(buf+offset,
1613 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
1614 rulla->vcc?rulla->vcc->vpi:0,
1615 rulla->vcc?rulla->vcc->vci:0,
1616 rulla->recv_vcc?rulla->recv_vcc->vpi:0,
1617 rulla->recv_vcc?rulla->recv_vcc->vci:0,
1618 rulla->last_used,
1619 rulla->timestamp, rulla->no_tries);
1620 offset+=sprintf(buf+offset,
1621 "Flags:%x, Packets_flooded:%x, Status: %s ",
1622 rulla->flags, rulla->packets_flooded,
1623 get_status_string(rulla->status));
1624 offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);
1625 rulla = rulla->next;
1626 printk("%s",buf);
1627 }
1628 rulla = lec_arp_empty_ones;
1629 if (rulla)
1630 printk("Empty ones\n");
1631 while(rulla) {
1632 offset=0;
1633 offset += sprintf(buf+offset,"Mac:");
1634 for(j=0;j<ETH_ALEN;j++) {
1635 offset+=sprintf(buf+offset,"%2.2x ",
1636 rulla->mac_addr[j]&0xff);
1637 }
1638 offset +=sprintf(buf+offset,"Atm:");
1639 for(j=0;j<ATM_ESA_LEN;j++) {
1640 offset+=sprintf(buf+offset,"%2.2x ",
1641 rulla->atm_addr[j]&0xff);
1642 }
1643 offset+=sprintf(buf+offset,
1644 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
1645 rulla->vcc?rulla->vcc->vpi:0,
1646 rulla->vcc?rulla->vcc->vci:0,
1647 rulla->recv_vcc?rulla->recv_vcc->vpi:0,
1648 rulla->recv_vcc?rulla->recv_vcc->vci:0,
1649 rulla->last_used,
1650 rulla->timestamp, rulla->no_tries);
1651 offset+=sprintf(buf+offset,
1652 "Flags:%x, Packets_flooded:%x, Status: %s ",
1653 rulla->flags, rulla->packets_flooded,
1654 get_status_string(rulla->status));
1655 offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);
1656 rulla = rulla->next;
1657 printk("%s",buf);
1658 }
1659
1660 rulla = mcast_fwds;
1661 if (rulla)
1662 printk("Multicast Forward VCCs\n");
1663 while(rulla) {
1664 offset=0;
1665 offset += sprintf(buf+offset,"Mac:");
1666 for(j=0;j<ETH_ALEN;j++) {
1667 offset+=sprintf(buf+offset,"%2.2x ",
1668 rulla->mac_addr[j]&0xff);
1669 }
1670 offset +=sprintf(buf+offset,"Atm:");
1671 for(j=0;j<ATM_ESA_LEN;j++) {
1672 offset+=sprintf(buf+offset,"%2.2x ",
1673 rulla->atm_addr[j]&0xff);
1674 }
1675 offset+=sprintf(buf+offset,
1676 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
1677 rulla->vcc?rulla->vcc->vpi:0,
1678 rulla->vcc?rulla->vcc->vci:0,
1679 rulla->recv_vcc?rulla->recv_vcc->vpi:0,
1680 rulla->recv_vcc?rulla->recv_vcc->vci:0,
1681 rulla->last_used,
1682 rulla->timestamp, rulla->no_tries);
1683 offset+=sprintf(buf+offset,
1684 "Flags:%x, Packets_flooded:%x, Status: %s ",
1685 rulla->flags, rulla->packets_flooded,
1686 get_status_string(rulla->status));
1687 offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);
1688 rulla = rulla->next;
1689 printk("%s",buf);
1690 }
1691
1692#endif
1693}
1694
1695/*
1696 * Destruction of arp-cache
1697 */
1698static void
1699lec_arp_destroy(struct lec_priv *priv)
1700{
1701 unsigned long flags;
1702 struct lec_arp_table *entry, *next;
1703 int i;
1704
1705 del_timer_sync(&priv->lec_arp_timer);
1706
1707 /*
1708 * Remove all entries
1709 */
1710
1711 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1712 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1713 for(entry = priv->lec_arp_tables[i]; entry != NULL; entry=next) {
1714 next = entry->next;
1715 lec_arp_remove(priv, entry);
1716 kfree(entry);
1717 }
1718 }
1719 entry = priv->lec_arp_empty_ones;
1720 while(entry) {
1721 next = entry->next;
1722 del_timer_sync(&entry->timer);
1723 lec_arp_clear_vccs(entry);
1724 kfree(entry);
1725 entry = next;
1726 }
1727 priv->lec_arp_empty_ones = NULL;
1728 entry = priv->lec_no_forward;
1729 while(entry) {
1730 next = entry->next;
1731 del_timer_sync(&entry->timer);
1732 lec_arp_clear_vccs(entry);
1733 kfree(entry);
1734 entry = next;
1735 }
1736 priv->lec_no_forward = NULL;
1737 entry = priv->mcast_fwds;
1738 while(entry) {
1739 next = entry->next;
1740 /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
1741 lec_arp_clear_vccs(entry);
1742 kfree(entry);
1743 entry = next;
1744 }
1745 priv->mcast_fwds = NULL;
1746 priv->mcast_vcc = NULL;
1747 memset(priv->lec_arp_tables, 0,
1748 sizeof(struct lec_arp_table *) * LEC_ARP_TABLE_SIZE);
1749 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1750}
1751
1752
1753/*
1754 * Find entry by mac_address
1755 */
1756static struct lec_arp_table*
1757lec_arp_find(struct lec_priv *priv,
1758 unsigned char *mac_addr)
1759{
1760 unsigned short place;
1761 struct lec_arp_table *to_return;
1762
1763 DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
1764 mac_addr[0]&0xff, mac_addr[1]&0xff, mac_addr[2]&0xff,
1765 mac_addr[3]&0xff, mac_addr[4]&0xff, mac_addr[5]&0xff);
1766 place = HASH(mac_addr[ETH_ALEN-1]);
1767
1768 to_return = priv->lec_arp_tables[place];
1769 while(to_return) {
1770 if (memcmp(mac_addr, to_return->mac_addr, ETH_ALEN) == 0) {
1771 return to_return;
1772 }
1773 to_return = to_return->next;
1774 }
1775 return NULL;
1776}
1777
1778static struct lec_arp_table*
1779make_entry(struct lec_priv *priv, unsigned char *mac_addr)
1780{
1781 struct lec_arp_table *to_return;
1782
1783 to_return = (struct lec_arp_table *) kmalloc(sizeof(struct lec_arp_table),
1784 GFP_ATOMIC);
1785 if (!to_return) {
1786 printk("LEC: Arp entry kmalloc failed\n");
1787 return NULL;
1788 }
1789 memset(to_return, 0, sizeof(struct lec_arp_table));
1790 memcpy(to_return->mac_addr, mac_addr, ETH_ALEN);
1791 init_timer(&to_return->timer);
1792 to_return->timer.function = lec_arp_expire_arp;
1793 to_return->timer.data = (unsigned long) to_return;
1794 to_return->last_used = jiffies;
1795 to_return->priv = priv;
1796 skb_queue_head_init(&to_return->tx_wait);
1797 return to_return;
1798}
1799
1800/*
1801 *
1802 * Arp sent timer expired
1803 *
1804 */
1805static void
1806lec_arp_expire_arp(unsigned long data)
1807{
1808 struct lec_arp_table *entry;
1809
1810 entry = (struct lec_arp_table *)data;
1811
1812 DPRINTK("lec_arp_expire_arp\n");
1813 if (entry->status == ESI_ARP_PENDING) {
1814 if (entry->no_tries <= entry->priv->max_retry_count) {
1815 if (entry->is_rdesc)
1816 send_to_lecd(entry->priv, l_rdesc_arp_xmt, entry->mac_addr, NULL, NULL);
1817 else
1818 send_to_lecd(entry->priv, l_arp_xmt, entry->mac_addr, NULL, NULL);
1819 entry->no_tries++;
1820 }
1821 mod_timer(&entry->timer, jiffies + (1*HZ));
1822 }
1823}
1824
1825/*
1826 *
1827 * Unknown/unused vcc expire, remove associated entry
1828 *
1829 */
1830static void
1831lec_arp_expire_vcc(unsigned long data)
1832{
1833 unsigned long flags;
1834 struct lec_arp_table *to_remove = (struct lec_arp_table*)data;
1835 struct lec_priv *priv = (struct lec_priv *)to_remove->priv;
1836 struct lec_arp_table *entry = NULL;
1837
1838 del_timer(&to_remove->timer);
1839
1840 DPRINTK("LEC_ARP %p %p: lec_arp_expire_vcc vpi:%d vci:%d\n",
1841 to_remove, priv,
1842 to_remove->vcc?to_remove->recv_vcc->vpi:0,
1843 to_remove->vcc?to_remove->recv_vcc->vci:0);
1844 DPRINTK("eo:%p nf:%p\n",priv->lec_arp_empty_ones,priv->lec_no_forward);
1845
1846 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1847 if (to_remove == priv->lec_arp_empty_ones)
1848 priv->lec_arp_empty_ones = to_remove->next;
1849 else {
1850 entry = priv->lec_arp_empty_ones;
1851 while (entry && entry->next != to_remove)
1852 entry = entry->next;
1853 if (entry)
1854 entry->next = to_remove->next;
1855 }
1856 if (!entry) {
1857 if (to_remove == priv->lec_no_forward) {
1858 priv->lec_no_forward = to_remove->next;
1859 } else {
1860 entry = priv->lec_no_forward;
1861 while (entry && entry->next != to_remove)
1862 entry = entry->next;
1863 if (entry)
1864 entry->next = to_remove->next;
1865 }
1866 }
1867 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1868
1869 lec_arp_clear_vccs(to_remove);
1870 kfree(to_remove);
1871}
1872
1873/*
1874 * Expire entries.
1875 * 1. Re-set timer
1876 * 2. For each entry, delete entries that have aged past the age limit.
1877 * 3. For each entry, depending on the status of the entry, perform
1878 * the following maintenance.
1879 * a. If status is ESI_VC_PENDING or ESI_ARP_PENDING then if the
1880 * tick_count is above the max_unknown_frame_time, clear
1881 * the tick_count to zero and clear the packets_flooded counter
1882 * to zero. This supports the packet rate limit per address
1883 * while flooding unknowns.
1884 * b. If the status is ESI_FLUSH_PENDING and the tick_count is greater
1885 * than or equal to the path_switching_delay, change the status
1886 * to ESI_FORWARD_DIRECT. This causes the flush period to end
1887 * regardless of the progress of the flush protocol.
1888 */
1889static void
1890lec_arp_check_expire(unsigned long data)
1891{
1892 unsigned long flags;
1893 struct lec_priv *priv = (struct lec_priv *)data;
1894 struct lec_arp_table *entry, *next;
1895 unsigned long now;
1896 unsigned long time_to_check;
1897 int i;
1898
1899 DPRINTK("lec_arp_check_expire %p\n",priv);
1900 DPRINTK("expire: eo:%p nf:%p\n",priv->lec_arp_empty_ones,
1901 priv->lec_no_forward);
1902 now = jiffies;
1903 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1904 for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1905 for(entry = priv->lec_arp_tables[i]; entry != NULL; ) {
1906 if ((entry->flags) & LEC_REMOTE_FLAG &&
1907 priv->topology_change)
1908 time_to_check = priv->forward_delay_time;
1909 else
1910 time_to_check = priv->aging_time;
1911
1912 DPRINTK("About to expire: %lx - %lx > %lx\n",
1913 now,entry->last_used, time_to_check);
1914 if( time_after(now, entry->last_used+
1915 time_to_check) &&
1916 !(entry->flags & LEC_PERMANENT_FLAG) &&
1917 !(entry->mac_addr[0] & 0x01) ) { /* LANE2: 7.1.20 */
1918 /* Remove entry */
1919 DPRINTK("LEC:Entry timed out\n");
1920 next = entry->next;
1921 lec_arp_remove(priv, entry);
1922 kfree(entry);
1923 entry = next;
1924 } else {
1925 /* Something else */
1926 if ((entry->status == ESI_VC_PENDING ||
1927 entry->status == ESI_ARP_PENDING)
1928 && time_after_eq(now,
1929 entry->timestamp +
1930 priv->max_unknown_frame_time)) {
1931 entry->timestamp = jiffies;
1932 entry->packets_flooded = 0;
1933 if (entry->status == ESI_VC_PENDING)
1934 send_to_lecd(priv, l_svc_setup, entry->mac_addr, entry->atm_addr, NULL);
1935 }
1936 if (entry->status == ESI_FLUSH_PENDING
1937 &&
1938 time_after_eq(now, entry->timestamp+
1939 priv->path_switching_delay)) {
1940 struct sk_buff *skb;
1941
1942 while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
1943 lec_send(entry->vcc, skb, entry->priv);
1944 entry->last_used = jiffies;
1945 entry->status =
1946 ESI_FORWARD_DIRECT;
1947 }
1948 entry = entry->next;
1949 }
1950 }
1951 }
1952 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1953
1954 mod_timer(&priv->lec_arp_timer, jiffies + LEC_ARP_REFRESH_INTERVAL);
1955}
1956/*
1957 * Try to find vcc where mac_address is attached.
1958 *
1959 */
1960static struct atm_vcc*
1961lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find,
1962 int is_rdesc, struct lec_arp_table **ret_entry)
1963{
1964 unsigned long flags;
1965 struct lec_arp_table *entry;
1966 struct atm_vcc *found;
1967
1968 if (mac_to_find[0] & 0x01) {
1969 switch (priv->lane_version) {
1970 case 1:
1971 return priv->mcast_vcc;
1972 break;
1973 case 2: /* LANE2 wants arp for multicast addresses */
1974 if ( memcmp(mac_to_find, bus_mac, ETH_ALEN) == 0)
1975 return priv->mcast_vcc;
1976 break;
1977 default:
1978 break;
1979 }
1980 }
1981
1982 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1983 entry = lec_arp_find(priv, mac_to_find);
1984
1985 if (entry) {
1986 if (entry->status == ESI_FORWARD_DIRECT) {
1987 /* Connection Ok */
1988 entry->last_used = jiffies;
1989 *ret_entry = entry;
1990 found = entry->vcc;
1991 goto out;
1992 }
1993 /* Data direct VC not yet set up, check to see if the unknown
1994 frame count is greater than the limit. If the limit has
1995 not been reached, allow the caller to send packet to
1996 BUS. */
1997 if (entry->status != ESI_FLUSH_PENDING &&
1998 entry->packets_flooded<priv->maximum_unknown_frame_count) {
1999 entry->packets_flooded++;
2000 DPRINTK("LEC_ARP: Flooding..\n");
2001 found = priv->mcast_vcc;
2002 goto out;
2003 }
2004 /* We got here because entry->status == ESI_FLUSH_PENDING
2005 * or BUS flood limit was reached for an entry which is
2006 * in ESI_ARP_PENDING or ESI_VC_PENDING state.
2007 */
2008 *ret_entry = entry;
2009 DPRINTK("lec: entry->status %d entry->vcc %p\n", entry->status, entry->vcc);
2010 found = NULL;
2011 } else {
2012 /* No matching entry was found */
2013 entry = make_entry(priv, mac_to_find);
2014 DPRINTK("LEC_ARP: Making entry\n");
2015 if (!entry) {
2016 found = priv->mcast_vcc;
2017 goto out;
2018 }
2019 lec_arp_add(priv, entry);
2020 /* We want arp-request(s) to be sent */
2021 entry->packets_flooded =1;
2022 entry->status = ESI_ARP_PENDING;
2023 entry->no_tries = 1;
2024 entry->last_used = entry->timestamp = jiffies;
2025 entry->is_rdesc = is_rdesc;
2026 if (entry->is_rdesc)
2027 send_to_lecd(priv, l_rdesc_arp_xmt, mac_to_find, NULL, NULL);
2028 else
2029 send_to_lecd(priv, l_arp_xmt, mac_to_find, NULL, NULL);
2030 entry->timer.expires = jiffies + (1*HZ);
2031 entry->timer.function = lec_arp_expire_arp;
2032 add_timer(&entry->timer);
2033 found = priv->mcast_vcc;
2034 }
2035
2036out:
2037 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2038 return found;
2039}
2040
2041static int
2042lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
2043 unsigned long permanent)
2044{
2045 unsigned long flags;
2046 struct lec_arp_table *entry, *next;
2047 int i;
2048
2049 DPRINTK("lec_addr_delete\n");
2050 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2051 for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2052 for(entry = priv->lec_arp_tables[i]; entry != NULL; entry = next) {
2053 next = entry->next;
2054 if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)
2055 && (permanent ||
2056 !(entry->flags & LEC_PERMANENT_FLAG))) {
2057 lec_arp_remove(priv, entry);
2058 kfree(entry);
2059 }
2060 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2061 return 0;
2062 }
2063 }
2064 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2065 return -1;
2066}
2067
2068/*
2069 * Notifies: Response to arp_request (atm_addr != NULL)
2070 */
2071static void
2072lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
2073 unsigned char *atm_addr, unsigned long remoteflag,
2074 unsigned int targetless_le_arp)
2075{
2076 unsigned long flags;
2077 struct lec_arp_table *entry, *tmp;
2078 int i;
2079
2080 DPRINTK("lec:%s", (targetless_le_arp) ? "targetless ": " ");
2081 DPRINTK("lec_arp_update mac:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
2082 mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],
2083 mac_addr[4],mac_addr[5]);
2084
2085 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2086 entry = lec_arp_find(priv, mac_addr);
2087 if (entry == NULL && targetless_le_arp)
2088 goto out; /* LANE2: ignore targetless LE_ARPs for which
2089 * we have no entry in the cache. 7.1.30
2090 */
2091 if (priv->lec_arp_empty_ones) {
2092 entry = priv->lec_arp_empty_ones;
2093 if (!memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN)) {
2094 priv->lec_arp_empty_ones = entry->next;
2095 } else {
2096 while(entry->next && memcmp(entry->next->atm_addr,
2097 atm_addr, ATM_ESA_LEN))
2098 entry = entry->next;
2099 if (entry->next) {
2100 tmp = entry;
2101 entry = entry->next;
2102 tmp->next = entry->next;
2103 } else
2104 entry = NULL;
2105
2106 }
2107 if (entry) {
2108 del_timer(&entry->timer);
2109 tmp = lec_arp_find(priv, mac_addr);
2110 if (tmp) {
2111 del_timer(&tmp->timer);
2112 tmp->status = ESI_FORWARD_DIRECT;
2113 memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN);
2114 tmp->vcc = entry->vcc;
2115 tmp->old_push = entry->old_push;
2116 tmp->last_used = jiffies;
2117 del_timer(&entry->timer);
2118 kfree(entry);
2119 entry=tmp;
2120 } else {
2121 entry->status = ESI_FORWARD_DIRECT;
2122 memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
2123 entry->last_used = jiffies;
2124 lec_arp_add(priv, entry);
2125 }
2126 if (remoteflag)
2127 entry->flags|=LEC_REMOTE_FLAG;
2128 else
2129 entry->flags&=~LEC_REMOTE_FLAG;
2130 DPRINTK("After update\n");
2131 dump_arp_table(priv);
2132 goto out;
2133 }
2134 }
2135 entry = lec_arp_find(priv, mac_addr);
2136 if (!entry) {
2137 entry = make_entry(priv, mac_addr);
2138 if (!entry)
2139 goto out;
2140 entry->status = ESI_UNKNOWN;
2141 lec_arp_add(priv, entry);
2142 /* Temporary, changes before end of function */
2143 }
2144 memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN);
2145 del_timer(&entry->timer);
2146 for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2147 for(tmp = priv->lec_arp_tables[i]; tmp; tmp=tmp->next) {
2148 if (entry != tmp &&
2149 !memcmp(tmp->atm_addr, atm_addr,
2150 ATM_ESA_LEN)) {
2151 /* Vcc to this host exists */
2152 if (tmp->status > ESI_VC_PENDING) {
2153 /*
2154 * ESI_FLUSH_PENDING,
2155 * ESI_FORWARD_DIRECT
2156 */
2157 entry->vcc = tmp->vcc;
2158 entry->old_push=tmp->old_push;
2159 }
2160 entry->status=tmp->status;
2161 break;
2162 }
2163 }
2164 }
2165 if (remoteflag)
2166 entry->flags|=LEC_REMOTE_FLAG;
2167 else
2168 entry->flags&=~LEC_REMOTE_FLAG;
2169 if (entry->status == ESI_ARP_PENDING ||
2170 entry->status == ESI_UNKNOWN) {
2171 entry->status = ESI_VC_PENDING;
2172 send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL);
2173 }
2174 DPRINTK("After update2\n");
2175 dump_arp_table(priv);
2176out:
2177 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2178}
2179
2180/*
2181 * Notifies: Vcc setup ready
2182 */
2183static void
2184lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
2185 struct atm_vcc *vcc,
2186 void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb))
2187{
2188 unsigned long flags;
2189 struct lec_arp_table *entry;
2190 int i, found_entry=0;
2191
2192 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2193 if (ioc_data->receive == 2) {
2194 /* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */
2195
2196 DPRINTK("LEC_ARP: Attaching mcast forward\n");
2197#if 0
2198 entry = lec_arp_find(priv, bus_mac);
2199 if (!entry) {
2200 printk("LEC_ARP: Multicast entry not found!\n");
2201 goto out;
2202 }
2203 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
2204 entry->recv_vcc = vcc;
2205 entry->old_recv_push = old_push;
2206#endif
2207 entry = make_entry(priv, bus_mac);
2208 if (entry == NULL)
2209 goto out;
2210 del_timer(&entry->timer);
2211 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
2212 entry->recv_vcc = vcc;
2213 entry->old_recv_push = old_push;
2214 entry->next = priv->mcast_fwds;
2215 priv->mcast_fwds = entry;
2216 goto out;
2217 } else if (ioc_data->receive == 1) {
2218 /* Vcc which we don't want to make default vcc, attach it
2219 anyway. */
2220 DPRINTK("LEC_ARP:Attaching data direct, not default :%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
2221 ioc_data->atm_addr[0],ioc_data->atm_addr[1],
2222 ioc_data->atm_addr[2],ioc_data->atm_addr[3],
2223 ioc_data->atm_addr[4],ioc_data->atm_addr[5],
2224 ioc_data->atm_addr[6],ioc_data->atm_addr[7],
2225 ioc_data->atm_addr[8],ioc_data->atm_addr[9],
2226 ioc_data->atm_addr[10],ioc_data->atm_addr[11],
2227 ioc_data->atm_addr[12],ioc_data->atm_addr[13],
2228 ioc_data->atm_addr[14],ioc_data->atm_addr[15],
2229 ioc_data->atm_addr[16],ioc_data->atm_addr[17],
2230 ioc_data->atm_addr[18],ioc_data->atm_addr[19]);
2231 entry = make_entry(priv, bus_mac);
2232 if (entry == NULL)
2233 goto out;
2234 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
2235 memset(entry->mac_addr, 0, ETH_ALEN);
2236 entry->recv_vcc = vcc;
2237 entry->old_recv_push = old_push;
2238 entry->status = ESI_UNKNOWN;
2239 entry->timer.expires = jiffies + priv->vcc_timeout_period;
2240 entry->timer.function = lec_arp_expire_vcc;
2241 add_timer(&entry->timer);
2242 entry->next = priv->lec_no_forward;
2243 priv->lec_no_forward = entry;
2244 dump_arp_table(priv);
2245 goto out;
2246 }
2247 DPRINTK("LEC_ARP:Attaching data direct, default:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
2248 ioc_data->atm_addr[0],ioc_data->atm_addr[1],
2249 ioc_data->atm_addr[2],ioc_data->atm_addr[3],
2250 ioc_data->atm_addr[4],ioc_data->atm_addr[5],
2251 ioc_data->atm_addr[6],ioc_data->atm_addr[7],
2252 ioc_data->atm_addr[8],ioc_data->atm_addr[9],
2253 ioc_data->atm_addr[10],ioc_data->atm_addr[11],
2254 ioc_data->atm_addr[12],ioc_data->atm_addr[13],
2255 ioc_data->atm_addr[14],ioc_data->atm_addr[15],
2256 ioc_data->atm_addr[16],ioc_data->atm_addr[17],
2257 ioc_data->atm_addr[18],ioc_data->atm_addr[19]);
2258 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2259 for (entry = priv->lec_arp_tables[i]; entry; entry=entry->next) {
2260 if (memcmp(ioc_data->atm_addr, entry->atm_addr,
2261 ATM_ESA_LEN)==0) {
2262 DPRINTK("LEC_ARP: Attaching data direct\n");
2263 DPRINTK("Currently -> Vcc: %d, Rvcc:%d\n",
2264 entry->vcc?entry->vcc->vci:0,
2265 entry->recv_vcc?entry->recv_vcc->vci:0);
2266 found_entry=1;
2267 del_timer(&entry->timer);
2268 entry->vcc = vcc;
2269 entry->old_push = old_push;
2270 if (entry->status == ESI_VC_PENDING) {
2271 if(priv->maximum_unknown_frame_count
2272 ==0)
2273 entry->status =
2274 ESI_FORWARD_DIRECT;
2275 else {
2276 entry->timestamp = jiffies;
2277 entry->status =
2278 ESI_FLUSH_PENDING;
2279#if 0
2280 send_to_lecd(priv,l_flush_xmt,
2281 NULL,
2282 entry->atm_addr,
2283 NULL);
2284#endif
2285 }
2286 } else {
2287 /* They were forming a connection
2288 to us, and we to them. Our
2289 ATM address is numerically lower
2290 than theirs, so we make connection
2291 we formed into default VCC (8.1.11).
2292 Connection they made gets torn
2293 down. This might confuse some
2294 clients. Can be changed if
2295 someone reports trouble... */
2296 ;
2297 }
2298 }
2299 }
2300 }
2301 if (found_entry) {
2302 DPRINTK("After vcc was added\n");
2303 dump_arp_table(priv);
2304 goto out;
2305 }
2306 /* Not found, snatch address from first data packet that arrives from
2307 this vcc */
2308 entry = make_entry(priv, bus_mac);
2309 if (!entry)
2310 goto out;
2311 entry->vcc = vcc;
2312 entry->old_push = old_push;
2313 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
2314 memset(entry->mac_addr, 0, ETH_ALEN);
2315 entry->status = ESI_UNKNOWN;
2316 entry->next = priv->lec_arp_empty_ones;
2317 priv->lec_arp_empty_ones = entry;
2318 entry->timer.expires = jiffies + priv->vcc_timeout_period;
2319 entry->timer.function = lec_arp_expire_vcc;
2320 add_timer(&entry->timer);
2321 DPRINTK("After vcc was added\n");
2322 dump_arp_table(priv);
2323out:
2324 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2325}
2326
2327static void
2328lec_flush_complete(struct lec_priv *priv, unsigned long tran_id)
2329{
2330 unsigned long flags;
2331 struct lec_arp_table *entry;
2332 int i;
2333
2334 DPRINTK("LEC:lec_flush_complete %lx\n",tran_id);
2335 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2336 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2337 for (entry = priv->lec_arp_tables[i]; entry; entry=entry->next) {
2338 if (entry->flush_tran_id == tran_id &&
2339 entry->status == ESI_FLUSH_PENDING) {
2340 struct sk_buff *skb;
2341
2342 while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
2343 lec_send(entry->vcc, skb, entry->priv);
2344 entry->status = ESI_FORWARD_DIRECT;
2345 DPRINTK("LEC_ARP: Flushed\n");
2346 }
2347 }
2348 }
2349 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2350 dump_arp_table(priv);
2351}
2352
2353static void
2354lec_set_flush_tran_id(struct lec_priv *priv,
2355 unsigned char *atm_addr, unsigned long tran_id)
2356{
2357 unsigned long flags;
2358 struct lec_arp_table *entry;
2359 int i;
2360
2361 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2362 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
2363 for(entry = priv->lec_arp_tables[i]; entry; entry=entry->next)
2364 if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) {
2365 entry->flush_tran_id = tran_id;
2366 DPRINTK("Set flush transaction id to %lx for %p\n",tran_id,entry);
2367 }
2368 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2369}
2370
2371static int
2372lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc)
2373{
2374 unsigned long flags;
2375 unsigned char mac_addr[] = {
2376 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2377 struct lec_arp_table *to_add;
2378 struct lec_vcc_priv *vpriv;
2379 int err = 0;
2380
2381 if (!(vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL)))
2382 return -ENOMEM;
2383 vpriv->xoff = 0;
2384 vpriv->old_pop = vcc->pop;
2385 vcc->user_back = vpriv;
2386 vcc->pop = lec_pop;
2387 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2388 to_add = make_entry(priv, mac_addr);
2389 if (!to_add) {
2390 vcc->pop = vpriv->old_pop;
2391 kfree(vpriv);
2392 err = -ENOMEM;
2393 goto out;
2394 }
2395 memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN);
2396 to_add->status = ESI_FORWARD_DIRECT;
2397 to_add->flags |= LEC_PERMANENT_FLAG;
2398 to_add->vcc = vcc;
2399 to_add->old_push = vcc->push;
2400 vcc->push = lec_push;
2401 priv->mcast_vcc = vcc;
2402 lec_arp_add(priv, to_add);
2403out:
2404 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2405 return err;
2406}
2407
2408static void
2409lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
2410{
2411 unsigned long flags;
2412 struct lec_arp_table *entry, *next;
2413 int i;
2414
2415 DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n",vcc->vpi,vcc->vci);
2416 dump_arp_table(priv);
2417 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2418 for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
2419 for(entry = priv->lec_arp_tables[i];entry; entry=next) {
2420 next = entry->next;
2421 if (vcc == entry->vcc) {
2422 lec_arp_remove(priv, entry);
2423 kfree(entry);
2424 if (priv->mcast_vcc == vcc) {
2425 priv->mcast_vcc = NULL;
2426 }
2427 }
2428 }
2429 }
2430
2431 entry = priv->lec_arp_empty_ones;
2432 priv->lec_arp_empty_ones = NULL;
2433 while (entry != NULL) {
2434 next = entry->next;
2435 if (entry->vcc == vcc) { /* leave it out from the list */
2436 lec_arp_clear_vccs(entry);
2437 del_timer(&entry->timer);
2438 kfree(entry);
2439 }
2440 else { /* put it back to the list */
2441 entry->next = priv->lec_arp_empty_ones;
2442 priv->lec_arp_empty_ones = entry;
2443 }
2444 entry = next;
2445 }
2446
2447 entry = priv->lec_no_forward;
2448 priv->lec_no_forward = NULL;
2449 while (entry != NULL) {
2450 next = entry->next;
2451 if (entry->recv_vcc == vcc) {
2452 lec_arp_clear_vccs(entry);
2453 del_timer(&entry->timer);
2454 kfree(entry);
2455 }
2456 else {
2457 entry->next = priv->lec_no_forward;
2458 priv->lec_no_forward = entry;
2459 }
2460 entry = next;
2461 }
2462
2463 entry = priv->mcast_fwds;
2464 priv->mcast_fwds = NULL;
2465 while (entry != NULL) {
2466 next = entry->next;
2467 if (entry->recv_vcc == vcc) {
2468 lec_arp_clear_vccs(entry);
2469 /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
2470 kfree(entry);
2471 }
2472 else {
2473 entry->next = priv->mcast_fwds;
2474 priv->mcast_fwds = entry;
2475 }
2476 entry = next;
2477 }
2478
2479 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2480 dump_arp_table(priv);
2481}
2482
2483static void
2484lec_arp_check_empties(struct lec_priv *priv,
2485 struct atm_vcc *vcc, struct sk_buff *skb)
2486{
2487 unsigned long flags;
2488 struct lec_arp_table *entry, *prev;
2489 struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
2490 unsigned char *src;
2491#ifdef CONFIG_TR
2492 struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data;
2493
2494 if (priv->is_trdev) src = tr_hdr->h_source;
2495 else
2496#endif
2497 src = hdr->h_source;
2498
2499 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2500 entry = priv->lec_arp_empty_ones;
2501 if (vcc == entry->vcc) {
2502 del_timer(&entry->timer);
2503 memcpy(entry->mac_addr, src, ETH_ALEN);
2504 entry->status = ESI_FORWARD_DIRECT;
2505 entry->last_used = jiffies;
2506 priv->lec_arp_empty_ones = entry->next;
2507 /* We might have got an entry */
2508 if ((prev = lec_arp_find(priv,src))) {
2509 lec_arp_remove(priv, prev);
2510 kfree(prev);
2511 }
2512 lec_arp_add(priv, entry);
2513 goto out;
2514 }
2515 prev = entry;
2516 entry = entry->next;
2517 while (entry && entry->vcc != vcc) {
2518 prev= entry;
2519 entry = entry->next;
2520 }
2521 if (!entry) {
2522 DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n");
2523 goto out;
2524 }
2525 del_timer(&entry->timer);
2526 memcpy(entry->mac_addr, src, ETH_ALEN);
2527 entry->status = ESI_FORWARD_DIRECT;
2528 entry->last_used = jiffies;
2529 prev->next = entry->next;
2530 if ((prev = lec_arp_find(priv, src))) {
2531 lec_arp_remove(priv, prev);
2532 kfree(prev);
2533 }
2534 lec_arp_add(priv, entry);
2535out:
2536 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2537}
2538MODULE_LICENSE("GPL");