* added 0.99 linux version
[mascara-docs.git] / i386 / linux / linux-2.3.21 / net / atm / lec.c
blob67e8c33b4708638b7768d5a4a76c1b6bcc9e1305
1 /*
2 * lec.c: Lan Emulation driver
3 * Marko Kiiskila carnil@cs.tut.fi
5 */
7 #include <linux/config.h>
8 #include <linux/kernel.h>
10 /* We are ethernet device */
11 #include <linux/if_ether.h>
12 #include <linux/netdevice.h>
13 #include <linux/etherdevice.h>
14 #include <net/sock.h>
15 #include <linux/skbuff.h>
16 #include <linux/ip.h>
17 #include <asm/byteorder.h>
18 #include <asm/uaccess.h>
19 #include <net/arp.h>
20 #include <net/dst.h>
21 #include <linux/proc_fs.h>
23 /* TokenRing if needed */
24 #ifdef CONFIG_TR
25 #include <linux/trdevice.h>
26 #endif
28 /* And atm device */
29 #include <linux/atmdev.h>
30 #include <linux/atmlec.h>
32 /* Bridge */
33 #ifdef CONFIG_BRIDGE
34 #include <net/br.h>
35 #endif
37 /* Modular too */
38 #include <linux/module.h>
40 #include "lec.h"
41 #include "lec_arpc.h"
42 #include "tunable.h"
43 #include "resources.h" /* for bind_vcc() */
45 #if 0
46 #define DPRINTK printk
47 #else
48 #define DPRINTK(format,args...)
49 #endif
51 #define DUMP_PACKETS 0 /* 0 = None,
52 * 1 = 30 first bytes
53 * 2 = Whole packet
56 #define LEC_UNRES_QUE_LEN 8 /* number of tx packets to queue for a
57 single destination while waiting for SVC */
59 static int lec_open(struct net_device *dev);
60 static int lec_send_packet(struct sk_buff *skb, struct net_device *dev);
61 static int lec_close(struct net_device *dev);
62 static struct net_device_stats *lec_get_stats(struct net_device *dev);
63 static int lec_init(struct net_device *dev);
64 static __inline__ struct lec_arp_table* lec_arp_find(struct lec_priv *priv,
65 unsigned char *mac_addr);
66 static __inline__ int lec_arp_remove(struct lec_arp_table **lec_arp_tables,
67 struct lec_arp_table *to_remove);
68 /* LANE2 functions */
69 static void lane2_associate_ind (struct net_device *dev, u8 *mac_address,
70 u8 *tlvs, u32 sizeoftlvs);
71 static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
72 u8 **tlvs, u32 *sizeoftlvs);
73 static int lane2_associate_req (struct net_device *dev, u8 *lan_dst,
74 u8 *tlvs, u32 sizeoftlvs);
76 static struct lane2_ops lane2_ops = {
77 lane2_resolve, /* resolve, spec 3.1.3 */
78 lane2_associate_req, /* associate_req, spec 3.1.4 */
79 NULL /* associate indicator, spec 3.1.5 */
82 /* will be lec0, lec1, lec2 etc. */
83 static char myname[] = "lecxx";
85 static unsigned char bus_mac[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
87 /* Device structures */
88 static struct net_device *dev_lec[MAX_LEC_ITF];
90 /* This will be called from proc.c via function pointer */
91 struct net_device **get_dev_lec (void) {
92 return &dev_lec[0];
95 #ifdef CONFIG_BRIDGE
96 static void handle_bridge(struct sk_buff *skb, struct net_device *dev)
98 struct ethhdr *eth;
99 char *buff;
100 struct lec_priv *priv;
101 unsigned char bridge_ula[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
103 /* Check if this is a BPDU. If so, ask zeppelin to send
104 * LE_TOPOLOGY_REQUEST with the value of Topology Change bit
105 * in the Config BPDU*/
106 eth = (struct ethhdr *)skb->data;
107 buff = skb->data + skb->dev->hard_header_len;
108 if ((memcmp(eth->h_dest, bridge_ula, ETH_ALEN) == 0) &&
109 *buff++ == BRIDGE_LLC1_DSAP &&
110 *buff++ == BRIDGE_LLC1_SSAP &&
111 *buff++ == BRIDGE_LLC1_CTRL) {
112 struct sk_buff *skb2;
113 struct atmlec_msg *mesg;
115 skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
116 if (skb2 == NULL) return;
117 skb2->len = sizeof(struct atmlec_msg);
118 mesg = (struct atmlec_msg *)skb2->data;
119 mesg->type = l_topology_change;
120 mesg->content.normal.flag = *(skb->nh.raw + BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) & TOPOLOGY_CHANGE;
122 priv = (struct lec_priv *)dev->priv;
123 atm_force_charge(priv->lecd, skb2->truesize);
124 skb_queue_tail(&priv->lecd->recvq, skb2);
125 wake_up(&priv->lecd->sleep);
128 return;
130 #endif /* CONFIG_BRIDGE */
133 * Modelled after tr_type_trans
134 * All multicast and ARE or STE frames go to BUS.
135 * Non source routed frames go by destination address.
136 * Last hop source routed frames go by destination address.
137 * Not last hop source routed frames go by _next_ route descriptor.
138 * Returns pointer to destination MAC address or fills in rdesc
139 * and returns NULL.
141 #ifdef CONFIG_TR
142 unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc)
144 struct trh_hdr *trh;
145 int riflen, num_rdsc;
147 trh = (struct trh_hdr *)packet;
148 if (trh->daddr[0] & (uint8_t)0x80)
149 return bus_mac; /* multicast */
151 if (trh->saddr[0] & TR_RII) {
152 riflen = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
153 if ((ntohs(trh->rcf) >> 13) != 0)
154 return bus_mac; /* ARE or STE */
156 else
157 return trh->daddr; /* not source routed */
159 if (riflen < 6)
160 return trh->daddr; /* last hop, source routed */
162 /* riflen is 6 or more, packet has more than one route descriptor */
163 num_rdsc = (riflen/2) - 1;
164 memset(rdesc, 0, ETH_ALEN);
165 /* offset 4 comes from LAN destination field in LE control frames */
166 if (trh->rcf & htons((uint16_t)TR_RCF_DIR_BIT))
167 memcpy(&rdesc[4], &trh->rseg[num_rdsc-2], sizeof(uint16_t));
168 else {
169 memcpy(&rdesc[4], &trh->rseg[1], sizeof(uint16_t));
170 rdesc[5] = ((ntohs(trh->rseg[0]) & 0x000f) | (rdesc[5] & 0xf0));
173 return NULL;
175 #endif /* CONFIG_TR */
178 * Open/initialize the netdevice. This is called (in the current kernel)
179 * sometime after booting when the 'ifconfig' program is run.
181 * This routine should set everything up anew at each open, even
182 * registers that "should" only need to be set once at boot, so that
183 * there is non-reboot way to recover if something goes wrong.
186 static int
187 lec_open(struct net_device *dev)
189 struct lec_priv *priv = (struct lec_priv *)dev->priv;
191 dev->tbusy = 0;
192 dev->start = 1;
193 dev->interrupt = 1;
194 memset(&priv->stats,0,sizeof(struct net_device_stats));
196 return 0;
199 static int
200 lec_send_packet(struct sk_buff *skb, struct net_device *dev)
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 */
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 dev->tbusy = 1;
222 return -EUNATCH;
224 if (dev->tbusy) {
226 * If we get here, some higher level has decided we are broken.
227 * There should really be a "kick me" function call instead.
229 printk("%s: transmit timed out\n", dev->name);
230 dev->tbusy = 0;
234 * Block a timer-based transmit from overlapping. This could better be
235 * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
238 if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
239 printk(KERN_WARNING "%s: Transmitter access conflict.\n",
240 dev->name);
241 } else {
242 DPRINTK("skbuff head:%lx data:%lx tail:%lx end:%lx\n",
243 (long)skb->head, (long)skb->data, (long)skb->tail,
244 (long)skb->end);
245 #ifdef CONFIG_BRIDGE
246 if (skb->pkt_bridged == IS_BRIDGED)
247 handle_bridge(skb, dev);
248 #endif /* CONFIG_BRIDGE */
250 /* Make sure we have room for lec_id */
251 if (skb_headroom(skb) < 2) {
253 DPRINTK("lec_send_packet: reallocating skb\n");
254 skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
255 kfree_skb(skb);
256 if (skb2 == NULL) return 0;
257 skb = skb2;
259 skb_push(skb, 2);
261 /* Put le header to place, works for TokenRing too */
262 lec_h = (struct lecdatahdr_8023*)skb->data;
263 lec_h->le_header = htons(priv->lecid);
265 #if DUMP_PACKETS > 0
266 printk("%s: send datalen:%ld lecid:%4.4x\n", dev->name,
267 skb->len, priv->lecid);
268 #if DUMP_PACKETS >= 2
269 for(i=0;i<skb->len && i <99;i++) {
270 sprintf(buf+i*3,"%2.2x ",0xff&skb->data[i]);
272 #elif DUMP_PACKETS >= 1
273 for(i=0;i<skb->len && i < 30;i++) {
274 sprintf(buf+i*3,"%2.2x ", 0xff&skb->data[i]);
276 #endif /* DUMP_PACKETS >= 1 */
277 if (i==skb->len)
278 printk("%s\n",buf);
279 else
280 printk("%s...\n",buf);
281 #endif /* DUMP_PACKETS > 0 */
283 /* Minimum ethernet-frame size */
284 if (skb->len <62) {
285 if (skb->truesize < 62) {
286 printk("%s:data packet %d / %d\n",
287 dev->name,
288 skb->len,skb->truesize);
289 nb=(unsigned char*)kmalloc(64, GFP_ATOMIC);
290 memcpy(nb,skb->data,skb->len);
291 kfree(skb->head);
292 skb->head = skb->data = nb;
293 skb->tail = nb+62;
294 skb->end = nb+64;
295 skb->len=62;
296 skb->truesize = 64;
297 } else {
298 skb->len = 62;
302 /* Send to right vcc */
303 is_rdesc = 0;
304 dst = lec_h->h_dest;
305 #ifdef CONFIG_TR
306 if (priv->is_trdev) {
307 dst = get_tr_dst(skb->data+2, rdesc);
308 if (dst == NULL) {
309 dst = rdesc;
310 is_rdesc = 1;
313 #endif
314 entry = NULL;
315 send_vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry);
316 DPRINTK("%s:send_vcc:%p vcc_flags:%x, entry:%p\n", dev->name,
317 send_vcc, send_vcc?send_vcc->flags:0, entry);
318 if (!send_vcc || !(send_vcc->flags & ATM_VF_READY)) {
319 if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) {
320 DPRINTK("%s:lec_send_packet: queuing packet, ", dev->name);
321 DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
322 lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
323 lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
324 skb_queue_tail(&entry->tx_wait, skb);
325 } else {
326 DPRINTK("%s:lec_send_packet: tx queue full or no arp entry, dropping, ", dev->name);
327 DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
328 lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
329 lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
330 priv->stats.tx_dropped++;
331 dev_kfree_skb(skb);
333 dev->tbusy=0;
334 return 0;
337 #if DUMP_PACKETS > 0
338 printk("%s:sending to vpi:%d vci:%d\n", dev->name,
339 send_vcc->vpi, send_vcc->vci);
340 #endif /* DUMP_PACKETS > 0 */
342 while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
343 DPRINTK("lec.c: emptying tx queue, ");
344 DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
345 lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
346 lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
347 ATM_SKB(skb2)->vcc = send_vcc;
348 atomic_add(skb2->truesize, &send_vcc->tx_inuse);
349 ATM_SKB(skb2)->iovcnt = 0;
350 ATM_SKB(skb2)->atm_options = send_vcc->atm_options;
351 DPRINTK("%s:sending to vpi:%d vci:%d\n", dev->name,
352 send_vcc->vpi, send_vcc->vci);
353 priv->stats.tx_packets++;
354 priv->stats.tx_bytes += skb2->len;
355 send_vcc->dev->ops->send(send_vcc, skb2);
358 ATM_SKB(skb)->vcc = send_vcc;
359 atomic_add(skb->truesize, &send_vcc->tx_inuse);
360 ATM_SKB(skb)->iovcnt = 0;
361 ATM_SKB(skb)->atm_options = send_vcc->atm_options;
362 priv->stats.tx_packets++;
363 priv->stats.tx_bytes += skb->len;
364 send_vcc->dev->ops->send(send_vcc, skb);
366 /* Should we wait for card's device driver to notify us? */
367 dev->tbusy=0;
369 return 0;
372 /* The inverse routine to net_open(). */
373 static int
374 lec_close(struct net_device *dev)
376 dev->tbusy = 1;
377 dev->start = 0;
378 return 0;
382 * Get the current statistics.
383 * This may be called with the card open or closed.
385 static struct net_device_stats *
386 lec_get_stats(struct net_device *dev)
388 return &((struct lec_priv *)dev->priv)->stats;
391 static int
392 lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
394 struct net_device *dev = (struct net_device*)vcc->proto_data;
395 struct lec_priv *priv = (struct lec_priv*)dev->priv;
396 struct atmlec_msg *mesg;
397 struct lec_arp_table *entry;
398 int i;
399 char *tmp; /* FIXME */
401 atomic_sub(skb->truesize+ATM_PDU_OVHD, &vcc->tx_inuse);
402 mesg = (struct atmlec_msg *)skb->data;
403 tmp = skb->data;
404 tmp += sizeof(struct atmlec_msg);
405 DPRINTK("%s: msg from zeppelin:%d\n", dev->name, mesg->type);
406 switch(mesg->type) {
407 case l_set_mac_addr:
408 for (i=0;i<6;i++) {
409 dev->dev_addr[i] = mesg->content.normal.mac_addr[i];
411 break;
412 case l_del_mac_addr:
413 for(i=0;i<6;i++) {
414 dev->dev_addr[i] = 0;
416 break;
417 case l_addr_delete:
418 lec_addr_delete(priv, mesg->content.normal.atm_addr,
419 mesg->content.normal.flag);
420 break;
421 case l_topology_change:
422 priv->topology_change = mesg->content.normal.flag;
423 break;
424 case l_flush_complete:
425 lec_flush_complete(priv, mesg->content.normal.flag);
426 break;
427 case l_narp_req: /* LANE2: see 7.1.35 in the lane2 spec */
428 entry = lec_arp_find(priv, mesg->content.normal.mac_addr);
429 lec_arp_remove(priv->lec_arp_tables, entry);
431 if (mesg->content.normal.no_source_le_narp)
432 break;
433 /* FALL THROUGH */
434 case l_arp_update:
435 lec_arp_update(priv, mesg->content.normal.mac_addr,
436 mesg->content.normal.atm_addr,
437 mesg->content.normal.flag,
438 mesg->content.normal.targetless_le_arp);
439 DPRINTK("lec: in l_arp_update\n");
440 if (mesg->sizeoftlvs != 0) { /* LANE2 3.1.5 */
441 DPRINTK("lec: LANE2 3.1.5, got tlvs, size %d\n", mesg->sizeoftlvs);
442 lane2_associate_ind(dev,
443 mesg->content.normal.mac_addr,
444 tmp, mesg->sizeoftlvs);
446 break;
447 case l_config:
448 priv->maximum_unknown_frame_count =
449 mesg->content.config.maximum_unknown_frame_count;
450 priv->max_unknown_frame_time =
451 (mesg->content.config.max_unknown_frame_time*HZ);
452 priv->max_retry_count =
453 mesg->content.config.max_retry_count;
454 priv->aging_time = (mesg->content.config.aging_time*HZ);
455 priv->forward_delay_time =
456 (mesg->content.config.forward_delay_time*HZ);
457 priv->arp_response_time =
458 (mesg->content.config.arp_response_time*HZ);
459 priv->flush_timeout = (mesg->content.config.flush_timeout*HZ);
460 priv->path_switching_delay =
461 (mesg->content.config.path_switching_delay*HZ);
462 priv->lane_version = mesg->content.config.lane_version; /* LANE2 */
463 priv->lane2_ops = NULL;
464 if (priv->lane_version > 1)
465 priv->lane2_ops = &lane2_ops;
466 if (dev->change_mtu(dev, mesg->content.config.mtu))
467 printk("%s: change_mtu to %d failed\n", dev->name,
468 mesg->content.config.mtu);
469 break;
470 case l_flush_tran_id:
471 lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr,
472 mesg->content.normal.flag);
473 break;
474 case l_set_lecid:
475 priv->lecid=(unsigned short)(0xffff&mesg->content.normal.flag);
476 break;
477 case l_should_bridge: {
478 #ifdef CONFIG_BRIDGE
479 struct fdb *f;
480 extern Port_data port_info[];
482 DPRINTK("%s: bridge zeppelin asks about 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
483 dev->name,
484 mesg->content.proxy.mac_addr[0], mesg->content.proxy.mac_addr[1],
485 mesg->content.proxy.mac_addr[2], mesg->content.proxy.mac_addr[3],
486 mesg->content.proxy.mac_addr[4], mesg->content.proxy.mac_addr[5]);
487 f = br_avl_find_addr(mesg->content.proxy.mac_addr); /* bridge/br.c */
488 if (f != NULL &&
489 port_info[f->port].dev != dev &&
490 port_info[f->port].state == Forwarding) {
491 /* hit from bridge table, send LE_ARP_RESPONSE */
492 struct sk_buff *skb2;
494 DPRINTK("%s: entry found, responding to zeppelin\n", dev->name);
495 skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
496 if (skb2 == NULL) break;
497 skb2->len = sizeof(struct atmlec_msg);
498 memcpy(skb2->data, mesg, sizeof(struct atmlec_msg));
499 atm_force_charge(priv->lecd, skb2->truesize);
500 skb_queue_tail(&priv->lecd->recvq, skb2);
501 wake_up(&priv->lecd->sleep);
503 #endif /* CONFIG_BRIDGE */
505 break;
506 default:
507 printk("%s: Unknown message type %d\n", dev->name, mesg->type);
508 dev_kfree_skb(skb);
509 return -EINVAL;
511 dev_kfree_skb(skb);
512 return 0;
515 static void
516 lec_atm_close(struct atm_vcc *vcc)
518 struct sk_buff *skb;
519 struct net_device *dev = (struct net_device *)vcc->proto_data;
520 struct lec_priv *priv = (struct lec_priv *)dev->priv;
522 priv->lecd = NULL;
523 /* Do something needful? */
525 dev->tbusy = 1;
526 dev->start = 0;
528 lec_arp_destroy(priv);
530 if (skb_peek(&vcc->recvq))
531 printk("%s lec_atm_close: closing with messages pending\n",
532 dev->name);
533 while ((skb = skb_dequeue(&vcc->recvq))) {
534 atm_return(vcc, skb->truesize);
535 dev_kfree_skb(skb);
538 printk("%s: Shut down!\n", dev->name);
539 MOD_DEC_USE_COUNT;
542 static struct atmdev_ops lecdev_ops = {
543 NULL, /*dev_close*/
544 NULL, /*open*/
545 lec_atm_close, /*close*/
546 NULL, /*ioctl*/
547 NULL, /*getsockopt */
548 NULL, /*setsockopt */
549 lec_atm_send, /*send */
550 NULL, /*sg_send */
551 #if 0 /* these are disabled in <linux/atmdev.h> too */
552 NULL, /*poll */
553 NULL, /*send_iovec*/
554 #endif
555 NULL, /*send_oam*/
556 NULL, /*phy_put*/
557 NULL, /*phy_get*/
558 NULL, /*feedback*/
559 NULL, /* change_qos*/
560 NULL /* free_rx_skb*/
563 static struct atm_dev lecatm_dev = {
564 &lecdev_ops,
565 NULL, /*PHY*/
566 "lec", /*type*/
567 999, /*dummy device number*/
568 NULL,NULL, /*no VCCs*/
569 NULL,NULL, /*no data*/
570 0, /*no flags*/
571 NULL, /* no local address*/
572 { 0 } /*no ESI or rest of the atm_dev struct things*/
576 * LANE2: new argument struct sk_buff *data contains
577 * the LE_ARP based TLVs introduced in the LANE2 spec
579 int
580 send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,
581 unsigned char *mac_addr, unsigned char *atm_addr,
582 struct sk_buff *data)
584 struct sk_buff *skb;
585 struct atmlec_msg *mesg;
587 if (!priv || !priv->lecd) {
588 return -1;
590 skb = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
591 if (!skb)
592 return -1;
593 skb->len = sizeof(struct atmlec_msg);
594 mesg = (struct atmlec_msg *)skb->data;
595 memset(mesg, 0, sizeof(struct atmlec_msg));
596 mesg->type = type;
597 if (data != NULL)
598 mesg->sizeoftlvs = data->len;
599 if (mac_addr)
600 memcpy(&mesg->content.normal.mac_addr, mac_addr, ETH_ALEN);
601 else
602 mesg->content.normal.targetless_le_arp = 1;
603 if (atm_addr)
604 memcpy(&mesg->content.normal.atm_addr, atm_addr, ATM_ESA_LEN);
606 atm_force_charge(priv->lecd, skb->truesize);
607 skb_queue_tail(&priv->lecd->recvq, skb);
608 wake_up(&priv->lecd->sleep);
610 if (data != NULL) {
611 DPRINTK("lec: about to send %d bytes of data\n", data->len);
612 atm_force_charge(priv->lecd, data->truesize);
613 skb_queue_tail(&priv->lecd->recvq, data);
614 wake_up(&priv->lecd->sleep);
617 return 0;
620 /* shamelessly stolen from drivers/net/net_init.c */
621 static int lec_change_mtu(struct net_device *dev, int new_mtu)
623 if ((new_mtu < 68) || (new_mtu > 18190))
624 return -EINVAL;
625 dev->mtu = new_mtu;
626 return 0;
629 static int
630 lec_init(struct net_device *dev)
632 struct lec_priv *priv;
634 priv = (struct lec_priv *)dev->priv;
635 if (priv->is_trdev) {
636 #ifdef CONFIG_TR
637 init_trdev(dev, 0);
638 #endif
639 } else ether_setup(dev);
640 dev->change_mtu = lec_change_mtu;
641 dev->open = lec_open;
642 dev->stop = lec_close;
643 dev->hard_start_xmit = lec_send_packet;
645 dev->get_stats = lec_get_stats;
646 dev->set_multicast_list = NULL;
647 dev->do_ioctl = NULL;
648 printk("%s: Initialized!\n",dev->name);
649 return 0;
652 static unsigned char lec_ctrl_magic[] = {
653 0xff,
654 0x00,
655 0x01,
656 0x01 };
658 void
659 lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
661 struct net_device *dev = (struct net_device *)vcc->proto_data;
662 struct lec_priv *priv = (struct lec_priv *)dev->priv;
663 struct lecdatahdr_8023 *hdr;
665 #if DUMP_PACKETS >0
666 int i=0;
667 char buf[300];
669 printk("%s: lec_push vcc vpi:%d vci:%d\n", dev->name,
670 vcc->vpi, vcc->vci);
671 #endif
672 if (!skb) {
673 DPRINTK("%s: null skb\n",dev->name);
674 lec_vcc_close(priv, vcc);
675 return;
677 #if DUMP_PACKETS > 0
678 printk("%s: rcv datalen:%ld lecid:%4.4x\n", dev->name,
679 skb->len, priv->lecid);
680 #if DUMP_PACKETS >= 2
681 for(i=0;i<skb->len && i <99;i++) {
682 sprintf(buf+i*3,"%2.2x ",0xff&skb->data[i]);
684 #elif DUMP_PACKETS >= 1
685 for(i=0;i<skb->len && i < 30;i++) {
686 sprintf(buf+i*3,"%2.2x ", 0xff&skb->data[i]);
688 #endif /* DUMP_PACKETS >= 1 */
689 if (i==skb->len)
690 printk("%s\n",buf);
691 else
692 printk("%s...\n",buf);
693 #endif /* DUMP_PACKETS > 0 */
694 if (memcmp(skb->data, lec_ctrl_magic, 4) ==0) { /* Control frame, to daemon*/
695 DPRINTK("%s: To daemon\n",dev->name);
696 skb_queue_tail(&vcc->recvq, skb);
697 wake_up(&vcc->sleep);
698 } else { /* Data frame, queue to protocol handlers */
699 atm_return(vcc,skb->truesize);
700 hdr = (struct lecdatahdr_8023 *)skb->data;
701 if (hdr->le_header == htons(priv->lecid) ||
702 !priv->lecd) {
703 /* Probably looping back, or if lecd is missing,
704 lecd has gone down */
705 DPRINTK("Ignoring loopback frame...\n");
706 dev_kfree_skb(skb);
707 return;
709 if (priv->lec_arp_empty_ones) { /* FILTER DATA!!!! */
710 lec_arp_check_empties(priv, vcc, skb);
712 skb->dev = dev;
713 skb->data += 2; /* skip lec_id */
714 #ifdef CONFIG_TR
715 if (priv->is_trdev) skb->protocol = tr_type_trans(skb, dev);
716 else
717 #endif
718 skb->protocol = eth_type_trans(skb, dev);
719 priv->stats.rx_packets++;
720 priv->stats.rx_bytes += skb->len;
721 netif_rx(skb);
725 int
726 lec_vcc_attach(struct atm_vcc *vcc, void *arg)
728 int bytes_left;
729 struct atmlec_ioc ioc_data;
731 /* Lecd must be up in this case */
732 bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc));
733 if (bytes_left != 0) {
734 printk("lec: lec_vcc_attach, copy from user failed for %d bytes\n",
735 bytes_left);
737 if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF ||
738 !dev_lec[ioc_data.dev_num])
739 return -EINVAL;
740 lec_vcc_added(dev_lec[ioc_data.dev_num]->priv,
741 &ioc_data, vcc, vcc->push);
742 vcc->push = lec_push;
743 vcc->proto_data = dev_lec[ioc_data.dev_num];
744 return 0;
747 int
748 lec_mcast_attach(struct atm_vcc *vcc, int arg)
750 if (arg <0 || arg >= MAX_LEC_ITF || !dev_lec[arg])
751 return -EINVAL;
752 vcc->proto_data = dev_lec[arg];
753 return (lec_mcast_make((struct lec_priv*)dev_lec[arg]->priv, vcc));
756 /* Initialize device. */
757 int
758 lecd_attach(struct atm_vcc *vcc, int arg)
760 int i, result;
761 struct lec_priv *priv;
763 if (arg<0)
764 i = 0;
765 else
766 i = arg;
767 #ifdef CONFIG_TR
768 if (arg >= MAX_LEC_ITF)
769 return -EINVAL;
770 #else /* Reserve the top NUM_TR_DEVS for TR */
771 if (arg >= (MAX_LEC_ITF-NUM_TR_DEVS))
772 return -EINVAL;
773 #endif
774 if (!dev_lec[i]) {
775 dev_lec[i] = (struct net_device*)
776 kmalloc(sizeof(struct net_device)+sizeof(myname)+1,
777 GFP_KERNEL);
778 if (!dev_lec[i])
779 return -ENOMEM;
780 memset(dev_lec[i],0,sizeof(struct net_device)+sizeof(myname)+1);
782 dev_lec[i]->priv = kmalloc(sizeof(struct lec_priv), GFP_KERNEL);
783 if (!dev_lec[i]->priv)
784 return -ENOMEM;
785 memset(dev_lec[i]->priv,0,sizeof(struct lec_priv));
786 priv = (struct lec_priv *)dev_lec[i]->priv;
788 if (i >= (MAX_LEC_ITF - NUM_TR_DEVS))
789 priv->is_trdev = 1;
791 dev_lec[i]->name = (char*)(dev_lec[i]+1);
792 sprintf(dev_lec[i]->name, "lec%d",i);
793 dev_lec[i]->init = lec_init;
794 if ((result = register_netdev(dev_lec[i])) !=0)
795 return result;
796 sprintf(dev_lec[i]->name, "lec%d", i); /* init_trdev globbers device name */
797 } else {
798 priv = (struct lec_priv *)dev_lec[i]->priv;
799 if (priv->lecd)
800 return -EADDRINUSE;
802 lec_arp_init(priv);
803 priv->itfnum = i; /* LANE2 addition */
804 priv->lecd = vcc;
805 bind_vcc(vcc, &lecatm_dev);
807 vcc->proto_data = dev_lec[i];
808 vcc->flags |= ATM_VF_READY | ATM_VF_META;
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);
822 if (dev_lec[i]->flags & IFF_UP) {
823 dev_lec[i]->tbusy = 0;
824 dev_lec[i]->start = 1;
826 MOD_INC_USE_COUNT;
827 return i;
830 void atm_lane_init_ops(struct atm_lane_ops *ops)
832 ops->lecd_attach = lecd_attach;
833 ops->mcast_attach = lec_mcast_attach;
834 ops->vcc_attach = lec_vcc_attach;
835 ops->get_lecs = get_dev_lec;
837 printk("lec.c: " __DATE__ " " __TIME__ " initialized\n");
839 return;
842 #ifdef MODULE
843 int init_module(void)
845 extern struct atm_lane_ops atm_lane_ops;
847 atm_lane_init_ops(&atm_lane_ops);
849 return 0;
852 void cleanup_module(void)
854 int i;
855 extern struct atm_lane_ops atm_lane_ops;
856 struct lec_priv *priv;
858 if (MOD_IN_USE) {
859 printk(KERN_NOTICE "lec.c: module in use\n");
860 return;
863 atm_lane_ops.lecd_attach = NULL;
864 atm_lane_ops.mcast_attach = NULL;
865 atm_lane_ops.vcc_attach = NULL;
866 atm_lane_ops.get_lecs = NULL;
868 for (i = 0; i < MAX_LEC_ITF; i++) {
869 if (dev_lec[i] != NULL) {
870 priv = (struct lec_priv *)dev_lec[i]->priv;
871 if (priv->is_trdev) {
872 #ifdef CONFIG_TR
873 unregister_trdev(dev_lec[i]);
874 #endif
875 } else
876 unregister_netdev(dev_lec[i]);
877 kfree(dev_lec[i]->priv);
878 kfree(dev_lec[i]);
879 dev_lec[i] = NULL;
883 return;
885 #endif /* MODULE */
888 * LANE2: 3.1.3, LE_RESOLVE.request
889 * Non force allocates memory and fills in *tlvs, fills in *sizeoftlvs.
890 * If sizeoftlvs == NULL the default TLVs associated with with this
891 * lec will be used.
892 * If dst_mac == NULL, targetless LE_ARP will be sent
894 static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
895 u8 **tlvs, u32 *sizeoftlvs)
897 struct lec_priv *priv = (struct lec_priv *)dev->priv;
898 struct lec_arp_table *table;
899 struct sk_buff *skb;
900 int retval;
902 if (force == 0) {
903 table = lec_arp_find(priv, dst_mac);
904 if(table == NULL)
905 return -1;
907 *tlvs = kmalloc(table->sizeoftlvs, GFP_KERNEL);
908 if (*tlvs == NULL)
909 return -1;
911 memcpy(*tlvs, table->tlvs, table->sizeoftlvs);
912 *sizeoftlvs = table->sizeoftlvs;
914 return 0;
917 if (sizeoftlvs == NULL)
918 retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, NULL);
920 else {
921 skb = alloc_skb(*sizeoftlvs, GFP_ATOMIC);
922 if (skb == NULL)
923 return -1;
924 skb->len = *sizeoftlvs;
925 memcpy(skb->data, *tlvs, *sizeoftlvs);
926 retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, skb);
928 return retval;
933 * LANE2: 3.1.4, LE_ASSOCIATE.request
934 * Associate the *tlvs with the *lan_dst address.
935 * Will overwrite any previous association
936 * Returns 1 for success, 0 for failure (out of memory)
939 static int lane2_associate_req (struct net_device *dev, u8 *lan_dst,
940 u8 *tlvs, u32 sizeoftlvs)
942 int retval;
943 struct sk_buff *skb;
944 struct lec_priv *priv = (struct lec_priv*)dev->priv;
946 if ( memcmp(lan_dst, dev->dev_addr, ETH_ALEN) != 0 )
947 return (0); /* not our mac address */
949 kfree(priv->tlvs); /* NULL if there was no previous association */
951 priv->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);
952 if (priv->tlvs == NULL)
953 return (0);
954 priv->sizeoftlvs = sizeoftlvs;
955 memcpy(priv->tlvs, tlvs, sizeoftlvs);
957 skb = alloc_skb(sizeoftlvs, GFP_ATOMIC);
958 if (skb == NULL)
959 return 0;
960 skb->len = sizeoftlvs;
961 memcpy(skb->data, tlvs, sizeoftlvs);
962 retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb);
963 if (retval != 0)
964 printk("lec.c: lane2_associate_req() failed\n");
965 /* If the previous association has changed we must
966 * somehow notify other LANE entities about the change
968 return (1);
972 * LANE2: 3.1.5, LE_ASSOCIATE.indication
975 static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr,
976 u8 *tlvs, u32 sizeoftlvs)
978 #if 0
979 int i = 0;
980 #endif
981 struct lec_priv *priv = (struct lec_priv *)dev->priv;
982 #if 0 /* Why have the TLVs in LE_ARP entries since we do not use them? When you
983 uncomment this code, make sure the TLVs get freed when entry is killed */
984 struct lec_arp_table *entry = lec_arp_find(priv, mac_addr);
986 if (entry == NULL)
987 return; /* should not happen */
989 kfree(entry->tlvs);
991 entry->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);
992 if (entry->tlvs == NULL)
993 return;
995 entry->sizeoftlvs = sizeoftlvs;
996 memcpy(entry->tlvs, tlvs, sizeoftlvs);
997 #endif
998 #if 0
999 printk("lec.c: lane2_associate_ind()\n");
1000 printk("dump of tlvs, sizeoftlvs=%d\n", sizeoftlvs);
1001 while (i < sizeoftlvs)
1002 printk("%02x ", tlvs[i++]);
1004 printk("\n");
1005 #endif
1007 /* tell MPOA about the TLVs we saw */
1008 if (priv->lane2_ops && priv->lane2_ops->associate_indicator) {
1009 priv->lane2_ops->associate_indicator(dev, mac_addr,
1010 tlvs, sizeoftlvs);
1012 return;
1016 * Here starts what used to lec_arpc.c
1018 * lec_arpc.c was added here when making
1019 * lane client modular. October 1997
1023 #include <linux/types.h>
1024 #include <linux/sched.h>
1025 #include <linux/timer.h>
1026 #include <asm/param.h>
1027 #include <asm/atomic.h>
1028 #include <linux/inetdevice.h>
1029 #include <net/route.h>
1032 #if 0
1033 #define DPRINTK(format,args...)
1035 #define DPRINTK printk
1037 #endif
1038 #define DEBUG_ARP_TABLE 0
1040 #define LEC_ARP_REFRESH_INTERVAL (3*HZ)
1042 static void lec_arp_check_expire(unsigned long data);
1043 static __inline__ void lec_arp_expire_arp(unsigned long data);
1044 void dump_arp_table(struct lec_priv *priv);
1047 * Arp table funcs
1050 #define HASH(ch) (ch & (LEC_ARP_TABLE_SIZE -1))
1052 static __inline__ void
1053 lec_arp_lock(struct lec_priv *priv)
1055 atomic_inc(&priv->lec_arp_lock_var);
1058 static __inline__ void
1059 lec_arp_unlock(struct lec_priv *priv)
1061 atomic_dec(&priv->lec_arp_lock_var);
1065 * Initialization of arp-cache
1067 void
1068 lec_arp_init(struct lec_priv *priv)
1070 unsigned short i;
1072 for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {
1073 priv->lec_arp_tables[i] = NULL;
1075 init_timer(&priv->lec_arp_timer);
1076 priv->lec_arp_timer.expires = jiffies+LEC_ARP_REFRESH_INTERVAL;
1077 priv->lec_arp_timer.data = (unsigned long)priv;
1078 priv->lec_arp_timer.function = lec_arp_check_expire;
1079 add_timer(&priv->lec_arp_timer);
1082 void
1083 lec_arp_clear_vccs(struct lec_arp_table *entry)
1085 if (entry->vcc) {
1086 entry->vcc->push = entry->old_push;
1087 #if 0 /* August 6, 1998 */
1088 entry->vcc->flags |= ATM_VF_RELEASED;
1089 entry->vcc->flags &= ~ATM_VF_READY;
1090 entry->vcc->push(entry->vcc, NULL);
1091 #endif
1092 atm_async_release_vcc(entry->vcc, -EPIPE);
1093 entry->vcc = NULL;
1095 if (entry->recv_vcc) {
1096 entry->recv_vcc->push = entry->old_recv_push;
1097 #if 0
1098 entry->recv_vcc->flags |= ATM_VF_RELEASED;
1099 entry->recv_vcc->flags &= ~ATM_VF_READY;
1100 entry->recv_vcc->push(entry->recv_vcc, NULL);
1101 #endif
1102 atm_async_release_vcc(entry->recv_vcc, -EPIPE);
1103 entry->recv_vcc = NULL;
1108 * Insert entry to lec_arp_table
1109 * LANE2: Add to the end of the list to satisfy 8.1.13
1111 static __inline__ void
1112 lec_arp_put(struct lec_arp_table **lec_arp_tables,
1113 struct lec_arp_table *to_put)
1115 unsigned short place;
1116 unsigned long flags;
1117 struct lec_arp_table *tmp;
1119 save_flags(flags);
1120 cli();
1122 place = HASH(to_put->mac_addr[ETH_ALEN-1]);
1123 tmp = lec_arp_tables[place];
1124 to_put->next = NULL;
1125 if (tmp == NULL)
1126 lec_arp_tables[place] = to_put;
1128 else { /* add to the end */
1129 while (tmp->next)
1130 tmp = tmp->next;
1131 tmp->next = to_put;
1134 restore_flags(flags);
1135 DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
1136 0xff&to_put->mac_addr[0], 0xff&to_put->mac_addr[1],
1137 0xff&to_put->mac_addr[2], 0xff&to_put->mac_addr[3],
1138 0xff&to_put->mac_addr[4], 0xff&to_put->mac_addr[5]);
1142 * Remove entry from lec_arp_table
1144 static __inline__ int
1145 lec_arp_remove(struct lec_arp_table **lec_arp_tables,
1146 struct lec_arp_table *to_remove)
1148 unsigned short place;
1149 struct lec_arp_table *tmp;
1150 unsigned long flags;
1151 int remove_vcc=1;
1153 save_flags(flags);
1154 cli();
1156 if (!to_remove) {
1157 restore_flags(flags);
1158 return -1;
1160 place = HASH(to_remove->mac_addr[ETH_ALEN-1]);
1161 tmp = lec_arp_tables[place];
1162 if (tmp == to_remove) {
1163 lec_arp_tables[place] = tmp->next;
1164 } else {
1165 while(tmp && tmp->next != to_remove) {
1166 tmp = tmp->next;
1168 if (!tmp) {/* Entry was not found */
1169 restore_flags(flags);
1170 return -1;
1173 tmp->next = to_remove->next;
1174 del_timer(&to_remove->timer);
1176 /* If this is the only MAC connected to this VCC, also tear down
1177 the VCC */
1178 if (to_remove->status >= ESI_FLUSH_PENDING) {
1180 * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT
1182 for(place=0;place<LEC_ARP_TABLE_SIZE;place++) {
1183 for(tmp=lec_arp_tables[place];tmp!=NULL;tmp=tmp->next){
1184 if (memcmp(tmp->atm_addr, to_remove->atm_addr,
1185 ATM_ESA_LEN)==0) {
1186 remove_vcc=0;
1187 break;
1191 if (remove_vcc)
1192 lec_arp_clear_vccs(to_remove);
1194 skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */
1195 restore_flags(flags);
1196 DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
1197 0xff&to_remove->mac_addr[0], 0xff&to_remove->mac_addr[1],
1198 0xff&to_remove->mac_addr[2], 0xff&to_remove->mac_addr[3],
1199 0xff&to_remove->mac_addr[4], 0xff&to_remove->mac_addr[5]);
1200 return 0;
1203 #if DEBUG_ARP_TABLE
1204 static char*
1205 get_status_string(unsigned char st)
1207 switch(st) {
1208 case ESI_UNKNOWN:
1209 return "ESI_UNKNOWN";
1210 case ESI_ARP_PENDING:
1211 return "ESI_ARP_PENDING";
1212 case ESI_VC_PENDING:
1213 return "ESI_VC_PENDING";
1214 case ESI_FLUSH_PENDING:
1215 return "ESI_FLUSH_PENDING";
1216 case ESI_FORWARD_DIRECT:
1217 return "ESI_FORWARD_DIRECT";
1218 default:
1219 return "<UNKNOWN>";
1222 #endif
1224 void
1225 dump_arp_table(struct lec_priv *priv)
1227 #if DEBUG_ARP_TABLE
1228 int i,j, offset;
1229 struct lec_arp_table *rulla;
1230 char buf[1024];
1231 struct lec_arp_table **lec_arp_tables =
1232 (struct lec_arp_table **)priv->lec_arp_tables;
1233 struct lec_arp_table *lec_arp_empty_ones =
1234 (struct lec_arp_table *)priv->lec_arp_empty_ones;
1235 struct lec_arp_table *lec_no_forward =
1236 (struct lec_arp_table *)priv->lec_no_forward;
1237 struct lec_arp_table *mcast_fwds = priv->mcast_fwds;
1240 printk("Dump %p:\n",priv);
1241 for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {
1242 rulla = lec_arp_tables[i];
1243 offset = 0;
1244 offset += sprintf(buf,"%d: %p\n",i, rulla);
1245 while (rulla) {
1246 offset += sprintf(buf+offset,"Mac:");
1247 for(j=0;j<ETH_ALEN;j++) {
1248 offset+=sprintf(buf+offset,
1249 "%2.2x ",
1250 rulla->mac_addr[j]&0xff);
1252 offset +=sprintf(buf+offset,"Atm:");
1253 for(j=0;j<ATM_ESA_LEN;j++) {
1254 offset+=sprintf(buf+offset,
1255 "%2.2x ",
1256 rulla->atm_addr[j]&0xff);
1258 offset+=sprintf(buf+offset,
1259 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
1260 rulla->vcc?rulla->vcc->vpi:0,
1261 rulla->vcc?rulla->vcc->vci:0,
1262 rulla->recv_vcc?rulla->recv_vcc->vpi:0,
1263 rulla->recv_vcc?rulla->recv_vcc->vci:0,
1264 rulla->last_used,
1265 rulla->timestamp, rulla->no_tries);
1266 offset+=sprintf(buf+offset,
1267 "Flags:%x, Packets_flooded:%x, Status: %s ",
1268 rulla->flags, rulla->packets_flooded,
1269 get_status_string(rulla->status));
1270 offset+=sprintf(buf+offset,"->%p\n",rulla->next);
1271 rulla = rulla->next;
1273 printk("%s",buf);
1275 rulla = lec_no_forward;
1276 if (rulla)
1277 printk("No forward\n");
1278 while(rulla) {
1279 offset=0;
1280 offset += sprintf(buf+offset,"Mac:");
1281 for(j=0;j<ETH_ALEN;j++) {
1282 offset+=sprintf(buf+offset,"%2.2x ",
1283 rulla->mac_addr[j]&0xff);
1285 offset +=sprintf(buf+offset,"Atm:");
1286 for(j=0;j<ATM_ESA_LEN;j++) {
1287 offset+=sprintf(buf+offset,"%2.2x ",
1288 rulla->atm_addr[j]&0xff);
1290 offset+=sprintf(buf+offset,
1291 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
1292 rulla->vcc?rulla->vcc->vpi:0,
1293 rulla->vcc?rulla->vcc->vci:0,
1294 rulla->recv_vcc?rulla->recv_vcc->vpi:0,
1295 rulla->recv_vcc?rulla->recv_vcc->vci:0,
1296 rulla->last_used,
1297 rulla->timestamp, rulla->no_tries);
1298 offset+=sprintf(buf+offset,
1299 "Flags:%x, Packets_flooded:%x, Status: %s ",
1300 rulla->flags, rulla->packets_flooded,
1301 get_status_string(rulla->status));
1302 offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);
1303 rulla = rulla->next;
1304 printk("%s",buf);
1306 rulla = lec_arp_empty_ones;
1307 if (rulla)
1308 printk("Empty ones\n");
1309 while(rulla) {
1310 offset=0;
1311 offset += sprintf(buf+offset,"Mac:");
1312 for(j=0;j<ETH_ALEN;j++) {
1313 offset+=sprintf(buf+offset,"%2.2x ",
1314 rulla->mac_addr[j]&0xff);
1316 offset +=sprintf(buf+offset,"Atm:");
1317 for(j=0;j<ATM_ESA_LEN;j++) {
1318 offset+=sprintf(buf+offset,"%2.2x ",
1319 rulla->atm_addr[j]&0xff);
1321 offset+=sprintf(buf+offset,
1322 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
1323 rulla->vcc?rulla->vcc->vpi:0,
1324 rulla->vcc?rulla->vcc->vci:0,
1325 rulla->recv_vcc?rulla->recv_vcc->vpi:0,
1326 rulla->recv_vcc?rulla->recv_vcc->vci:0,
1327 rulla->last_used,
1328 rulla->timestamp, rulla->no_tries);
1329 offset+=sprintf(buf+offset,
1330 "Flags:%x, Packets_flooded:%x, Status: %s ",
1331 rulla->flags, rulla->packets_flooded,
1332 get_status_string(rulla->status));
1333 offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);
1334 rulla = rulla->next;
1335 printk("%s",buf);
1338 rulla = mcast_fwds;
1339 if (rulla)
1340 printk("Multicast Forward VCCs\n");
1341 while(rulla) {
1342 offset=0;
1343 offset += sprintf(buf+offset,"Mac:");
1344 for(j=0;j<ETH_ALEN;j++) {
1345 offset+=sprintf(buf+offset,"%2.2x ",
1346 rulla->mac_addr[j]&0xff);
1348 offset +=sprintf(buf+offset,"Atm:");
1349 for(j=0;j<ATM_ESA_LEN;j++) {
1350 offset+=sprintf(buf+offset,"%2.2x ",
1351 rulla->atm_addr[j]&0xff);
1353 offset+=sprintf(buf+offset,
1354 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
1355 rulla->vcc?rulla->vcc->vpi:0,
1356 rulla->vcc?rulla->vcc->vci:0,
1357 rulla->recv_vcc?rulla->recv_vcc->vpi:0,
1358 rulla->recv_vcc?rulla->recv_vcc->vci:0,
1359 rulla->last_used,
1360 rulla->timestamp, rulla->no_tries);
1361 offset+=sprintf(buf+offset,
1362 "Flags:%x, Packets_flooded:%x, Status: %s ",
1363 rulla->flags, rulla->packets_flooded,
1364 get_status_string(rulla->status));
1365 offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);
1366 rulla = rulla->next;
1367 printk("%s",buf);
1370 #endif
1374 * Destruction of arp-cache
1376 void
1377 lec_arp_destroy(struct lec_priv *priv)
1379 struct lec_arp_table *entry, *next;
1380 unsigned long flags;
1381 int i;
1383 save_flags(flags);
1384 cli();
1386 del_timer(&priv->lec_arp_timer);
1389 * Remove all entries
1391 for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {
1392 for(entry =priv->lec_arp_tables[i];entry != NULL; entry=next) {
1393 next = entry->next;
1394 lec_arp_remove(priv->lec_arp_tables, entry);
1395 kfree(entry);
1398 entry = priv->lec_arp_empty_ones;
1399 while(entry) {
1400 next = entry->next;
1401 del_timer(&entry->timer);
1402 lec_arp_clear_vccs(entry);
1403 kfree(entry);
1404 entry = next;
1406 priv->lec_arp_empty_ones = NULL;
1407 entry = priv->lec_no_forward;
1408 while(entry) {
1409 next = entry->next;
1410 del_timer(&entry->timer);
1411 lec_arp_clear_vccs(entry);
1412 kfree(entry);
1413 entry = next;
1415 priv->lec_no_forward = NULL;
1416 entry = priv->mcast_fwds;
1417 while(entry) {
1418 next = entry->next;
1419 del_timer(&entry->timer);
1420 lec_arp_clear_vccs(entry);
1421 kfree(entry);
1422 entry = next;
1424 priv->mcast_fwds = NULL;
1425 priv->mcast_vcc = NULL;
1426 memset(priv->lec_arp_tables, 0,
1427 sizeof(struct lec_arp_table*)*LEC_ARP_TABLE_SIZE);
1428 restore_flags(flags);
1433 * Find entry by mac_address
1435 static __inline__ struct lec_arp_table*
1436 lec_arp_find(struct lec_priv *priv,
1437 unsigned char *mac_addr)
1439 unsigned short place;
1440 struct lec_arp_table *to_return;
1442 DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
1443 mac_addr[0]&0xff, mac_addr[1]&0xff, mac_addr[2]&0xff,
1444 mac_addr[3]&0xff, mac_addr[4]&0xff, mac_addr[5]&0xff);
1445 lec_arp_lock(priv);
1446 place = HASH(mac_addr[ETH_ALEN-1]);
1448 to_return = priv->lec_arp_tables[place];
1449 while(to_return) {
1450 if (memcmp(mac_addr, to_return->mac_addr, ETH_ALEN) == 0) {
1451 lec_arp_unlock(priv);
1452 return to_return;
1454 to_return = to_return->next;
1456 lec_arp_unlock(priv);
1457 return NULL;
1460 static struct lec_arp_table*
1461 make_entry(struct lec_priv *priv, unsigned char *mac_addr)
1463 struct lec_arp_table *to_return;
1465 to_return=(struct lec_arp_table *)kmalloc(sizeof(struct lec_arp_table),
1466 GFP_ATOMIC);
1467 if (!to_return) {
1468 printk("LEC: Arp entry kmalloc failed\n");
1469 return NULL;
1471 memset(to_return,0,sizeof(struct lec_arp_table));
1472 memcpy(to_return->mac_addr, mac_addr, ETH_ALEN);
1473 init_timer(&to_return->timer);
1474 to_return->timer.function = lec_arp_expire_arp;
1475 to_return->timer.data = (unsigned long)to_return;
1476 to_return->last_used = jiffies;
1477 to_return->priv = priv;
1478 skb_queue_head_init(&to_return->tx_wait);
1479 return to_return;
1484 * Arp sent timer expired
1487 static void
1488 lec_arp_expire_arp(unsigned long data)
1490 struct lec_arp_table *entry;
1492 entry = (struct lec_arp_table *)data;
1494 del_timer(&entry->timer);
1496 DPRINTK("lec_arp_expire_arp\n");
1497 if (entry->status == ESI_ARP_PENDING) {
1498 if (entry->no_tries <= entry->priv->max_retry_count) {
1499 if (entry->is_rdesc)
1500 send_to_lecd(entry->priv, l_rdesc_arp_xmt, entry->mac_addr, NULL, NULL);
1501 else
1502 send_to_lecd(entry->priv, l_arp_xmt, entry->mac_addr, NULL, NULL);
1503 entry->no_tries++;
1505 entry->timer.expires = jiffies + (1*HZ);
1506 add_timer(&entry->timer);
1512 * Unknown/unused vcc expire, remove associated entry
1515 static void
1516 lec_arp_expire_vcc(unsigned long data)
1518 struct lec_arp_table *to_remove = (struct lec_arp_table*)data;
1519 struct lec_priv *priv = (struct lec_priv *)to_remove->priv;
1520 struct lec_arp_table *entry = NULL;
1522 del_timer(&to_remove->timer);
1524 DPRINTK("LEC_ARP %p %p: lec_arp_expire_vcc vpi:%d vci:%d\n",
1525 to_remove, priv,
1526 to_remove->vcc?to_remove->recv_vcc->vpi:0,
1527 to_remove->vcc?to_remove->recv_vcc->vci:0);
1528 DPRINTK("eo:%p nf:%p\n",priv->lec_arp_empty_ones,priv->lec_no_forward);
1529 if (to_remove == priv->lec_arp_empty_ones)
1530 priv->lec_arp_empty_ones = to_remove->next;
1531 else {
1532 entry = priv->lec_arp_empty_ones;
1533 while (entry && entry->next != to_remove)
1534 entry = entry->next;
1535 if (entry)
1536 entry->next = to_remove->next;
1538 if (!entry)
1539 if (to_remove == priv->lec_no_forward) {
1540 priv->lec_no_forward = to_remove->next;
1541 } else {
1542 entry = priv->lec_no_forward;
1543 while (entry && entry->next != to_remove)
1544 entry = entry->next;
1545 if (entry)
1546 entry->next = to_remove->next;
1548 lec_arp_clear_vccs(to_remove);
1549 kfree(to_remove);
1553 * Expire entries.
1554 * 1. Re-set timer
1555 * 2. For each entry, delete entries that have aged past the age limit.
1556 * 3. For each entry, depending on the status of the entry, perform
1557 * the following maintenance.
1558 * a. If status is ESI_VC_PENDING or ESI_ARP_PENDING then if the
1559 * tick_count is above the max_unknown_frame_time, clear
1560 * the tick_count to zero and clear the packets_flooded counter
1561 * to zero. This supports the packet rate limit per address
1562 * while flooding unknowns.
1563 * b. If the status is ESI_FLUSH_PENDING and the tick_count is greater
1564 * than or equal to the path_switching_delay, change the status
1565 * to ESI_FORWARD_DIRECT. This causes the flush period to end
1566 * regardless of the progress of the flush protocol.
1568 static void
1569 lec_arp_check_expire(unsigned long data)
1571 struct lec_priv *priv = (struct lec_priv *)data;
1572 struct lec_arp_table **lec_arp_tables =
1573 (struct lec_arp_table **)priv->lec_arp_tables;
1574 struct lec_arp_table *entry, *next;
1575 unsigned long now;
1576 unsigned long time_to_check;
1577 int i;
1579 del_timer(&priv->lec_arp_timer);
1581 DPRINTK("lec_arp_check_expire %p,%d\n",priv,
1582 priv->lec_arp_lock_var.counter);
1583 DPRINTK("expire: eo:%p nf:%p\n",priv->lec_arp_empty_ones,
1584 priv->lec_no_forward);
1585 if (!priv->lec_arp_lock_var.counter) {
1586 lec_arp_lock(priv);
1587 now = jiffies;
1588 for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
1589 for(entry = lec_arp_tables[i];entry != NULL;) {
1590 if ((entry->flags) & LEC_REMOTE_FLAG &&
1591 priv->topology_change)
1592 time_to_check=priv->forward_delay_time;
1593 else
1594 time_to_check = priv->aging_time;
1596 DPRINTK("About to expire: %lx - %lx > %lx\n",
1597 now,entry->last_used, time_to_check);
1598 if( time_after(now, entry->last_used+
1599 time_to_check) &&
1600 !(entry->flags & LEC_PERMANENT_FLAG) &&
1601 !(entry->mac_addr[0] & 0x01) ) { /* LANE2: 7.1.20 */
1602 /* Remove entry */
1603 DPRINTK("LEC:Entry timed out\n");
1604 next = entry->next;
1605 lec_arp_remove(lec_arp_tables, entry);
1606 kfree(entry);
1607 entry = next;
1608 } else {
1609 /* Something else */
1610 if ((entry->status == ESI_VC_PENDING ||
1611 entry->status == ESI_ARP_PENDING)
1612 && time_after_eq(now,
1613 entry->timestamp +
1614 priv->max_unknown_frame_time)) {
1615 entry->timestamp = jiffies;
1616 entry->packets_flooded = 0;
1617 if (entry->status == ESI_VC_PENDING)
1618 send_to_lecd(priv, l_svc_setup, entry->mac_addr, entry->atm_addr, NULL);
1620 if (entry->status == ESI_FLUSH_PENDING
1622 time_after_eq(now, entry->timestamp+
1623 priv->path_switching_delay)) {
1624 entry->last_used = jiffies;
1625 entry->status =
1626 ESI_FORWARD_DIRECT;
1628 entry = entry->next;
1632 lec_arp_unlock(priv);
1634 priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL;
1635 add_timer(&priv->lec_arp_timer);
1638 * Try to find vcc where mac_address is attached.
1641 struct atm_vcc*
1642 lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find, int is_rdesc,
1643 struct lec_arp_table **ret_entry)
1645 struct lec_arp_table *entry;
1647 if (mac_to_find[0]&0x01) {
1648 switch (priv->lane_version) {
1649 case 1:
1650 return priv->mcast_vcc;
1651 break;
1652 case 2: /* LANE2 wants arp for multicast addresses */
1653 if ( memcmp(mac_to_find, bus_mac, ETH_ALEN) == 0)
1654 return priv->mcast_vcc;
1655 break;
1656 default:
1657 break;
1661 entry = lec_arp_find(priv, mac_to_find);
1663 if (entry) {
1664 if (entry->status == ESI_FORWARD_DIRECT) {
1665 /* Connection Ok */
1666 entry->last_used = jiffies;
1667 *ret_entry = entry;
1668 return entry->vcc;
1670 /* Data direct VC not yet set up, check to see if the unknown
1671 frame count is greater than the limit. If the limit has
1672 not been reached, allow the caller to send packet to
1673 BUS. */
1674 if (entry->status != ESI_FLUSH_PENDING &&
1675 entry->packets_flooded<priv->maximum_unknown_frame_count) {
1676 entry->packets_flooded++;
1677 DPRINTK("LEC_ARP: Flooding..\n");
1678 return priv->mcast_vcc;
1680 /* We got here because entry->status == ESI_FLUSH_PENDING
1681 * or BUS flood limit was reached for an entry which is
1682 * in ESI_ARP_PENDING or ESI_VC_PENDING state.
1684 *ret_entry = entry;
1685 DPRINTK("lec: entry->status %d entry->vcc %p\n", entry->status, entry->vcc);
1686 return NULL;
1687 } else {
1688 /* No matching entry was found */
1689 entry = make_entry(priv, mac_to_find);
1690 DPRINTK("LEC_ARP: Making entry\n");
1691 if (!entry) {
1692 return priv->mcast_vcc;
1694 lec_arp_put(priv->lec_arp_tables, entry);
1695 /* We want arp-request(s) to be sent */
1696 entry->packets_flooded =1;
1697 entry->status = ESI_ARP_PENDING;
1698 entry->no_tries = 1;
1699 entry->last_used = entry->timestamp = jiffies;
1700 entry->is_rdesc = is_rdesc;
1701 if (entry->is_rdesc)
1702 send_to_lecd(priv, l_rdesc_arp_xmt, mac_to_find, NULL, NULL);
1703 else
1704 send_to_lecd(priv, l_arp_xmt, mac_to_find, NULL, NULL);
1705 entry->timer.expires = jiffies + (1*HZ);
1706 entry->timer.function = lec_arp_expire_arp;
1707 add_timer(&entry->timer);
1708 return priv->mcast_vcc;
1713 lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
1714 unsigned long permanent)
1716 struct lec_arp_table *entry, *next;
1717 int i;
1719 lec_arp_lock(priv);
1720 DPRINTK("lec_addr_delete\n");
1721 for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
1722 for(entry=priv->lec_arp_tables[i];entry != NULL; entry=next) {
1723 next = entry->next;
1724 if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)
1725 && (permanent ||
1726 !(entry->flags & LEC_PERMANENT_FLAG))) {
1727 lec_arp_remove(priv->lec_arp_tables, entry);
1728 kfree(entry);
1730 lec_arp_unlock(priv);
1731 return 0;
1734 lec_arp_unlock(priv);
1735 return -1;
1739 * Notifies: Response to arp_request (atm_addr != NULL)
1741 void
1742 lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
1743 unsigned char *atm_addr, unsigned long remoteflag,
1744 unsigned int targetless_le_arp)
1746 struct lec_arp_table *entry, *tmp;
1747 int i;
1749 DPRINTK("lec:%s", (targetless_le_arp) ? "targetless ": " ");
1750 DPRINTK("lec_arp_update mac:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
1751 mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],
1752 mac_addr[4],mac_addr[5]);
1754 entry = lec_arp_find(priv, mac_addr);
1755 if (entry == NULL && targetless_le_arp)
1756 return; /* LANE2: ignore targetless LE_ARPs for which
1757 * we have no entry in the cache. 7.1.30
1759 lec_arp_lock(priv);
1760 if (priv->lec_arp_empty_ones) {
1761 entry = priv->lec_arp_empty_ones;
1762 if (!memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN)) {
1763 priv->lec_arp_empty_ones = entry->next;
1764 } else {
1765 while(entry->next && memcmp(entry->next->atm_addr,
1766 atm_addr, ATM_ESA_LEN))
1767 entry = entry->next;
1768 if (entry->next) {
1769 tmp = entry;
1770 entry = entry->next;
1771 tmp->next = entry->next;
1772 } else
1773 entry = NULL;
1776 if (entry) {
1777 del_timer(&entry->timer);
1778 tmp = lec_arp_find(priv, mac_addr);
1779 if (tmp) {
1780 del_timer(&tmp->timer);
1781 tmp->status = ESI_FORWARD_DIRECT;
1782 memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN);
1783 tmp->vcc = entry->vcc;
1784 tmp->old_push = entry->old_push;
1785 tmp->last_used = jiffies;
1786 del_timer(&entry->timer);
1787 kfree(entry);
1788 entry=tmp;
1789 } else {
1790 entry->status = ESI_FORWARD_DIRECT;
1791 memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
1792 entry->last_used = jiffies;
1793 lec_arp_put(priv->lec_arp_tables, entry);
1795 if (remoteflag)
1796 entry->flags|=LEC_REMOTE_FLAG;
1797 else
1798 entry->flags&=~LEC_REMOTE_FLAG;
1799 lec_arp_unlock(priv);
1800 DPRINTK("After update\n");
1801 dump_arp_table(priv);
1802 return;
1805 entry = lec_arp_find(priv, mac_addr);
1806 if (!entry) {
1807 entry = make_entry(priv, mac_addr);
1808 entry->status = ESI_UNKNOWN;
1809 lec_arp_put(priv->lec_arp_tables, entry);
1810 /* Temporary, changes before end of function */
1812 memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN);
1813 del_timer(&entry->timer);
1814 for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
1815 for(tmp=priv->lec_arp_tables[i];tmp;tmp=tmp->next) {
1816 if (entry != tmp &&
1817 !memcmp(tmp->atm_addr, atm_addr,
1818 ATM_ESA_LEN)) {
1819 /* Vcc to this host exists */
1820 if (tmp->status > ESI_VC_PENDING) {
1822 * ESI_FLUSH_PENDING,
1823 * ESI_FORWARD_DIRECT
1825 entry->vcc = tmp->vcc;
1826 entry->old_push=tmp->old_push;
1828 entry->status=tmp->status;
1829 break;
1833 if (remoteflag)
1834 entry->flags|=LEC_REMOTE_FLAG;
1835 else
1836 entry->flags&=~LEC_REMOTE_FLAG;
1837 if (entry->status == ESI_ARP_PENDING ||
1838 entry->status == ESI_UNKNOWN) {
1839 entry->status = ESI_VC_PENDING;
1840 send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL);
1842 DPRINTK("After update2\n");
1843 dump_arp_table(priv);
1844 lec_arp_unlock(priv);
1848 * Notifies: Vcc setup ready
1850 void
1851 lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
1852 struct atm_vcc *vcc,
1853 void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb))
1855 struct lec_arp_table *entry;
1856 int i, found_entry=0;
1858 lec_arp_lock(priv);
1859 if (ioc_data->receive == 2) {
1860 /* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */
1862 DPRINTK("LEC_ARP: Attaching mcast forward\n");
1863 #if 0
1864 entry = lec_arp_find(priv, bus_mac);
1865 if (!entry) {
1866 printk("LEC_ARP: Multicast entry not found!\n");
1867 lec_arp_unlock(priv);
1868 return;
1870 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
1871 entry->recv_vcc = vcc;
1872 entry->old_recv_push = old_push;
1873 #endif
1874 entry = make_entry(priv, bus_mac);
1875 if (entry == NULL) {
1876 lec_arp_unlock(priv);
1877 return;
1879 del_timer(&entry->timer);
1880 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
1881 entry->recv_vcc = vcc;
1882 entry->old_recv_push = old_push;
1883 entry->next = priv->mcast_fwds;
1884 priv->mcast_fwds = entry;
1885 lec_arp_unlock(priv);
1886 return;
1887 } else if (ioc_data->receive == 1) {
1888 /* Vcc which we don't want to make default vcc, attach it
1889 anyway. */
1890 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",
1891 ioc_data->atm_addr[0],ioc_data->atm_addr[1],
1892 ioc_data->atm_addr[2],ioc_data->atm_addr[3],
1893 ioc_data->atm_addr[4],ioc_data->atm_addr[5],
1894 ioc_data->atm_addr[6],ioc_data->atm_addr[7],
1895 ioc_data->atm_addr[8],ioc_data->atm_addr[9],
1896 ioc_data->atm_addr[10],ioc_data->atm_addr[11],
1897 ioc_data->atm_addr[12],ioc_data->atm_addr[13],
1898 ioc_data->atm_addr[14],ioc_data->atm_addr[15],
1899 ioc_data->atm_addr[16],ioc_data->atm_addr[17],
1900 ioc_data->atm_addr[18],ioc_data->atm_addr[19]);
1901 entry = make_entry(priv, bus_mac);
1902 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
1903 memset(entry->mac_addr, 0, ETH_ALEN);
1904 entry->recv_vcc = vcc;
1905 entry->old_recv_push = old_push;
1906 entry->status = ESI_UNKNOWN;
1907 entry->timer.expires = jiffies + priv->vcc_timeout_period;
1908 entry->timer.function = lec_arp_expire_vcc;
1909 add_timer(&entry->timer);
1910 entry->next = priv->lec_no_forward;
1911 priv->lec_no_forward = entry;
1912 lec_arp_unlock(priv);
1913 dump_arp_table(priv);
1914 return;
1916 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",
1917 ioc_data->atm_addr[0],ioc_data->atm_addr[1],
1918 ioc_data->atm_addr[2],ioc_data->atm_addr[3],
1919 ioc_data->atm_addr[4],ioc_data->atm_addr[5],
1920 ioc_data->atm_addr[6],ioc_data->atm_addr[7],
1921 ioc_data->atm_addr[8],ioc_data->atm_addr[9],
1922 ioc_data->atm_addr[10],ioc_data->atm_addr[11],
1923 ioc_data->atm_addr[12],ioc_data->atm_addr[13],
1924 ioc_data->atm_addr[14],ioc_data->atm_addr[15],
1925 ioc_data->atm_addr[16],ioc_data->atm_addr[17],
1926 ioc_data->atm_addr[18],ioc_data->atm_addr[19]);
1927 for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {
1928 for (entry = priv->lec_arp_tables[i];entry;entry=entry->next) {
1929 if (memcmp(ioc_data->atm_addr, entry->atm_addr,
1930 ATM_ESA_LEN)==0) {
1931 DPRINTK("LEC_ARP: Attaching data direct\n");
1932 DPRINTK("Currently -> Vcc: %d, Rvcc:%d\n",
1933 entry->vcc?entry->vcc->vci:0,
1934 entry->recv_vcc?entry->recv_vcc->vci:0);
1935 found_entry=1;
1936 del_timer(&entry->timer);
1937 entry->vcc = vcc;
1938 entry->old_push = old_push;
1939 if (entry->status == ESI_VC_PENDING) {
1940 if(priv->maximum_unknown_frame_count
1941 ==0)
1942 entry->status =
1943 ESI_FORWARD_DIRECT;
1944 else {
1945 entry->timestamp = jiffies;
1946 entry->status =
1947 ESI_FLUSH_PENDING;
1948 #if 0
1949 send_to_lecd(priv,l_flush_xmt,
1950 NULL,
1951 entry->atm_addr,
1952 NULL);
1953 #endif
1955 } else {
1956 /* They were forming a connection
1957 to us, and we to them. Our
1958 ATM address is numerically lower
1959 than theirs, so we make connection
1960 we formed into default VCC (8.1.11).
1961 Connection they made gets torn
1962 down. This might confuse some
1963 clients. Can be changed if
1964 someone reports trouble... */
1970 if (found_entry) {
1971 lec_arp_unlock(priv);
1972 DPRINTK("After vcc was added\n");
1973 dump_arp_table(priv);
1974 return;
1976 /* Not found, snatch address from first data packet that arrives from
1977 this vcc */
1978 entry = make_entry(priv, bus_mac);
1979 entry->vcc = vcc;
1980 entry->old_push = old_push;
1981 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
1982 memset(entry->mac_addr, 0, ETH_ALEN);
1983 entry->status = ESI_UNKNOWN;
1984 entry->next = priv->lec_arp_empty_ones;
1985 priv->lec_arp_empty_ones = entry;
1986 entry->timer.expires = jiffies + priv->vcc_timeout_period;
1987 entry->timer.function = lec_arp_expire_vcc;
1988 add_timer(&entry->timer);
1989 lec_arp_unlock(priv);
1990 DPRINTK("After vcc was added\n");
1991 dump_arp_table(priv);
1994 void
1995 lec_flush_complete(struct lec_priv *priv, unsigned long tran_id)
1997 struct lec_arp_table *entry;
1998 int i;
2000 DPRINTK("LEC:lec_flush_complete %lx\n",tran_id);
2001 for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {
2002 for (entry=priv->lec_arp_tables[i];entry;entry=entry->next) {
2003 if (entry->flush_tran_id == tran_id &&
2004 entry->status == ESI_FLUSH_PENDING) {
2005 entry->status = ESI_FORWARD_DIRECT;
2006 DPRINTK("LEC_ARP: Flushed\n");
2010 dump_arp_table(priv);
2013 void
2014 lec_set_flush_tran_id(struct lec_priv *priv,
2015 unsigned char *atm_addr, unsigned long tran_id)
2017 struct lec_arp_table *entry;
2018 int i;
2020 for (i=0;i<LEC_ARP_TABLE_SIZE;i++)
2021 for(entry=priv->lec_arp_tables[i];entry;entry=entry->next)
2022 if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) {
2023 entry->flush_tran_id = tran_id;
2024 DPRINTK("Set flush transaction id to %lx for %p\n",tran_id,entry);
2028 int
2029 lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc)
2031 unsigned char mac_addr[] = {
2032 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2033 struct lec_arp_table *to_add;
2035 lec_arp_lock(priv);
2036 to_add = make_entry(priv, mac_addr);
2037 if (!to_add) {
2038 lec_arp_unlock(priv);
2039 return -ENOMEM;
2041 memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN);
2042 to_add->status = ESI_FORWARD_DIRECT;
2043 to_add->flags |= LEC_PERMANENT_FLAG;
2044 to_add->vcc = vcc;
2045 to_add->old_push = vcc->push;
2046 vcc->push = lec_push;
2047 priv->mcast_vcc = vcc;
2048 lec_arp_put(priv->lec_arp_tables, to_add);
2049 lec_arp_unlock(priv);
2050 return 0;
2053 void
2054 lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
2056 struct lec_arp_table *entry, *next;
2057 int i;
2059 DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n",vcc->vpi,vcc->vci);
2060 dump_arp_table(priv);
2061 lec_arp_lock(priv);
2062 for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
2063 for(entry = priv->lec_arp_tables[i];entry; entry=next) {
2064 next = entry->next;
2065 if (vcc == entry->vcc) {
2066 lec_arp_remove(priv->lec_arp_tables,entry);
2067 kfree(entry);
2068 if (priv->mcast_vcc == vcc) {
2069 priv->mcast_vcc = NULL;
2075 entry = priv->lec_arp_empty_ones;
2076 priv->lec_arp_empty_ones = NULL;
2077 while (entry != NULL) {
2078 next = entry->next;
2079 if (entry->vcc == vcc) { /* leave it out from the list */
2080 lec_arp_clear_vccs(entry);
2081 del_timer(&entry->timer);
2082 kfree(entry);
2084 else { /* put it back to the list */
2085 entry->next = priv->lec_arp_empty_ones;
2086 priv->lec_arp_empty_ones = entry;
2088 entry = next;
2091 entry = priv->lec_no_forward;
2092 priv->lec_no_forward = NULL;
2093 while (entry != NULL) {
2094 next = entry->next;
2095 if (entry->recv_vcc == vcc) {
2096 lec_arp_clear_vccs(entry);
2097 del_timer(&entry->timer);
2098 kfree(entry);
2100 else {
2101 entry->next = priv->lec_no_forward;
2102 priv->lec_no_forward = entry;
2104 entry = next;
2107 entry = priv->mcast_fwds;
2108 priv->mcast_fwds = NULL;
2109 while (entry != NULL) {
2110 next = entry->next;
2111 if (entry->recv_vcc == vcc) {
2112 lec_arp_clear_vccs(entry);
2113 /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
2114 kfree(entry);
2116 else {
2117 entry->next = priv->mcast_fwds;
2118 priv->mcast_fwds = entry;
2120 entry = next;
2123 lec_arp_unlock(priv);
2124 dump_arp_table(priv);
2127 void
2128 lec_arp_check_empties(struct lec_priv *priv,
2129 struct atm_vcc *vcc, struct sk_buff *skb)
2131 struct lec_arp_table *entry, *prev;
2132 struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
2133 unsigned long flags;
2134 unsigned char *src;
2135 #ifdef CONFIG_TR
2136 struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data;
2138 if (priv->is_trdev) src = tr_hdr->h_source;
2139 else
2140 #endif
2141 src = hdr->h_source;
2143 lec_arp_lock(priv);
2144 entry = priv->lec_arp_empty_ones;
2145 if (vcc == entry->vcc) {
2146 save_flags(flags);
2147 cli();
2148 del_timer(&entry->timer);
2149 memcpy(entry->mac_addr, src, ETH_ALEN);
2150 entry->status = ESI_FORWARD_DIRECT;
2151 entry->last_used = jiffies;
2152 priv->lec_arp_empty_ones = entry->next;
2153 restore_flags(flags);
2154 /* We might have got an entry */
2155 if ((prev=lec_arp_find(priv,src))) {
2156 lec_arp_remove(priv->lec_arp_tables, prev);
2157 kfree(prev);
2159 lec_arp_put(priv->lec_arp_tables, entry);
2160 lec_arp_unlock(priv);
2161 return;
2163 prev = entry;
2164 entry = entry->next;
2165 while (entry && entry->vcc != vcc) {
2166 prev= entry;
2167 entry = entry->next;
2169 if (!entry) {
2170 DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n");
2171 lec_arp_unlock(priv);
2172 return;
2174 save_flags(flags);
2175 cli();
2176 del_timer(&entry->timer);
2177 memcpy(entry->mac_addr, src, ETH_ALEN);
2178 entry->status = ESI_FORWARD_DIRECT;
2179 entry->last_used = jiffies;
2180 prev->next = entry->next;
2181 restore_flags(flags);
2182 if ((prev = lec_arp_find(priv, src))) {
2183 lec_arp_remove(priv->lec_arp_tables,prev);
2184 kfree(prev);
2186 lec_arp_put(priv->lec_arp_tables,entry);
2187 lec_arp_unlock(priv);