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