patch-2.3.43 linux/net/atm/lec.c
Next file: linux/net/atm/mpc.c
Previous file: linux/net/atm/common.c
Back to the patch index
Back to the overall index
- Lines: 233
- Date:
Tue Feb 8 18:23:13 2000
- Orig file:
v2.3.42/linux/net/atm/lec.c
- Orig date:
Fri Sep 10 23:57:38 1999
diff -u --recursive --new-file v2.3.42/linux/net/atm/lec.c linux/net/atm/lec.c
@@ -39,7 +39,6 @@
#include "lec.h"
#include "lec_arpc.h"
-#include "tunable.h"
#include "resources.h" /* for bind_vcc() */
#if 0
@@ -60,7 +59,7 @@
static int lec_send_packet(struct sk_buff *skb, struct net_device *dev);
static int lec_close(struct net_device *dev);
static struct net_device_stats *lec_get_stats(struct net_device *dev);
-static int lec_init(struct net_device *dev);
+static void lec_init(struct net_device *dev);
static __inline__ struct lec_arp_table* lec_arp_find(struct lec_priv *priv,
unsigned char *mac_addr);
static __inline__ int lec_arp_remove(struct lec_arp_table **lec_arp_tables,
@@ -79,9 +78,6 @@
NULL /* associate indicator, spec 3.1.5 */
};
-/* will be lec0, lec1, lec2 etc. */
-static char myname[] = "lecxx";
-
static unsigned char bus_mac[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
/* Device structures */
@@ -262,6 +258,17 @@
lec_h = (struct lecdatahdr_8023*)skb->data;
lec_h->le_header = htons(priv->lecid);
+#ifdef CONFIG_TR
+ /* Ugly. Use this to realign Token Ring packets for
+ * e.g. PCA-200E driver. */
+ if (priv->is_trdev) {
+ skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
+ kfree_skb(skb);
+ if (skb2 == NULL) return 0;
+ skb = skb2;
+ }
+#endif
+
#if DUMP_PACKETS > 0
printk("%s: send datalen:%ld lecid:%4.4x\n", dev->name,
skb->len, priv->lecid);
@@ -466,6 +473,7 @@
if (dev->change_mtu(dev, mesg->content.config.mtu))
printk("%s: change_mtu to %d failed\n", dev->name,
mesg->content.config.mtu);
+ priv->is_proxy = mesg->content.config.is_proxy;
break;
case l_flush_tran_id:
lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr,
@@ -540,24 +548,8 @@
}
static struct atmdev_ops lecdev_ops = {
- NULL, /*dev_close*/
- NULL, /*open*/
- lec_atm_close, /*close*/
- NULL, /*ioctl*/
- NULL, /*getsockopt */
- NULL, /*setsockopt */
- lec_atm_send, /*send */
- NULL, /*sg_send */
-#if 0 /* these are disabled in <linux/atmdev.h> too */
- NULL, /*poll */
- NULL, /*send_iovec*/
-#endif
- NULL, /*send_oam*/
- NULL, /*phy_put*/
- NULL, /*phy_get*/
- NULL, /*feedback*/
- NULL, /* change_qos*/
- NULL /* free_rx_skb*/
+ close: lec_atm_close,
+ send: lec_atm_send
};
static struct atm_dev lecatm_dev = {
@@ -626,17 +618,9 @@
return 0;
}
-static int
+static void
lec_init(struct net_device *dev)
{
- struct lec_priv *priv;
-
- priv = (struct lec_priv *)dev->priv;
- if (priv->is_trdev) {
-#ifdef CONFIG_TR
- init_trdev(dev, 0);
-#endif
- } else ether_setup(dev);
dev->change_mtu = lec_change_mtu;
dev->open = lec_open;
dev->stop = lec_close;
@@ -646,7 +630,7 @@
dev->set_multicast_list = NULL;
dev->do_ioctl = NULL;
printk("%s: Initialized!\n",dev->name);
- return 0;
+ return;
}
static unsigned char lec_ctrl_magic[] = {
@@ -660,7 +644,6 @@
{
struct net_device *dev = (struct net_device *)vcc->proto_data;
struct lec_priv *priv = (struct lec_priv *)dev->priv;
- struct lecdatahdr_8023 *hdr;
#if DUMP_PACKETS >0
int i=0;
@@ -696,9 +679,10 @@
skb_queue_tail(&vcc->recvq, skb);
wake_up(&vcc->sleep);
} else { /* Data frame, queue to protocol handlers */
+ unsigned char *dst;
+
atm_return(vcc,skb->truesize);
- hdr = (struct lecdatahdr_8023 *)skb->data;
- if (hdr->le_header == htons(priv->lecid) ||
+ if (*(uint16_t *)skb->data == htons(priv->lecid) ||
!priv->lecd) {
/* Probably looping back, or if lecd is missing,
lecd has gone down */
@@ -706,7 +690,19 @@
dev_kfree_skb(skb);
return;
}
- if (priv->lec_arp_empty_ones) { /* FILTER DATA!!!! */
+#ifdef CONFIG_TR
+ if (priv->is_trdev) dst = ((struct lecdatahdr_8025 *)skb->data)->h_dest;
+ else
+#endif
+ dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest;
+
+ if (!(dst[0]&0x01) && /* Never filter Multi/Broadcast */
+ !priv->is_proxy && /* Proxy wants all the packets */
+ memcmp(dst, dev->dev_addr, sizeof(dev->dev_addr))) {
+ dev_kfree_skb(skb);
+ return;
+ }
+ if (priv->lec_arp_empty_ones) {
lec_arp_check_empties(priv, vcc, skb);
}
skb->dev = dev;
@@ -757,7 +753,7 @@
int
lecd_attach(struct atm_vcc *vcc, int arg)
{
- int i, result;
+ int i;
struct lec_priv *priv;
if (arg<0)
@@ -772,30 +768,28 @@
return -EINVAL;
#endif
if (!dev_lec[i]) {
- dev_lec[i] = (struct net_device*)
- kmalloc(sizeof(struct net_device)+sizeof(myname)+1,
- GFP_KERNEL);
- if (!dev_lec[i])
- return -ENOMEM;
- memset(dev_lec[i],0,sizeof(struct net_device)+sizeof(myname)+1);
-
- dev_lec[i]->priv = kmalloc(sizeof(struct lec_priv), GFP_KERNEL);
- if (!dev_lec[i]->priv)
- return -ENOMEM;
- memset(dev_lec[i]->priv,0,sizeof(struct lec_priv));
- priv = (struct lec_priv *)dev_lec[i]->priv;
+ int is_trdev, size;
+ is_trdev = 0;
if (i >= (MAX_LEC_ITF - NUM_TR_DEVS))
- priv->is_trdev = 1;
+ is_trdev = 1;
- dev_lec[i]->name = (char*)(dev_lec[i]+1);
- sprintf(dev_lec[i]->name, "lec%d",i);
- dev_lec[i]->init = lec_init;
- if ((result = register_netdev(dev_lec[i])) !=0)
- return result;
- sprintf(dev_lec[i]->name, "lec%d", i); /* init_trdev globbers device name */
+ size = sizeof(struct lec_priv);
+#ifdef CONFIG_TR
+ if (is_trdev)
+ dev_lec[i] = init_trdev(NULL, size);
+ else
+#endif
+ dev_lec[i] = init_etherdev(NULL, size);
+ if (!dev_lec[i])
+ return -ENOMEM;
+
+ priv = dev_lec[i]->priv;
+ priv->is_trdev = is_trdev;
+ sprintf(dev_lec[i]->name, "lec%d", i);
+ lec_init(dev_lec[i]);
} else {
- priv = (struct lec_priv *)dev_lec[i]->priv;
+ priv = dev_lec[i]->priv;
if (priv->lecd)
return -EADDRINUSE;
}
@@ -874,7 +868,6 @@
#endif
} else
unregister_netdev(dev_lec[i]);
- kfree(dev_lec[i]->priv);
kfree(dev_lec[i]);
dev_lec[i] = NULL;
}
@@ -1535,7 +1528,7 @@
if (entry)
entry->next = to_remove->next;
}
- if (!entry)
+ if (!entry) {
if (to_remove == priv->lec_no_forward) {
priv->lec_no_forward = to_remove->next;
} else {
@@ -1545,6 +1538,7 @@
if (entry)
entry->next = to_remove->next;
}
+ }
lec_arp_clear_vccs(to_remove);
kfree(to_remove);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)