Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[safe/jmp/linux-2.6] / drivers / net / r8169.c
index 616ae5a..9674005 100644 (file)
@@ -186,7 +186,12 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = {
 
 MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
 
-static int rx_copybreak = 200;
+/*
+ * we set our copybreak very high so that we don't have
+ * to allocate 16k frames all the time (see note in
+ * rtl8169_open()
+ */
+static int rx_copybreak = 16383;
 static int use_dac;
 static struct {
        u32 msg_enable;
@@ -2820,8 +2825,8 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
        spin_lock_irq(&tp->lock);
 
        RTL_W8(Cfg9346, Cfg9346_Unlock);
-       RTL_W32(MAC0, low);
        RTL_W32(MAC4, high);
+       RTL_W32(MAC0, low);
        RTL_W8(Cfg9346, Cfg9346_Lock);
 
        spin_unlock_irq(&tp->lock);
@@ -3217,9 +3222,13 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
 }
 
 static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
-                                 struct net_device *dev)
+                                 unsigned int mtu)
 {
-       unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
+       unsigned int max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
+
+       if (max_frame != 16383)
+               printk(KERN_WARNING "WARNING! Changing of MTU on this NIC"
+                       "May lead to frame reception errors!\n");
 
        tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
 }
@@ -3231,7 +3240,17 @@ static int rtl8169_open(struct net_device *dev)
        int retval = -ENOMEM;
 
 
-       rtl8169_set_rxbufsize(tp, dev);
+       /*
+        * Note that we use a magic value here, its wierd I know
+        * its done because, some subset of rtl8169 hardware suffers from
+        * a problem in which frames received that are longer than
+        * the size set in RxMaxSize register return garbage sizes
+        * when received.  To avoid this we need to turn off filtering,
+        * which is done by setting a value of 16383 in the RxMaxSize register
+        * and allocating 16k frames to handle the largest possible rx value
+        * thats what the magic math below does.
+        */
+       rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN);
 
        /*
         * Rx and Tx desscriptors needs 256 bytes alignment.
@@ -3884,7 +3903,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
 
        rtl8169_down(dev);
 
-       rtl8169_set_rxbufsize(tp, dev);
+       rtl8169_set_rxbufsize(tp, dev->mtu);
 
        ret = rtl8169_init_ring(dev);
        if (ret < 0)
@@ -4263,7 +4282,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
 
        tp->cur_tx += frags + 1;
 
-       smp_wmb();
+       wmb();
 
        RTL_W8(TxPoll, NPQ);    /* set polling bit */
 
@@ -4614,7 +4633,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
                 * until it does.
                 */
                tp->intr_mask = 0xffff;
-               smp_wmb();
+               wmb();
                RTL_W16(IntrMask, tp->intr_event);
        }
 
@@ -4725,12 +4744,10 @@ static void rtl_set_rx_mode(struct net_device *dev)
                mc_filter[1] = mc_filter[0] = 0xffffffff;
        } else {
                struct dev_mc_list *mclist;
-               unsigned int i;
 
                rx_mode = AcceptBroadcast | AcceptMyPhys;
                mc_filter[1] = mc_filter[0] = 0;
-               for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev);
-                    i++, mclist = mclist->next) {
+               netdev_for_each_mc_addr(mclist, dev) {
                        int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
                        mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
                        rx_mode |= AcceptMulticast;
@@ -4749,8 +4766,8 @@ static void rtl_set_rx_mode(struct net_device *dev)
                mc_filter[1] = swab32(data);
        }
 
-       RTL_W32(MAR0 + 0, mc_filter[0]);
        RTL_W32(MAR0 + 4, mc_filter[1]);
+       RTL_W32(MAR0 + 0, mc_filter[0]);
 
        RTL_W32(RxConfig, tmp);