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