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