OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [atm/] [lec.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.