Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: vpeirq() optimization and cleanup



HI

> and I get a promiscuous message everytime I get this line :
> 1.2.3.4 > ALL-ROUTERS.MCAST.NET: igmp leave 224.79.81.1 (DF) [ttl 1]
> 
> I can't change my client to tell not to go into promiscuous mode, it's 
> not open source. Also, I don't have this message when I use the 
> pentamedia card. Could something come up your mind after these details ?

Here's a patch that will prevent changing of the modes
(and restarting of the net feed) unless actual contents
is changed. 

So repeatable use of e.g. set promisc mode will set it
only once and the rest will be NOP'ed

Emard
diff -pur orig/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c
--- orig/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c	Mon Feb  3 09:56:09 2003
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c	Fri Feb 21 23:15:01 2003
@@ -280,48 +280,63 @@ dvb_net_feed_stop(struct net_device *dev
 }
 
 static int
-dvb_set_mc_filter(struct net_device *dev, struct dev_mc_list *mc)
+dvb_add_mc_filter(struct net_device *dev, struct dev_mc_list *mc)
 {
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+	int ret;
 
-	if (priv->multi_num==DVB_NET_MULTICAST_MAX)
+	if (priv->multi_num >= DVB_NET_MULTICAST_MAX)
 		return -ENOMEM;
 
+	ret = memcmp(priv->multi_macs[priv->multi_num], mc->dmi_addr, 6);
 	memcpy(priv->multi_macs[priv->multi_num], mc->dmi_addr, 6);
-	
+
 	priv->multi_num++;
-	return 0;
+
+	return ret;
 }
 
 static void
 dvb_net_set_multi(struct net_device *dev)
 {
-	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+    struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+    struct dev_mc_list *mc;
+    int mci;
+    int update = 0;
+
+    if(dev->flags & IFF_PROMISC) {
+//	printk("%s: promiscuous mode\n", dev->name);
+	if(priv->mode != 3)
+	    update = 1;
+	priv->mode = 3;
+    } else if(dev->flags & IFF_ALLMULTI) {
+//	printk("%s: allmulti mode\n", dev->name);
+	if(priv->mode != 2)
+	    update = 1;
+	priv->mode = 2;
+    } else if(dev->mc_count > 0) {
+//	printk("%s: set_mc_list, %d entries\n", 
+//	       dev->name, dev->mc_count);
+	if(priv->mode != 1)
+	    update = 1;
+	priv->mode = 1;
+	priv->multi_num = 0;
+	for (mci = 0, mc=dev->mc_list; 
+	     mci < dev->mc_count;
+	     mc=mc->next, mci++)
+	    if(dvb_add_mc_filter(dev, mc) != 0)
+		update = 1;
+    } else {
+	if(priv->mode != 0)
+	    update = 1;
+	priv->mode = 0;
+    }
 
+    if(netif_running(dev) != 0 && update > 0)
+    {
 	dvb_net_feed_stop(dev);
-
-	priv->mode=0;
-	if (dev->flags&IFF_PROMISC) {
-		printk("%s: promiscuous mode\n", dev->name);
-		priv->mode=3;
-	} else if((dev->flags&IFF_ALLMULTI)) {
-		printk("%s: allmulti mode\n", dev->name);
-		priv->mode=2;
-	} else if(dev->mc_count) {
-                int mci;
-                struct dev_mc_list *mc;
-		
-		printk("%s: set_mc_list, %d entries\n", 
-		       dev->name, dev->mc_count);
-		priv->mode=1;
-		priv->multi_num=0;
-                for (mci=0, mc=dev->mc_list; 
-		     mci<dev->mc_count;
-		     mc=mc->next, mci++) {
-			dvb_set_mc_filter(dev, mc);
-                } 
-	}
 	dvb_net_feed_start(dev);
+    }
 }
 
 static int
@@ -336,9 +351,11 @@ static int
 dvb_net_set_mac(struct net_device *dev, void *p)
 {
 	struct sockaddr *addr=p;
+	int update;
 
+	update = memcmp(dev->dev_addr, addr->sa_data, dev->addr_len);
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-	if (netif_running(dev)) {
+	if (netif_running(dev) != 0 && update > 0) {
 	        dvb_net_feed_stop(dev);
 		dvb_net_feed_start(dev);
 	}
Only in dvb-kernel/linux/drivers/media/dvb/dvb-core: dvb_net.c~

Home | Main Index | Thread Index