2 * lec.c: Lan Emulation driver
3 * Marko Kiiskila carnil@cs.tut.fi
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>
15 #include <linux/skbuff.h>
17 #include <asm/byteorder.h>
18 #include <asm/uaccess.h>
21 #include <linux/proc_fs.h>
23 /* TokenRing if needed */
25 #include <linux/trdevice.h>
29 #include <linux/atmdev.h>
30 #include <linux/atmlec.h>
38 #include <linux/module.h>
43 #include "resources.h" /* for bind_vcc() */
46 #define DPRINTK printk
48 #define DPRINTK(format,args...)
51 #define DUMP_PACKETS 0 /* 0 = None,
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
);
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) {
96 static void handle_bridge(struct sk_buff
*skb
, struct net_device
*dev
)
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
);
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
142 unsigned char *get_tr_dst(unsigned char *packet
, unsigned char *rdesc
)
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 */
157 return trh
->daddr
; /* not source routed */
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));
169 memcpy(&rdesc
[4], &trh
->rseg
[1], sizeof(uint16_t));
170 rdesc
[5] = ((ntohs(trh
->rseg
[0]) & 0x000f) | (rdesc
[5] & 0xf0));
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.
187 lec_open(struct net_device
*dev
)
189 struct lec_priv
*priv
= (struct lec_priv
*)dev
->priv
;
194 memset(&priv
->stats
,0,sizeof(struct net_device_stats
));
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
;
209 unsigned char rdesc
[ETH_ALEN
]; /* Token Ring route descriptor */
215 #endif /* DUMP_PACKETS >0 */
217 DPRINTK("Lec_send_packet called\n");
219 printk("%s:No lecd attached\n",dev
->name
);
220 priv
->stats
.tx_errors
++;
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
);
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",
242 DPRINTK("skbuff head:%lx data:%lx tail:%lx end:%lx\n",
243 (long)skb
->head
, (long)skb
->data
, (long)skb
->tail
,
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
);
256 if (skb2
== NULL
) return 0;
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
);
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 */
280 printk("%s...\n",buf
);
281 #endif /* DUMP_PACKETS > 0 */
283 /* Minimum ethernet-frame size */
285 if (skb
->truesize
< 62) {
286 printk("%s:data packet %d / %d\n",
288 skb
->len
,skb
->truesize
);
289 nb
=(unsigned char*)kmalloc(64, GFP_ATOMIC
);
290 memcpy(nb
,skb
->data
,skb
->len
);
292 skb
->head
= skb
->data
= nb
;
302 /* Send to right vcc */
306 if (priv
->is_trdev
) {
307 dst
= get_tr_dst(skb
->data
+2, rdesc
);
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
);
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
++;
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? */
372 /* The inverse routine to net_open(). */
374 lec_close(struct net_device
*dev
)
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
;
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
;
399 char *tmp
; /* FIXME */
401 atomic_sub(skb
->truesize
+ATM_PDU_OVHD
, &vcc
->tx_inuse
);
402 mesg
= (struct atmlec_msg
*)skb
->data
;
404 tmp
+= sizeof(struct atmlec_msg
);
405 DPRINTK("%s: msg from zeppelin:%d\n", dev
->name
, mesg
->type
);
409 dev
->dev_addr
[i
] = mesg
->content
.normal
.mac_addr
[i
];
414 dev
->dev_addr
[i
] = 0;
418 lec_addr_delete(priv
, mesg
->content
.normal
.atm_addr
,
419 mesg
->content
.normal
.flag
);
421 case l_topology_change
:
422 priv
->topology_change
= mesg
->content
.normal
.flag
;
424 case l_flush_complete
:
425 lec_flush_complete(priv
, mesg
->content
.normal
.flag
);
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
)
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
);
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
);
470 case l_flush_tran_id
:
471 lec_set_flush_tran_id(priv
, mesg
->content
.normal
.atm_addr
,
472 mesg
->content
.normal
.flag
);
475 priv
->lecid
=(unsigned short)(0xffff&mesg
->content
.normal
.flag
);
477 case l_should_bridge
: {
480 extern Port_data port_info
[];
482 DPRINTK("%s: bridge zeppelin asks about 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
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 */
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 */
507 printk("%s: Unknown message type %d\n", dev
->name
, mesg
->type
);
516 lec_atm_close(struct atm_vcc
*vcc
)
519 struct net_device
*dev
= (struct net_device
*)vcc
->proto_data
;
520 struct lec_priv
*priv
= (struct lec_priv
*)dev
->priv
;
523 /* Do something needful? */
528 lec_arp_destroy(priv
);
530 if (skb_peek(&vcc
->recvq
))
531 printk("%s lec_atm_close: closing with messages pending\n",
533 while ((skb
= skb_dequeue(&vcc
->recvq
))) {
534 atm_return(vcc
, skb
->truesize
);
538 printk("%s: Shut down!\n", dev
->name
);
542 static struct atmdev_ops lecdev_ops
= {
545 lec_atm_close
, /*close*/
547 NULL
, /*getsockopt */
548 NULL
, /*setsockopt */
549 lec_atm_send
, /*send */
551 #if 0 /* these are disabled in <linux/atmdev.h> too */
559 NULL
, /* change_qos*/
560 NULL
/* free_rx_skb*/
563 static struct atm_dev lecatm_dev
= {
567 999, /*dummy device number*/
568 NULL
,NULL
, /*no VCCs*/
569 NULL
,NULL
, /*no data*/
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
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
)
585 struct atmlec_msg
*mesg
;
587 if (!priv
|| !priv
->lecd
) {
590 skb
= alloc_skb(sizeof(struct atmlec_msg
), GFP_ATOMIC
);
593 skb
->len
= sizeof(struct atmlec_msg
);
594 mesg
= (struct atmlec_msg
*)skb
->data
;
595 memset(mesg
, 0, sizeof(struct atmlec_msg
));
598 mesg
->sizeoftlvs
= data
->len
;
600 memcpy(&mesg
->content
.normal
.mac_addr
, mac_addr
, ETH_ALEN
);
602 mesg
->content
.normal
.targetless_le_arp
= 1;
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
);
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
);
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))
630 lec_init(struct net_device
*dev
)
632 struct lec_priv
*priv
;
634 priv
= (struct lec_priv
*)dev
->priv
;
635 if (priv
->is_trdev
) {
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
);
652 static unsigned char lec_ctrl_magic
[] = {
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
;
669 printk("%s: lec_push vcc vpi:%d vci:%d\n", dev
->name
,
673 DPRINTK("%s: null skb\n",dev
->name
);
674 lec_vcc_close(priv
, vcc
);
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 */
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
) ||
703 /* Probably looping back, or if lecd is missing,
704 lecd has gone down */
705 DPRINTK("Ignoring loopback frame...\n");
709 if (priv
->lec_arp_empty_ones
) { /* FILTER DATA!!!! */
710 lec_arp_check_empties(priv
, vcc
, skb
);
713 skb
->data
+= 2; /* skip lec_id */
715 if (priv
->is_trdev
) skb
->protocol
= tr_type_trans(skb
, dev
);
718 skb
->protocol
= eth_type_trans(skb
, dev
);
719 priv
->stats
.rx_packets
++;
720 priv
->stats
.rx_bytes
+= skb
->len
;
726 lec_vcc_attach(struct atm_vcc
*vcc
, void *arg
)
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",
737 if (ioc_data
.dev_num
< 0 || ioc_data
.dev_num
>= MAX_LEC_ITF
||
738 !dev_lec
[ioc_data
.dev_num
])
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
];
748 lec_mcast_attach(struct atm_vcc
*vcc
, int arg
)
750 if (arg
<0 || arg
>= MAX_LEC_ITF
|| !dev_lec
[arg
])
752 vcc
->proto_data
= dev_lec
[arg
];
753 return (lec_mcast_make((struct lec_priv
*)dev_lec
[arg
]->priv
, vcc
));
756 /* Initialize device. */
758 lecd_attach(struct atm_vcc
*vcc
, int arg
)
761 struct lec_priv
*priv
;
768 if (arg
>= MAX_LEC_ITF
)
770 #else /* Reserve the top NUM_TR_DEVS for TR */
771 if (arg
>= (MAX_LEC_ITF
-NUM_TR_DEVS
))
775 dev_lec
[i
] = (struct net_device
*)
776 kmalloc(sizeof(struct net_device
)+sizeof(myname
)+1,
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
)
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
))
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)
796 sprintf(dev_lec
[i
]->name
, "lec%d", i
); /* init_trdev globbers device name */
798 priv
= (struct lec_priv
*)dev_lec
[i
]->priv
;
803 priv
->itfnum
= i
; /* LANE2 addition */
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;
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");
843 int init_module(void)
845 extern struct atm_lane_ops atm_lane_ops
;
847 atm_lane_init_ops(&atm_lane_ops
);
852 void cleanup_module(void)
855 extern struct atm_lane_ops atm_lane_ops
;
856 struct lec_priv
*priv
;
859 printk(KERN_NOTICE
"lec.c: module in use\n");
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
) {
873 unregister_trdev(dev_lec
[i
]);
876 unregister_netdev(dev_lec
[i
]);
877 kfree(dev_lec
[i
]->priv
);
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
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
;
903 table
= lec_arp_find(priv
, dst_mac
);
907 *tlvs
= kmalloc(table
->sizeoftlvs
, GFP_KERNEL
);
911 memcpy(*tlvs
, table
->tlvs
, table
->sizeoftlvs
);
912 *sizeoftlvs
= table
->sizeoftlvs
;
917 if (sizeoftlvs
== NULL
)
918 retval
= send_to_lecd(priv
, l_arp_xmt
, dst_mac
, NULL
, NULL
);
921 skb
= alloc_skb(*sizeoftlvs
, GFP_ATOMIC
);
924 skb
->len
= *sizeoftlvs
;
925 memcpy(skb
->data
, *tlvs
, *sizeoftlvs
);
926 retval
= send_to_lecd(priv
, l_arp_xmt
, dst_mac
, NULL
, skb
);
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
)
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
)
954 priv
->sizeoftlvs
= sizeoftlvs
;
955 memcpy(priv
->tlvs
, tlvs
, sizeoftlvs
);
957 skb
= alloc_skb(sizeoftlvs
, GFP_ATOMIC
);
960 skb
->len
= sizeoftlvs
;
961 memcpy(skb
->data
, tlvs
, sizeoftlvs
);
962 retval
= send_to_lecd(priv
, l_associate_req
, NULL
, NULL
, skb
);
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
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
)
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
);
987 return; /* should not happen */
991 entry
->tlvs
= kmalloc(sizeoftlvs
, GFP_KERNEL
);
992 if (entry
->tlvs
== NULL
)
995 entry
->sizeoftlvs
= sizeoftlvs
;
996 memcpy(entry
->tlvs
, tlvs
, sizeoftlvs
);
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
++]);
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
,
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>
1033 #define DPRINTK(format,args...)
1035 #define DPRINTK printk
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
);
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
1068 lec_arp_init(struct lec_priv
*priv
)
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
);
1083 lec_arp_clear_vccs(struct lec_arp_table
*entry
)
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
);
1092 atm_async_release_vcc(entry
->vcc
, -EPIPE
);
1095 if (entry
->recv_vcc
) {
1096 entry
->recv_vcc
->push
= entry
->old_recv_push
;
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
);
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
;
1122 place
= HASH(to_put
->mac_addr
[ETH_ALEN
-1]);
1123 tmp
= lec_arp_tables
[place
];
1124 to_put
->next
= NULL
;
1126 lec_arp_tables
[place
] = to_put
;
1128 else { /* add to the end */
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
;
1157 restore_flags(flags
);
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
;
1165 while(tmp
&& tmp
->next
!= to_remove
) {
1168 if (!tmp
) {/* Entry was not found */
1169 restore_flags(flags
);
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
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
,
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]);
1205 get_status_string(unsigned char st
)
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";
1225 dump_arp_table(struct lec_priv
*priv
)
1229 struct lec_arp_table
*rulla
;
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
];
1244 offset
+= sprintf(buf
,"%d: %p\n",i
, rulla
);
1246 offset
+= sprintf(buf
+offset
,"Mac:");
1247 for(j
=0;j
<ETH_ALEN
;j
++) {
1248 offset
+=sprintf(buf
+offset
,
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
,
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,
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
;
1275 rulla
= lec_no_forward
;
1277 printk("No forward\n");
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,
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
;
1306 rulla
= lec_arp_empty_ones
;
1308 printk("Empty ones\n");
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,
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
;
1340 printk("Multicast Forward VCCs\n");
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,
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
;
1374 * Destruction of arp-cache
1377 lec_arp_destroy(struct lec_priv
*priv
)
1379 struct lec_arp_table
*entry
, *next
;
1380 unsigned long flags
;
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
) {
1394 lec_arp_remove(priv
->lec_arp_tables
, entry
);
1398 entry
= priv
->lec_arp_empty_ones
;
1401 del_timer(&entry
->timer
);
1402 lec_arp_clear_vccs(entry
);
1406 priv
->lec_arp_empty_ones
= NULL
;
1407 entry
= priv
->lec_no_forward
;
1410 del_timer(&entry
->timer
);
1411 lec_arp_clear_vccs(entry
);
1415 priv
->lec_no_forward
= NULL
;
1416 entry
= priv
->mcast_fwds
;
1419 del_timer(&entry
->timer
);
1420 lec_arp_clear_vccs(entry
);
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);
1446 place
= HASH(mac_addr
[ETH_ALEN
-1]);
1448 to_return
= priv
->lec_arp_tables
[place
];
1450 if (memcmp(mac_addr
, to_return
->mac_addr
, ETH_ALEN
) == 0) {
1451 lec_arp_unlock(priv
);
1454 to_return
= to_return
->next
;
1456 lec_arp_unlock(priv
);
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
),
1468 printk("LEC: Arp entry kmalloc failed\n");
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
);
1484 * Arp sent timer expired
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
);
1502 send_to_lecd(entry
->priv
, l_arp_xmt
, entry
->mac_addr
, NULL
, NULL
);
1505 entry
->timer
.expires
= jiffies
+ (1*HZ
);
1506 add_timer(&entry
->timer
);
1512 * Unknown/unused vcc expire, remove associated entry
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",
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
;
1532 entry
= priv
->lec_arp_empty_ones
;
1533 while (entry
&& entry
->next
!= to_remove
)
1534 entry
= entry
->next
;
1536 entry
->next
= to_remove
->next
;
1539 if (to_remove
== priv
->lec_no_forward
) {
1540 priv
->lec_no_forward
= to_remove
->next
;
1542 entry
= priv
->lec_no_forward
;
1543 while (entry
&& entry
->next
!= to_remove
)
1544 entry
= entry
->next
;
1546 entry
->next
= to_remove
->next
;
1548 lec_arp_clear_vccs(to_remove
);
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.
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
;
1576 unsigned long time_to_check
;
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
) {
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
;
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
+
1600 !(entry
->flags
& LEC_PERMANENT_FLAG
) &&
1601 !(entry
->mac_addr
[0] & 0x01) ) { /* LANE2: 7.1.20 */
1603 DPRINTK("LEC:Entry timed out\n");
1605 lec_arp_remove(lec_arp_tables
, entry
);
1609 /* Something else */
1610 if ((entry
->status
== ESI_VC_PENDING
||
1611 entry
->status
== ESI_ARP_PENDING
)
1612 && time_after_eq(now
,
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
;
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.
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
) {
1650 return priv
->mcast_vcc
;
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
;
1661 entry
= lec_arp_find(priv
, mac_to_find
);
1664 if (entry
->status
== ESI_FORWARD_DIRECT
) {
1666 entry
->last_used
= jiffies
;
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
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.
1685 DPRINTK("lec: entry->status %d entry->vcc %p\n", entry
->status
, entry
->vcc
);
1688 /* No matching entry was found */
1689 entry
= make_entry(priv
, mac_to_find
);
1690 DPRINTK("LEC_ARP: Making entry\n");
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
);
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
;
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
) {
1724 if (!memcmp(atm_addr
, entry
->atm_addr
, ATM_ESA_LEN
)
1726 !(entry
->flags
& LEC_PERMANENT_FLAG
))) {
1727 lec_arp_remove(priv
->lec_arp_tables
, entry
);
1730 lec_arp_unlock(priv
);
1734 lec_arp_unlock(priv
);
1739 * Notifies: Response to arp_request (atm_addr != NULL)
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
;
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
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
;
1765 while(entry
->next
&& memcmp(entry
->next
->atm_addr
,
1766 atm_addr
, ATM_ESA_LEN
))
1767 entry
= entry
->next
;
1770 entry
= entry
->next
;
1771 tmp
->next
= entry
->next
;
1777 del_timer(&entry
->timer
);
1778 tmp
= lec_arp_find(priv
, mac_addr
);
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
);
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
);
1796 entry
->flags
|=LEC_REMOTE_FLAG
;
1798 entry
->flags
&=~LEC_REMOTE_FLAG
;
1799 lec_arp_unlock(priv
);
1800 DPRINTK("After update\n");
1801 dump_arp_table(priv
);
1805 entry
= lec_arp_find(priv
, mac_addr
);
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
) {
1817 !memcmp(tmp
->atm_addr
, atm_addr
,
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
;
1834 entry
->flags
|=LEC_REMOTE_FLAG
;
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
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;
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");
1864 entry
= lec_arp_find(priv
, bus_mac
);
1866 printk("LEC_ARP: Multicast entry not found!\n");
1867 lec_arp_unlock(priv
);
1870 memcpy(entry
->atm_addr
, ioc_data
->atm_addr
, ATM_ESA_LEN
);
1871 entry
->recv_vcc
= vcc
;
1872 entry
->old_recv_push
= old_push
;
1874 entry
= make_entry(priv
, bus_mac
);
1875 if (entry
== NULL
) {
1876 lec_arp_unlock(priv
);
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
);
1887 } else if (ioc_data
->receive
== 1) {
1888 /* Vcc which we don't want to make default vcc, attach it
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
);
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
,
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);
1936 del_timer(&entry
->timer
);
1938 entry
->old_push
= old_push
;
1939 if (entry
->status
== ESI_VC_PENDING
) {
1940 if(priv
->maximum_unknown_frame_count
1945 entry
->timestamp
= jiffies
;
1949 send_to_lecd(priv
,l_flush_xmt
,
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... */
1971 lec_arp_unlock(priv
);
1972 DPRINTK("After vcc was added\n");
1973 dump_arp_table(priv
);
1976 /* Not found, snatch address from first data packet that arrives from
1978 entry
= make_entry(priv
, bus_mac
);
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
);
1995 lec_flush_complete(struct lec_priv
*priv
, unsigned long tran_id
)
1997 struct lec_arp_table
*entry
;
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
);
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
;
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
);
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
;
2036 to_add
= make_entry(priv
, mac_addr
);
2038 lec_arp_unlock(priv
);
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
;
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
);
2054 lec_vcc_close(struct lec_priv
*priv
, struct atm_vcc
*vcc
)
2056 struct lec_arp_table
*entry
, *next
;
2059 DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n",vcc
->vpi
,vcc
->vci
);
2060 dump_arp_table(priv
);
2062 for(i
=0;i
<LEC_ARP_TABLE_SIZE
;i
++) {
2063 for(entry
= priv
->lec_arp_tables
[i
];entry
; entry
=next
) {
2065 if (vcc
== entry
->vcc
) {
2066 lec_arp_remove(priv
->lec_arp_tables
,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
) {
2079 if (entry
->vcc
== vcc
) { /* leave it out from the list */
2080 lec_arp_clear_vccs(entry
);
2081 del_timer(&entry
->timer
);
2084 else { /* put it back to the list */
2085 entry
->next
= priv
->lec_arp_empty_ones
;
2086 priv
->lec_arp_empty_ones
= entry
;
2091 entry
= priv
->lec_no_forward
;
2092 priv
->lec_no_forward
= NULL
;
2093 while (entry
!= NULL
) {
2095 if (entry
->recv_vcc
== vcc
) {
2096 lec_arp_clear_vccs(entry
);
2097 del_timer(&entry
->timer
);
2101 entry
->next
= priv
->lec_no_forward
;
2102 priv
->lec_no_forward
= entry
;
2107 entry
= priv
->mcast_fwds
;
2108 priv
->mcast_fwds
= NULL
;
2109 while (entry
!= NULL
) {
2111 if (entry
->recv_vcc
== vcc
) {
2112 lec_arp_clear_vccs(entry
);
2113 /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
2117 entry
->next
= priv
->mcast_fwds
;
2118 priv
->mcast_fwds
= entry
;
2123 lec_arp_unlock(priv
);
2124 dump_arp_table(priv
);
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
;
2136 struct lecdatahdr_8025
*tr_hdr
= (struct lecdatahdr_8025
*)skb
->data
;
2138 if (priv
->is_trdev
) src
= tr_hdr
->h_source
;
2141 src
= hdr
->h_source
;
2144 entry
= priv
->lec_arp_empty_ones
;
2145 if (vcc
== entry
->vcc
) {
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
);
2159 lec_arp_put(priv
->lec_arp_tables
, entry
);
2160 lec_arp_unlock(priv
);
2164 entry
= entry
->next
;
2165 while (entry
&& entry
->vcc
!= vcc
) {
2167 entry
= entry
->next
;
2170 DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n");
2171 lec_arp_unlock(priv
);
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
);
2186 lec_arp_put(priv
->lec_arp_tables
,entry
);
2187 lec_arp_unlock(priv
);