lec.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:79k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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