Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[safe/jmp/linux-2.6] / drivers / net / jme.c
index 558b6a0..b705ad3 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/if_vlan.h>
+#include <linux/slab.h>
 #include <net/ip6_checksum.h>
 #include "jme.h"
 
@@ -946,6 +947,8 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx)
                                jme->jme_vlan_rx(skb, jme->vlgrp,
                                        le16_to_cpu(rxdesc->descwb.vlan));
                                NET_STAT(jme).rx_bytes += 4;
+                       } else {
+                               dev_kfree_skb(skb);
                        }
                } else {
                        jme->jme_rx(skb);
@@ -1997,7 +2000,6 @@ jme_set_multi(struct net_device *netdev)
 {
        struct jme_adapter *jme = netdev_priv(netdev);
        u32 mc_hash[2] = {};
-       int i;
 
        spin_lock_bh(&jme->rxmcs_lock);
 
@@ -2012,10 +2014,7 @@ jme_set_multi(struct net_device *netdev)
                int bit_nr;
 
                jme->reg_rxmcs |= RXMCS_MULFRAME | RXMCS_MULFILTERED;
-               for (i = 0, mclist = netdev->mc_list;
-                       mclist && i < netdev_mc_count(netdev);
-                       ++i, mclist = mclist->next) {
-
+               netdev_for_each_mc_addr(mclist, netdev) {
                        bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3F;
                        mc_hash[bit_nr >> 5] |= 1 << (bit_nr & 0x1F);
                }
@@ -2085,12 +2084,45 @@ jme_tx_timeout(struct net_device *netdev)
        jme_reset_link(jme);
 }
 
+static inline void jme_pause_rx(struct jme_adapter *jme)
+{
+       atomic_dec(&jme->link_changing);
+
+       jme_set_rx_pcc(jme, PCC_OFF);
+       if (test_bit(JME_FLAG_POLL, &jme->flags)) {
+               JME_NAPI_DISABLE(jme);
+       } else {
+               tasklet_disable(&jme->rxclean_task);
+               tasklet_disable(&jme->rxempty_task);
+       }
+}
+
+static inline void jme_resume_rx(struct jme_adapter *jme)
+{
+       struct dynpcc_info *dpi = &(jme->dpi);
+
+       if (test_bit(JME_FLAG_POLL, &jme->flags)) {
+               JME_NAPI_ENABLE(jme);
+       } else {
+               tasklet_hi_enable(&jme->rxclean_task);
+               tasklet_hi_enable(&jme->rxempty_task);
+       }
+       dpi->cur                = PCC_P1;
+       dpi->attempt            = PCC_P1;
+       dpi->cnt                = 0;
+       jme_set_rx_pcc(jme, PCC_P1);
+
+       atomic_inc(&jme->link_changing);
+}
+
 static void
 jme_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
 {
        struct jme_adapter *jme = netdev_priv(netdev);
 
+       jme_pause_rx(jme);
        jme->vlgrp = grp;
+       jme_resume_rx(jme);
 }
 
 static void