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