浏览代码

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (56 commits)
  sky2: Fix oops in sky2_xmit_frame() after TX timeout
  Documentation/3c509: document ethtool support
  af_packet: Don't use skb after dev_queue_xmit()
  vxge: use pci_dma_mapping_error to test return value
  netfilter: ebtables: enforce CAP_NET_ADMIN
  e1000e: fix and commonize code for setting the receive address registers
  e1000e: e1000e_enable_tx_pkt_filtering() returns wrong value
  e1000e: perform 10/100 adaptive IFS only on parts that support it
  e1000e: don't accumulate PHY statistics on PHY read failure
  e1000e: call pci_save_state() after pci_restore_state()
  netxen: update version to 4.0.72
  netxen: fix set mac addr
  netxen: fix smatch warning
  netxen: fix tx ring memory leak
  tcp: update the netstamp_needed counter when cloning sockets
  TI DaVinci EMAC: Handle emac module clock correctly.
  dmfe/tulip: Let dmfe handle DM910x except for SPARC on-board chips
  ixgbe: Fix compiler warning about variable being used uninitialized
  netfilter: nf_ct_ftp: fix out of bounds read in update_nl_seq()
  mv643xx_eth: don't include cache padding in rx desc buffer size
  ...

Fix trivial conflict in drivers/scsi/cxgb3i/cxgb3i_offload.c
Linus Torvalds 16 年之前
父节点
当前提交
597d8c7178
共有 59 个文件被更改,包括 526 次插入313 次删除
  1. 8 4
      Documentation/networking/3c509.txt
  2. 1 1
      drivers/isdn/hardware/mISDN/hfcmulti.c
  3. 1 1
      drivers/net/atarilance.c
  4. 5 2
      drivers/net/atlx/atl2.c
  5. 1 1
      drivers/net/can/mcp251x.c
  6. 1 2
      drivers/net/cs89x0.c
  7. 3 1
      drivers/net/davinci_emac.c
  8. 2 0
      drivers/net/e1000e/82571.c
  9. 2 0
      drivers/net/e1000e/es2lan.c
  10. 1 0
      drivers/net/e1000e/hw.h
  11. 2 0
      drivers/net/e1000e/ich8lan.c
  12. 38 16
      drivers/net/e1000e/lib.c
  13. 16 14
      drivers/net/e1000e/netdev.c
  14. 23 7
      drivers/net/fsl_pq_mdio.c
  15. 3 1
      drivers/net/hamradio/bpqether.c
  16. 7 2
      drivers/net/ixgbe/ixgbe_main.c
  17. 1 1
      drivers/net/ll_temac_main.c
  18. 4 2
      drivers/net/mv643xx_eth.c
  19. 2 2
      drivers/net/netxen/netxen_nic.h
  20. 67 126
      drivers/net/netxen/netxen_nic_ethtool.c
  21. 4 2
      drivers/net/netxen/netxen_nic_hw.c
  22. 3 1
      drivers/net/netxen/netxen_nic_init.c
  23. 3 7
      drivers/net/netxen/netxen_nic_main.c
  24. 1 1
      drivers/net/niu.c
  25. 0 1
      drivers/net/pcmcia/nmclan_cs.c
  26. 2 2
      drivers/net/pcmcia/pcnet_cs.c
  27. 2 2
      drivers/net/phy/broadcom.c
  28. 64 8
      drivers/net/phy/mdio_bus.c
  29. 15 15
      drivers/net/phy/phy_device.c
  30. 1 1
      drivers/net/rrunner.c
  31. 1 1
      drivers/net/sh_eth.c
  32. 2 1
      drivers/net/sky2.c
  33. 4 0
      drivers/net/tulip/Kconfig
  34. 21 0
      drivers/net/tulip/dmfe.c
  35. 25 7
      drivers/net/tulip/tulip_core.c
  36. 2 1
      drivers/net/ucc_geth.c
  37. 7 6
      drivers/net/ucc_geth.h
  38. 77 28
      drivers/net/usb/hso.c
  39. 2 2
      drivers/net/usb/rtl8150.c
  40. 4 4
      drivers/net/via-velocity.c
  41. 1 1
      drivers/net/vxge/vxge-main.c
  42. 1 1
      drivers/s390/net/claw.c
  43. 14 1
      drivers/serial/serial_cs.c
  44. 2 1
      firmware/Makefile
  45. 1 0
      firmware/WHENCE
  46. 9 0
      firmware/cis/PE520.cis.ihex
  47. 1 0
      include/linux/phy.h
  48. 16 0
      include/net/ip.h
  49. 6 0
      net/bridge/netfilter/ebtables.c
  50. 4 0
      net/core/sock.c
  51. 1 1
      net/ipv4/ip_output.c
  52. 1 2
      net/ipv6/ip6_output.c
  53. 2 1
      net/netfilter/ipvs/Kconfig
  54. 13 1
      net/netfilter/ipvs/ip_vs_ctl.c
  55. 1 14
      net/netfilter/ipvs/ip_vs_wrr.c
  56. 9 9
      net/netfilter/nf_conntrack_ftp.c
  57. 14 5
      net/packet/af_packet.c
  58. 1 1
      net/rose/rose_loopback.c
  59. 1 2
      net/sctp/socket.c

+ 8 - 4
Documentation/networking/3c509.txt

@@ -48,11 +48,11 @@ for LILO parameters for doing this:
 This configures the first found 3c509 card for IRQ 10, base I/O 0x310, and
 This configures the first found 3c509 card for IRQ 10, base I/O 0x310, and
 transceiver type 3 (10base2). The flag "0x3c509" must be set to avoid conflicts
 transceiver type 3 (10base2). The flag "0x3c509" must be set to avoid conflicts
 with other card types when overriding the I/O address. When the driver is
 with other card types when overriding the I/O address. When the driver is
-loaded as a module, only the IRQ and transceiver setting may be overridden.
-For example, setting two cards to 10base2/IRQ10 and AUI/IRQ11 is done by using
-the xcvr and irq module options:
+loaded as a module, only the IRQ may be overridden. For example,
+setting two cards to IRQ10 and IRQ11 is done by using the irq module
+option:
 
 
-   options 3c509 xcvr=3,1 irq=10,11
+   options 3c509 irq=10,11
 
 
 
 
 (2) Full-duplex mode
 (2) Full-duplex mode
@@ -77,6 +77,8 @@ operation.
 itself full-duplex capable. This is almost certainly one of two things: a full-
 itself full-duplex capable. This is almost certainly one of two things: a full-
 duplex-capable  Ethernet switch (*not* a hub), or a full-duplex-capable NIC on
 duplex-capable  Ethernet switch (*not* a hub), or a full-duplex-capable NIC on
 another system that's connected directly to the 3c509B via a crossover cable.
 another system that's connected directly to the 3c509B via a crossover cable.
+
+Full-duplex mode can be enabled using 'ethtool'.
  
  
 /////Extremely important caution concerning full-duplex mode/////
 /////Extremely important caution concerning full-duplex mode/////
 Understand that the 3c509B's hardware's full-duplex support is much more
 Understand that the 3c509B's hardware's full-duplex support is much more
@@ -113,6 +115,8 @@ This insured that merely upgrading the driver from an earlier version would
 never automatically enable full-duplex mode in an existing installation;
 never automatically enable full-duplex mode in an existing installation;
 it must always be explicitly enabled via one of these code in order to be
 it must always be explicitly enabled via one of these code in order to be
 activated.
 activated.
+
+The transceiver type can be changed using 'ethtool'.
   
   
 
 
 (4a) Interpretation of error messages and common problems
 (4a) Interpretation of error messages and common problems

+ 1 - 1
drivers/isdn/hardware/mISDN/hfcmulti.c

@@ -3152,7 +3152,7 @@ static void
 hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx,
 hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx,
     int slot_rx, int bank_rx)
     int slot_rx, int bank_rx)
 {
 {
-	if (slot_rx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) {
+	if (slot_tx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) {
 		/* disable PCM */
 		/* disable PCM */
 		mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0);
 		mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0);
 		return;
 		return;

+ 1 - 1
drivers/net/atarilance.c

@@ -663,7 +663,7 @@ static int lance_open( struct net_device *dev )
 	while (--i > 0)
 	while (--i > 0)
 		if (DREG & CSR0_IDON)
 		if (DREG & CSR0_IDON)
 			break;
 			break;
-	if (i < 0 || (DREG & CSR0_ERR)) {
+	if (i <= 0 || (DREG & CSR0_ERR)) {
 		DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
 		DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
 					  dev->name, i, DREG ));
 					  dev->name, i, DREG ));
 		DREG = CSR0_STOP;
 		DREG = CSR0_STOP;

+ 5 - 2
drivers/net/atlx/atl2.c

@@ -1959,12 +1959,15 @@ static int atl2_get_eeprom(struct net_device *netdev,
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	for (i = first_dword; i < last_dword; i++) {
 	for (i = first_dword; i < last_dword; i++) {
-		if (!atl2_read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword])))
-			return -EIO;
+		if (!atl2_read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword]))) {
+			ret_val = -EIO;
+			goto free;
+		}
 	}
 	}
 
 
 	memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
 	memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
 		eeprom->len);
 		eeprom->len);
+free:
 	kfree(eeprom_buff);
 	kfree(eeprom_buff);
 
 
 	return ret_val;
 	return ret_val;

+ 1 - 1
drivers/net/can/mcp251x.c

@@ -990,7 +990,7 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi)
 			goto error_tx_buf;
 			goto error_tx_buf;
 		}
 		}
 		priv->spi_rx_buf = kmalloc(SPI_TRANSFER_BUF_LEN, GFP_KERNEL);
 		priv->spi_rx_buf = kmalloc(SPI_TRANSFER_BUF_LEN, GFP_KERNEL);
-		if (!priv->spi_tx_buf) {
+		if (!priv->spi_rx_buf) {
 			ret = -ENOMEM;
 			ret = -ENOMEM;
 			goto error_rx_buf;
 			goto error_rx_buf;
 		}
 		}

+ 1 - 2
drivers/net/cs89x0.c

@@ -1325,8 +1325,7 @@ net_open(struct net_device *dev)
 		write_irq(dev, lp->chip_type, dev->irq);
 		write_irq(dev, lp->chip_type, dev->irq);
 		ret = request_irq(dev->irq, net_interrupt, 0, dev->name, dev);
 		ret = request_irq(dev->irq, net_interrupt, 0, dev->name, dev);
 		if (ret) {
 		if (ret) {
-			if (net_debug)
-				printk(KERN_DEBUG "cs89x0: request_irq(%d) failed\n", dev->irq);
+			printk(KERN_ERR "cs89x0: request_irq(%d) failed\n", dev->irq);
 			goto bad_out;
 			goto bad_out;
 		}
 		}
 	}
 	}

+ 3 - 1
drivers/net/davinci_emac.c

@@ -2711,6 +2711,8 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
 	SET_ETHTOOL_OPS(ndev, &ethtool_ops);
 	SET_ETHTOOL_OPS(ndev, &ethtool_ops);
 	netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT);
 	netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT);
 
 
+	clk_enable(emac_clk);
+
 	/* register the network device */
 	/* register the network device */
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	rc = register_netdev(ndev);
 	rc = register_netdev(ndev);
@@ -2720,7 +2722,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
 		goto netdev_reg_err;
 		goto netdev_reg_err;
 	}
 	}
 
 
-	clk_enable(emac_clk);
 
 
 	/* MII/Phy intialisation, mdio bus registration */
 	/* MII/Phy intialisation, mdio bus registration */
 	emac_mii = mdiobus_alloc();
 	emac_mii = mdiobus_alloc();
@@ -2760,6 +2761,7 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
 
 
 netdev_reg_err:
 netdev_reg_err:
 mdio_alloc_err:
 mdio_alloc_err:
+	clk_disable(emac_clk);
 no_irq_res:
 no_irq_res:
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(res->start, res->end - res->start + 1);
 	release_mem_region(res->start, res->end - res->start + 1);

+ 2 - 0
drivers/net/e1000e/82571.c

@@ -237,6 +237,8 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
 	/* Set if manageability features are enabled. */
 	/* Set if manageability features are enabled. */
 	mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK)
 	mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK)
 	                ? true : false;
 	                ? true : false;
+	/* Adaptive IFS supported */
+	mac->adaptive_ifs = true;
 
 
 	/* check for link */
 	/* check for link */
 	switch (hw->phy.media_type) {
 	switch (hw->phy.media_type) {

+ 2 - 0
drivers/net/e1000e/es2lan.c

@@ -224,6 +224,8 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter)
 	/* Set if manageability features are enabled. */
 	/* Set if manageability features are enabled. */
 	mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK)
 	mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK)
                         ? true : false;
                         ? true : false;
+	/* Adaptive IFS not supported */
+	mac->adaptive_ifs = false;
 
 
 	/* check for link */
 	/* check for link */
 	switch (hw->phy.media_type) {
 	switch (hw->phy.media_type) {

+ 1 - 0
drivers/net/e1000e/hw.h

@@ -818,6 +818,7 @@ struct e1000_mac_info {
 
 
 	u8  forced_speed_duplex;
 	u8  forced_speed_duplex;
 
 
+	bool adaptive_ifs;
 	bool arc_subsystem_valid;
 	bool arc_subsystem_valid;
 	bool autoneg;
 	bool autoneg;
 	bool autoneg_failed;
 	bool autoneg_failed;

+ 2 - 0
drivers/net/e1000e/ich8lan.c

@@ -454,6 +454,8 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
 		mac->rar_entry_count--;
 		mac->rar_entry_count--;
 	/* Set if manageability features are enabled. */
 	/* Set if manageability features are enabled. */
 	mac->arc_subsystem_valid = true;
 	mac->arc_subsystem_valid = true;
+	/* Adaptive IFS supported */
+	mac->adaptive_ifs = true;
 
 
 	/* LED operations */
 	/* LED operations */
 	switch (mac->type) {
 	switch (mac->type) {

+ 38 - 16
drivers/net/e1000e/lib.c

@@ -125,6 +125,7 @@ void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
 void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
 void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
 {
 {
 	u32 i;
 	u32 i;
+	u8 mac_addr[ETH_ALEN] = {0};
 
 
 	/* Setup the receive address */
 	/* Setup the receive address */
 	e_dbg("Programming MAC Address into RAR[0]\n");
 	e_dbg("Programming MAC Address into RAR[0]\n");
@@ -133,12 +134,8 @@ void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
 
 
 	/* Zero out the other (rar_entry_count - 1) receive addresses */
 	/* Zero out the other (rar_entry_count - 1) receive addresses */
 	e_dbg("Clearing RAR[1-%u]\n", rar_count-1);
 	e_dbg("Clearing RAR[1-%u]\n", rar_count-1);
-	for (i = 1; i < rar_count; i++) {
-		E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1), 0);
-		e1e_flush();
-		E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((i << 1) + 1), 0);
-		e1e_flush();
-	}
+	for (i = 1; i < rar_count; i++)
+		e1000e_rar_set(hw, mac_addr, i);
 }
 }
 
 
 /**
 /**
@@ -164,10 +161,19 @@ void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
 
 
 	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
 	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
 
 
-	rar_high |= E1000_RAH_AV;
+	/* If MAC address zero, no need to set the AV bit */
+	if (rar_low || rar_high)
+		rar_high |= E1000_RAH_AV;
 
 
-	E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low);
-	E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high);
+	/*
+	 * Some bridges will combine consecutive 32-bit writes into
+	 * a single burst write, which will malfunction on some parts.
+	 * The flushes avoid this.
+	 */
+	ew32(RAL(index), rar_low);
+	e1e_flush();
+	ew32(RAH(index), rar_high);
+	e1e_flush();
 }
 }
 
 
 /**
 /**
@@ -1609,6 +1615,11 @@ void e1000e_reset_adaptive(struct e1000_hw *hw)
 {
 {
 	struct e1000_mac_info *mac = &hw->mac;
 	struct e1000_mac_info *mac = &hw->mac;
 
 
+	if (!mac->adaptive_ifs) {
+		e_dbg("Not in Adaptive IFS mode!\n");
+		goto out;
+	}
+
 	mac->current_ifs_val = 0;
 	mac->current_ifs_val = 0;
 	mac->ifs_min_val = IFS_MIN;
 	mac->ifs_min_val = IFS_MIN;
 	mac->ifs_max_val = IFS_MAX;
 	mac->ifs_max_val = IFS_MAX;
@@ -1617,6 +1628,8 @@ void e1000e_reset_adaptive(struct e1000_hw *hw)
 
 
 	mac->in_ifs_mode = false;
 	mac->in_ifs_mode = false;
 	ew32(AIT, 0);
 	ew32(AIT, 0);
+out:
+	return;
 }
 }
 
 
 /**
 /**
@@ -1630,6 +1643,11 @@ void e1000e_update_adaptive(struct e1000_hw *hw)
 {
 {
 	struct e1000_mac_info *mac = &hw->mac;
 	struct e1000_mac_info *mac = &hw->mac;
 
 
+	if (!mac->adaptive_ifs) {
+		e_dbg("Not in Adaptive IFS mode!\n");
+		goto out;
+	}
+
 	if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
 	if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
 		if (mac->tx_packet_delta > MIN_NUM_XMITS) {
 		if (mac->tx_packet_delta > MIN_NUM_XMITS) {
 			mac->in_ifs_mode = true;
 			mac->in_ifs_mode = true;
@@ -1650,6 +1668,8 @@ void e1000e_update_adaptive(struct e1000_hw *hw)
 			ew32(AIT, 0);
 			ew32(AIT, 0);
 		}
 		}
 	}
 	}
+out:
+	return;
 }
 }
 
 
 /**
 /**
@@ -2287,10 +2307,12 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
 	s32 ret_val, hdr_csum, csum;
 	s32 ret_val, hdr_csum, csum;
 	u8 i, len;
 	u8 i, len;
 
 
+	hw->mac.tx_pkt_filtering = true;
+
 	/* No manageability, no filtering */
 	/* No manageability, no filtering */
 	if (!e1000e_check_mng_mode(hw)) {
 	if (!e1000e_check_mng_mode(hw)) {
 		hw->mac.tx_pkt_filtering = false;
 		hw->mac.tx_pkt_filtering = false;
-		return 0;
+		goto out;
 	}
 	}
 
 
 	/*
 	/*
@@ -2298,9 +2320,9 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
 	 * reason, disable filtering.
 	 * reason, disable filtering.
 	 */
 	 */
 	ret_val = e1000_mng_enable_host_if(hw);
 	ret_val = e1000_mng_enable_host_if(hw);
-	if (ret_val != 0) {
+	if (ret_val) {
 		hw->mac.tx_pkt_filtering = false;
 		hw->mac.tx_pkt_filtering = false;
-		return ret_val;
+		goto out;
 	}
 	}
 
 
 	/* Read in the header.  Length and offset are in dwords. */
 	/* Read in the header.  Length and offset are in dwords. */
@@ -2319,17 +2341,17 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
 	 */
 	 */
 	if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
 	if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
 		hw->mac.tx_pkt_filtering = true;
 		hw->mac.tx_pkt_filtering = true;
-		return 1;
+		goto out;
 	}
 	}
 
 
 	/* Cookie area is valid, make the final check for filtering. */
 	/* Cookie area is valid, make the final check for filtering. */
 	if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) {
 	if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) {
 		hw->mac.tx_pkt_filtering = false;
 		hw->mac.tx_pkt_filtering = false;
-		return 0;
+		goto out;
 	}
 	}
 
 
-	hw->mac.tx_pkt_filtering = true;
-	return 1;
+out:
+	return hw->mac.tx_pkt_filtering;
 }
 }
 
 
 /**
 /**

+ 16 - 14
drivers/net/e1000e/netdev.c

@@ -3315,24 +3315,24 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 	if ((hw->phy.type == e1000_phy_82578) ||
 	if ((hw->phy.type == e1000_phy_82578) ||
 	    (hw->phy.type == e1000_phy_82577)) {
 	    (hw->phy.type == e1000_phy_82577)) {
 		e1e_rphy(hw, HV_SCC_UPPER, &phy_data);
 		e1e_rphy(hw, HV_SCC_UPPER, &phy_data);
-		e1e_rphy(hw, HV_SCC_LOWER, &phy_data);
-		adapter->stats.scc += phy_data;
+		if (!e1e_rphy(hw, HV_SCC_LOWER, &phy_data))
+			adapter->stats.scc += phy_data;
 
 
 		e1e_rphy(hw, HV_ECOL_UPPER, &phy_data);
 		e1e_rphy(hw, HV_ECOL_UPPER, &phy_data);
-		e1e_rphy(hw, HV_ECOL_LOWER, &phy_data);
-		adapter->stats.ecol += phy_data;
+		if (!e1e_rphy(hw, HV_ECOL_LOWER, &phy_data))
+			adapter->stats.ecol += phy_data;
 
 
 		e1e_rphy(hw, HV_MCC_UPPER, &phy_data);
 		e1e_rphy(hw, HV_MCC_UPPER, &phy_data);
-		e1e_rphy(hw, HV_MCC_LOWER, &phy_data);
-		adapter->stats.mcc += phy_data;
+		if (!e1e_rphy(hw, HV_MCC_LOWER, &phy_data))
+			adapter->stats.mcc += phy_data;
 
 
 		e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data);
 		e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data);
-		e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data);
-		adapter->stats.latecol += phy_data;
+		if (!e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data))
+			adapter->stats.latecol += phy_data;
 
 
 		e1e_rphy(hw, HV_DC_UPPER, &phy_data);
 		e1e_rphy(hw, HV_DC_UPPER, &phy_data);
-		e1e_rphy(hw, HV_DC_LOWER, &phy_data);
-		adapter->stats.dc += phy_data;
+		if (!e1e_rphy(hw, HV_DC_LOWER, &phy_data))
+			adapter->stats.dc += phy_data;
 	} else {
 	} else {
 		adapter->stats.scc += er32(SCC);
 		adapter->stats.scc += er32(SCC);
 		adapter->stats.ecol += er32(ECOL);
 		adapter->stats.ecol += er32(ECOL);
@@ -3360,8 +3360,8 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 	if ((hw->phy.type == e1000_phy_82578) ||
 	if ((hw->phy.type == e1000_phy_82578) ||
 	    (hw->phy.type == e1000_phy_82577)) {
 	    (hw->phy.type == e1000_phy_82577)) {
 		e1e_rphy(hw, HV_COLC_UPPER, &phy_data);
 		e1e_rphy(hw, HV_COLC_UPPER, &phy_data);
-		e1e_rphy(hw, HV_COLC_LOWER, &phy_data);
-		hw->mac.collision_delta = phy_data;
+		if (!e1e_rphy(hw, HV_COLC_LOWER, &phy_data))
+			hw->mac.collision_delta = phy_data;
 	} else {
 	} else {
 		hw->mac.collision_delta = er32(COLC);
 		hw->mac.collision_delta = er32(COLC);
 	}
 	}
@@ -3372,8 +3372,8 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 	if ((hw->phy.type == e1000_phy_82578) ||
 	if ((hw->phy.type == e1000_phy_82578) ||
 	    (hw->phy.type == e1000_phy_82577)) {
 	    (hw->phy.type == e1000_phy_82577)) {
 		e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data);
 		e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data);
-		e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data);
-		adapter->stats.tncrs += phy_data;
+		if (!e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data))
+			adapter->stats.tncrs += phy_data;
 	} else {
 	} else {
 		if ((hw->mac.type != e1000_82574) &&
 		if ((hw->mac.type != e1000_82574) &&
 		    (hw->mac.type != e1000_82583))
 		    (hw->mac.type != e1000_82583))
@@ -4674,6 +4674,7 @@ static int e1000_resume(struct pci_dev *pdev)
 
 
 	pci_set_power_state(pdev, PCI_D0);
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 	pci_restore_state(pdev);
+	pci_save_state(pdev);
 	e1000e_disable_l1aspm(pdev);
 	e1000e_disable_l1aspm(pdev);
 
 
 	err = pci_enable_device_mem(pdev);
 	err = pci_enable_device_mem(pdev);
@@ -4825,6 +4826,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
 	} else {
 	} else {
 		pci_set_master(pdev);
 		pci_set_master(pdev);
 		pci_restore_state(pdev);
 		pci_restore_state(pdev);
+		pci_save_state(pdev);
 
 
 		pci_enable_wake(pdev, PCI_D3hot, 0);
 		pci_enable_wake(pdev, PCI_D3hot, 0);
 		pci_enable_wake(pdev, PCI_D3cold, 0);
 		pci_enable_wake(pdev, PCI_D3cold, 0);

+ 23 - 7
drivers/net/fsl_pq_mdio.c

@@ -46,6 +46,11 @@
 #include "gianfar.h"
 #include "gianfar.h"
 #include "fsl_pq_mdio.h"
 #include "fsl_pq_mdio.h"
 
 
+struct fsl_pq_mdio_priv {
+	void __iomem *map;
+	struct fsl_pq_mdio __iomem *regs;
+};
+
 /*
 /*
  * Write value to the PHY at mii_id at register regnum,
  * Write value to the PHY at mii_id at register regnum,
  * on the bus attached to the local interface, which may be different from the
  * on the bus attached to the local interface, which may be different from the
@@ -105,7 +110,9 @@ int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs,
 
 
 static struct fsl_pq_mdio __iomem *fsl_pq_mdio_get_regs(struct mii_bus *bus)
 static struct fsl_pq_mdio __iomem *fsl_pq_mdio_get_regs(struct mii_bus *bus)
 {
 {
-	return (void __iomem __force *)bus->priv;
+	struct fsl_pq_mdio_priv *priv = bus->priv;
+
+	return priv->regs;
 }
 }
 
 
 /*
 /*
@@ -266,6 +273,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
 {
 {
 	struct device_node *np = ofdev->node;
 	struct device_node *np = ofdev->node;
 	struct device_node *tbi;
 	struct device_node *tbi;
+	struct fsl_pq_mdio_priv *priv;
 	struct fsl_pq_mdio __iomem *regs = NULL;
 	struct fsl_pq_mdio __iomem *regs = NULL;
 	void __iomem *map;
 	void __iomem *map;
 	u32 __iomem *tbipa;
 	u32 __iomem *tbipa;
@@ -274,14 +282,19 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
 	u64 addr = 0, size = 0;
 	u64 addr = 0, size = 0;
 	int err = 0;
 	int err = 0;
 
 
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
 	new_bus = mdiobus_alloc();
 	new_bus = mdiobus_alloc();
 	if (NULL == new_bus)
 	if (NULL == new_bus)
-		return -ENOMEM;
+		goto err_free_priv;
 
 
 	new_bus->name = "Freescale PowerQUICC MII Bus",
 	new_bus->name = "Freescale PowerQUICC MII Bus",
 	new_bus->read = &fsl_pq_mdio_read,
 	new_bus->read = &fsl_pq_mdio_read,
 	new_bus->write = &fsl_pq_mdio_write,
 	new_bus->write = &fsl_pq_mdio_write,
 	new_bus->reset = &fsl_pq_mdio_reset,
 	new_bus->reset = &fsl_pq_mdio_reset,
+	new_bus->priv = priv;
 	fsl_pq_mdio_bus_name(new_bus->id, np);
 	fsl_pq_mdio_bus_name(new_bus->id, np);
 
 
 	/* Set the PHY base address */
 	/* Set the PHY base address */
@@ -291,6 +304,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
 		err = -ENOMEM;
 		err = -ENOMEM;
 		goto err_free_bus;
 		goto err_free_bus;
 	}
 	}
+	priv->map = map;
 
 
 	if (of_device_is_compatible(np, "fsl,gianfar-mdio") ||
 	if (of_device_is_compatible(np, "fsl,gianfar-mdio") ||
 			of_device_is_compatible(np, "fsl,gianfar-tbi") ||
 			of_device_is_compatible(np, "fsl,gianfar-tbi") ||
@@ -298,8 +312,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
 			of_device_is_compatible(np, "ucc_geth_phy"))
 			of_device_is_compatible(np, "ucc_geth_phy"))
 		map -= offsetof(struct fsl_pq_mdio, miimcfg);
 		map -= offsetof(struct fsl_pq_mdio, miimcfg);
 	regs = map;
 	regs = map;
-
-	new_bus->priv = (void __force *)regs;
+	priv->regs = regs;
 
 
 	new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
 	new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
 
 
@@ -392,10 +405,11 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
 err_free_irqs:
 err_free_irqs:
 	kfree(new_bus->irq);
 	kfree(new_bus->irq);
 err_unmap_regs:
 err_unmap_regs:
-	iounmap(regs);
+	iounmap(priv->map);
 err_free_bus:
 err_free_bus:
 	kfree(new_bus);
 	kfree(new_bus);
-
+err_free_priv:
+	kfree(priv);
 	return err;
 	return err;
 }
 }
 
 
@@ -404,14 +418,16 @@ static int fsl_pq_mdio_remove(struct of_device *ofdev)
 {
 {
 	struct device *device = &ofdev->dev;
 	struct device *device = &ofdev->dev;
 	struct mii_bus *bus = dev_get_drvdata(device);
 	struct mii_bus *bus = dev_get_drvdata(device);
+	struct fsl_pq_mdio_priv *priv = bus->priv;
 
 
 	mdiobus_unregister(bus);
 	mdiobus_unregister(bus);
 
 
 	dev_set_drvdata(device, NULL);
 	dev_set_drvdata(device, NULL);
 
 
-	iounmap(fsl_pq_mdio_get_regs(bus));
+	iounmap(priv->map);
 	bus->priv = NULL;
 	bus->priv = NULL;
 	mdiobus_free(bus);
 	mdiobus_free(bus);
+	kfree(priv);
 
 
 	return 0;
 	return 0;
 }
 }

+ 3 - 1
drivers/net/hamradio/bpqether.c

@@ -248,6 +248,7 @@ static netdev_tx_t bpq_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 {
 	unsigned char *ptr;
 	unsigned char *ptr;
 	struct bpqdev *bpq;
 	struct bpqdev *bpq;
+	struct net_device *orig_dev;
 	int size;
 	int size;
 
 
 	/*
 	/*
@@ -282,8 +283,9 @@ static netdev_tx_t bpq_xmit(struct sk_buff *skb, struct net_device *dev)
 
 
 	bpq = netdev_priv(dev);
 	bpq = netdev_priv(dev);
 
 
+	orig_dev = dev;
 	if ((dev = bpq_get_ether_dev(dev)) == NULL) {
 	if ((dev = bpq_get_ether_dev(dev)) == NULL) {
-		dev->stats.tx_dropped++;
+		orig_dev->stats.tx_dropped++;
 		kfree_skb(skb);
 		kfree_skb(skb);
 		return NETDEV_TX_OK;
 		return NETDEV_TX_OK;
 	}
 	}

+ 7 - 2
drivers/net/ixgbe/ixgbe_main.c

@@ -262,10 +262,12 @@ static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter,
 		int reg_idx = tx_ring->reg_idx;
 		int reg_idx = tx_ring->reg_idx;
 		int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
 		int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
 
 
-		if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+		switch (adapter->hw.mac.type) {
+		case ixgbe_mac_82598EB:
 			tc = reg_idx >> 2;
 			tc = reg_idx >> 2;
 			txoff = IXGBE_TFCS_TXOFF0;
 			txoff = IXGBE_TFCS_TXOFF0;
-		} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+			break;
+		case ixgbe_mac_82599EB:
 			tc = 0;
 			tc = 0;
 			txoff = IXGBE_TFCS_TXOFF;
 			txoff = IXGBE_TFCS_TXOFF;
 			if (dcb_i == 8) {
 			if (dcb_i == 8) {
@@ -284,6 +286,9 @@ static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter,
 						tc += (reg_idx - 96) >> 4;
 						tc += (reg_idx - 96) >> 4;
 				}
 				}
 			}
 			}
+			break;
+		default:
+			tc = 0;
 		}
 		}
 		txoff <<= tc;
 		txoff <<= tc;
 	}
 	}

+ 1 - 1
drivers/net/ll_temac_main.c

@@ -134,7 +134,7 @@ static int temac_dma_bd_init(struct net_device *ndev)
 	struct sk_buff *skb;
 	struct sk_buff *skb;
 	int i;
 	int i;
 
 
-	lp->rx_skb = kzalloc(sizeof(struct sk_buff)*RX_BD_NUM, GFP_KERNEL);
+	lp->rx_skb = kzalloc(sizeof(*lp->rx_skb) * RX_BD_NUM, GFP_KERNEL);
 	/* allocate the tx and rx ring buffer descriptors. */
 	/* allocate the tx and rx ring buffer descriptors. */
 	/* returns a virtual addres and a physical address. */
 	/* returns a virtual addres and a physical address. */
 	lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent,
 	lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent,

+ 4 - 2
drivers/net/mv643xx_eth.c

@@ -656,6 +656,7 @@ static int rxq_refill(struct rx_queue *rxq, int budget)
 		struct sk_buff *skb;
 		struct sk_buff *skb;
 		int rx;
 		int rx;
 		struct rx_desc *rx_desc;
 		struct rx_desc *rx_desc;
+		int size;
 
 
 		skb = __skb_dequeue(&mp->rx_recycle);
 		skb = __skb_dequeue(&mp->rx_recycle);
 		if (skb == NULL)
 		if (skb == NULL)
@@ -678,10 +679,11 @@ static int rxq_refill(struct rx_queue *rxq, int budget)
 
 
 		rx_desc = rxq->rx_desc_area + rx;
 		rx_desc = rxq->rx_desc_area + rx;
 
 
+		size = skb->end - skb->data;
 		rx_desc->buf_ptr = dma_map_single(mp->dev->dev.parent,
 		rx_desc->buf_ptr = dma_map_single(mp->dev->dev.parent,
-						  skb->data, mp->skb_size,
+						  skb->data, size,
 						  DMA_FROM_DEVICE);
 						  DMA_FROM_DEVICE);
-		rx_desc->buf_size = mp->skb_size;
+		rx_desc->buf_size = size;
 		rxq->rx_skb[rx] = skb;
 		rxq->rx_skb[rx] = skb;
 		wmb();
 		wmb();
 		rx_desc->cmd_sts = BUFFER_OWNED_BY_DMA | RX_ENABLE_INTERRUPT;
 		rx_desc->cmd_sts = BUFFER_OWNED_BY_DMA | RX_ENABLE_INTERRUPT;

+ 2 - 2
drivers/net/netxen/netxen_nic.h

@@ -53,8 +53,8 @@
 
 
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MINOR 0
 #define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 65
-#define NETXEN_NIC_LINUX_VERSIONID  "4.0.65"
+#define _NETXEN_NIC_LINUX_SUBVERSION 72
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.72"
 
 
 #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 24) + ((b) << 16) + (c))
 #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 24) + ((b) << 16) + (c))
 #define _major(v)	(((v) >> 24) & 0xff)
 #define _major(v)	(((v) >> 24) & 0xff)

+ 67 - 126
drivers/net/netxen/netxen_nic_ethtool.c

@@ -66,7 +66,7 @@ static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = {
 
 
 #define NETXEN_NIC_TEST_LEN	ARRAY_SIZE(netxen_nic_gstrings_test)
 #define NETXEN_NIC_TEST_LEN	ARRAY_SIZE(netxen_nic_gstrings_test)
 
 
-#define NETXEN_NIC_REGS_COUNT 42
+#define NETXEN_NIC_REGS_COUNT 30
 #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32))
 #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32))
 #define NETXEN_MAX_EEPROM_LEN   1024
 #define NETXEN_MAX_EEPROM_LEN   1024
 
 
@@ -312,150 +312,91 @@ static int netxen_nic_get_regs_len(struct net_device *dev)
 	return NETXEN_NIC_REGS_LEN;
 	return NETXEN_NIC_REGS_LEN;
 }
 }
 
 
-struct netxen_niu_regs {
-	__u32 reg[NETXEN_NIC_REGS_COUNT];
-};
-
-static struct netxen_niu_regs niu_registers[] = {
-	{
-	 /* GB Mode */
-	 {
-	  NETXEN_NIU_GB_SERDES_RESET,
-	  NETXEN_NIU_GB0_MII_MODE,
-	  NETXEN_NIU_GB1_MII_MODE,
-	  NETXEN_NIU_GB2_MII_MODE,
-	  NETXEN_NIU_GB3_MII_MODE,
-	  NETXEN_NIU_GB0_GMII_MODE,
-	  NETXEN_NIU_GB1_GMII_MODE,
-	  NETXEN_NIU_GB2_GMII_MODE,
-	  NETXEN_NIU_GB3_GMII_MODE,
-	  NETXEN_NIU_REMOTE_LOOPBACK,
-	  NETXEN_NIU_GB0_HALF_DUPLEX,
-	  NETXEN_NIU_GB1_HALF_DUPLEX,
-	  NETXEN_NIU_RESET_SYS_FIFOS,
-	  NETXEN_NIU_GB_CRC_DROP,
-	  NETXEN_NIU_GB_DROP_WRONGADDR,
-	  NETXEN_NIU_TEST_MUX_CTL,
-
-	  NETXEN_NIU_GB_MAC_CONFIG_0(0),
-	  NETXEN_NIU_GB_MAC_CONFIG_1(0),
-	  NETXEN_NIU_GB_HALF_DUPLEX_CTRL(0),
-	  NETXEN_NIU_GB_MAX_FRAME_SIZE(0),
-	  NETXEN_NIU_GB_TEST_REG(0),
-	  NETXEN_NIU_GB_MII_MGMT_CONFIG(0),
-	  NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
-	  NETXEN_NIU_GB_MII_MGMT_ADDR(0),
-	  NETXEN_NIU_GB_MII_MGMT_CTRL(0),
-	  NETXEN_NIU_GB_MII_MGMT_STATUS(0),
-	  NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
-	  NETXEN_NIU_GB_INTERFACE_CTRL(0),
-	  NETXEN_NIU_GB_INTERFACE_STATUS(0),
-	  NETXEN_NIU_GB_STATION_ADDR_0(0),
-	  NETXEN_NIU_GB_STATION_ADDR_1(0),
-	  -1,
-	  }
-	 },
-	{
-	 /* XG Mode */
-	 {
-	  NETXEN_NIU_XG_SINGLE_TERM,
-	  NETXEN_NIU_XG_DRIVE_HI,
-	  NETXEN_NIU_XG_DRIVE_LO,
-	  NETXEN_NIU_XG_DTX,
-	  NETXEN_NIU_XG_DEQ,
-	  NETXEN_NIU_XG_WORD_ALIGN,
-	  NETXEN_NIU_XG_RESET,
-	  NETXEN_NIU_XG_POWER_DOWN,
-	  NETXEN_NIU_XG_RESET_PLL,
-	  NETXEN_NIU_XG_SERDES_LOOPBACK,
-	  NETXEN_NIU_XG_DO_BYTE_ALIGN,
-	  NETXEN_NIU_XG_TX_ENABLE,
-	  NETXEN_NIU_XG_RX_ENABLE,
-	  NETXEN_NIU_XG_STATUS,
-	  NETXEN_NIU_XG_PAUSE_THRESHOLD,
-	  NETXEN_NIU_XGE_CONFIG_0,
-	  NETXEN_NIU_XGE_CONFIG_1,
-	  NETXEN_NIU_XGE_IPG,
-	  NETXEN_NIU_XGE_STATION_ADDR_0_HI,
-	  NETXEN_NIU_XGE_STATION_ADDR_0_1,
-	  NETXEN_NIU_XGE_STATION_ADDR_1_LO,
-	  NETXEN_NIU_XGE_STATUS,
-	  NETXEN_NIU_XGE_MAX_FRAME_SIZE,
-	  NETXEN_NIU_XGE_PAUSE_FRAME_VALUE,
-	  NETXEN_NIU_XGE_TX_BYTE_CNT,
-	  NETXEN_NIU_XGE_TX_FRAME_CNT,
-	  NETXEN_NIU_XGE_RX_BYTE_CNT,
-	  NETXEN_NIU_XGE_RX_FRAME_CNT,
-	  NETXEN_NIU_XGE_AGGR_ERROR_CNT,
-	  NETXEN_NIU_XGE_MULTICAST_FRAME_CNT,
-	  NETXEN_NIU_XGE_UNICAST_FRAME_CNT,
-	  NETXEN_NIU_XGE_CRC_ERROR_CNT,
-	  NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR,
-	  NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR,
-	  NETXEN_NIU_XGE_LOCAL_ERROR_CNT,
-	  NETXEN_NIU_XGE_REMOTE_ERROR_CNT,
-	  NETXEN_NIU_XGE_CONTROL_CHAR_CNT,
-	  NETXEN_NIU_XGE_PAUSE_FRAME_CNT,
-	  -1,
-	  }
-	 }
-};
-
 static void
 static void
 netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 {
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
 	struct netxen_adapter *adapter = netdev_priv(dev);
-	__u32 mode, *regs_buff = p;
-	int i, window;
+	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct nx_host_sds_ring *sds_ring;
+	u32 *regs_buff = p;
+	int ring, i = 0;
+	int port = adapter->physical_port;
 
 
 	memset(p, 0, NETXEN_NIC_REGS_LEN);
 	memset(p, 0, NETXEN_NIC_REGS_LEN);
+
 	regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
 	regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
 	    (adapter->pdev)->device;
 	    (adapter->pdev)->device;
-	/* which mode */
-	regs_buff[0] = NXRD32(adapter, NETXEN_NIU_MODE);
-	mode = regs_buff[0];
-
-	/* Common registers to all the modes */
-	regs_buff[2] = NXRD32(adapter, NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER);
-	/* GB/XGB Mode */
-	mode = (mode / 2) - 1;
-	window = 0;
-	if (mode <= 1) {
-		for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) {
-			/* GB: port specific registers */
-			if (mode == 0 && i >= 19)
-				window = adapter->physical_port *
-					NETXEN_NIC_PORT_WINDOW;
-
-			regs_buff[i] = NXRD32(adapter,
-				niu_registers[mode].reg[i - 3] + window);
-		}
 
 
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		return;
+
+	regs_buff[i++] = NXRD32(adapter, CRB_CMDPEG_STATE);
+	regs_buff[i++] = NXRD32(adapter, CRB_RCVPEG_STATE);
+	regs_buff[i++] = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
+	regs_buff[i++] = NXRDIO(adapter, adapter->crb_int_state_reg);
+	regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+	regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_STATE);
+	regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
+	regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
+	regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS2);
+
+	regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_0+0x3c);
+	regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_1+0x3c);
+	regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_2+0x3c);
+	regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_3+0x3c);
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+
+		regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_4+0x3c);
+		i += 2;
+
+		regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE_P3);
+		regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
+
+	} else {
+		i++;
+
+		regs_buff[i++] = NXRD32(adapter,
+					NETXEN_NIU_XGE_CONFIG_0+(0x10000*port));
+		regs_buff[i++] = NXRD32(adapter,
+					NETXEN_NIU_XGE_CONFIG_1+(0x10000*port));
+
+		regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE);
+		regs_buff[i++] = NXRDIO(adapter,
+				 adapter->tx_ring->crb_cmd_consumer);
+	}
+
+	regs_buff[i++] = NXRDIO(adapter, adapter->tx_ring->crb_cmd_producer);
+
+	regs_buff[i++] = NXRDIO(adapter,
+			 recv_ctx->rds_rings[0].crb_rcv_producer);
+	regs_buff[i++] = NXRDIO(adapter,
+			 recv_ctx->rds_rings[1].crb_rcv_producer);
+
+	regs_buff[i++] = adapter->max_sds_rings;
+
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &(recv_ctx->sds_rings[ring]);
+		regs_buff[i++] = NXRDIO(adapter,
+					sds_ring->crb_sts_consumer);
 	}
 	}
 }
 }
 
 
 static u32 netxen_nic_test_link(struct net_device *dev)
 static u32 netxen_nic_test_link(struct net_device *dev)
 {
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
 	struct netxen_adapter *adapter = netdev_priv(dev);
-	__u32 status;
-	int val;
+	u32 val, port;
 
 
-	/* read which mode */
-	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
-		if (adapter->phy_read &&
-		    adapter->phy_read(adapter,
-				      NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
-				      &status) != 0)
-			return -EIO;
-		else {
-			val = netxen_get_phy_link(status);
-			return !val;
-		}
-	} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
+	port = adapter->physical_port;
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		val = NXRD32(adapter, CRB_XG_STATE_P3);
+		val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
+		return (val == XG_LINK_UP_P3) ? 0 : 1;
+	} else {
 		val = NXRD32(adapter, CRB_XG_STATE);
 		val = NXRD32(adapter, CRB_XG_STATE);
+		val = (val >> port*8) & 0xff;
 		return (val == XG_LINK_UP) ? 0 : 1;
 		return (val == XG_LINK_UP) ? 0 : 1;
 	}
 	}
-	return -EIO;
 }
 }
 
 
 static int
 static int

+ 4 - 2
drivers/net/netxen/netxen_nic_hw.c

@@ -345,8 +345,7 @@ netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg)
 void
 void
 netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem)
 netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem)
 {
 {
-	int val;
-	val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
+	NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
 }
 }
 
 
 int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
 int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
@@ -691,6 +690,9 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
 	struct list_head *head;
 	struct list_head *head;
 	nx_mac_list_t *cur;
 	nx_mac_list_t *cur;
 
 
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		return;
+
 	list_splice_tail_init(&adapter->mac_list, &del_list);
 	list_splice_tail_init(&adapter->mac_list, &del_list);
 
 
 	nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list);
 	nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list);

+ 3 - 1
drivers/net/netxen/netxen_nic_init.c

@@ -184,6 +184,8 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter)
 
 
 	tx_ring = adapter->tx_ring;
 	tx_ring = adapter->tx_ring;
 	vfree(tx_ring->cmd_buf_arr);
 	vfree(tx_ring->cmd_buf_arr);
+	kfree(tx_ring);
+	adapter->tx_ring = NULL;
 }
 }
 
 
 int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
 int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
@@ -782,7 +784,7 @@ netxen_need_fw_reset(struct netxen_adapter *adapter)
 	if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED)
 	if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED)
 		return 1;
 		return 1;
 
 
-	old_count = count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
+	old_count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
 
 
 	for (i = 0; i < 10; i++) {
 	for (i = 0; i < 10; i++) {
 
 

+ 3 - 7
drivers/net/netxen/netxen_nic_main.c

@@ -340,7 +340,7 @@ netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot)
 		if (!(first_boot & 0x4)) {
 		if (!(first_boot & 0x4)) {
 			first_boot |= 0x4;
 			first_boot |= 0x4;
 			NXWR32(adapter, NETXEN_PCIE_REG(0x4), first_boot);
 			NXWR32(adapter, NETXEN_PCIE_REG(0x4), first_boot);
-			first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4));
+			NXRD32(adapter, NETXEN_PCIE_REG(0x4));
 		}
 		}
 
 
 		/* This is the first boot after power up */
 		/* This is the first boot after power up */
@@ -1898,12 +1898,8 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
 		linkup = (val == XG_LINK_UP_P3);
 		linkup = (val == XG_LINK_UP_P3);
 	} else {
 	} else {
 		val = NXRD32(adapter, CRB_XG_STATE);
 		val = NXRD32(adapter, CRB_XG_STATE);
-		if (adapter->ahw.port_type == NETXEN_NIC_GBE)
-			linkup = (val >> port) & 1;
-		else {
-			val = (val >> port*8) & 0xff;
-			linkup = (val == XG_LINK_UP);
-		}
+		val = (val >> port*8) & 0xff;
+		linkup = (val == XG_LINK_UP);
 	}
 	}
 
 
 	netxen_advert_link_change(adapter, linkup);
 	netxen_advert_link_change(adapter, linkup);

+ 1 - 1
drivers/net/niu.c

@@ -2844,7 +2844,7 @@ static int tcam_wait_bit(struct niu *np, u64 bit)
 			break;
 			break;
 		udelay(1);
 		udelay(1);
 	}
 	}
-	if (limit < 0)
+	if (limit <= 0)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	return 0;
 	return 0;

+ 0 - 1
drivers/net/pcmcia/nmclan_cs.c

@@ -1402,7 +1402,6 @@ static void BuildLAF(int *ladrf, int *adr)
   for (i = 0; i < 8; i++)
   for (i = 0; i < 8; i++)
     printk(KERN_CONT " %02X", ladrf[i]);
     printk(KERN_CONT " %02X", ladrf[i]);
   printk(KERN_CONT "\n");
   printk(KERN_CONT "\n");
-  }
 #endif
 #endif
 } /* BuildLAF */
 } /* BuildLAF */
 
 

+ 2 - 2
drivers/net/pcmcia/pcnet_cs.c

@@ -1741,7 +1741,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"),
 	PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"),
 	PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"),
-	PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "cis/PE520.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("PMX   ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("PMX   ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"),
@@ -1754,7 +1754,7 @@ MODULE_DEVICE_TABLE(pcmcia, pcnet_ids);
 MODULE_FIRMWARE("cis/PCMLM28.cis");
 MODULE_FIRMWARE("cis/PCMLM28.cis");
 MODULE_FIRMWARE("cis/DP83903.cis");
 MODULE_FIRMWARE("cis/DP83903.cis");
 MODULE_FIRMWARE("cis/LA-PCM.cis");
 MODULE_FIRMWARE("cis/LA-PCM.cis");
-MODULE_FIRMWARE("PE520.cis");
+MODULE_FIRMWARE("cis/PE520.cis");
 MODULE_FIRMWARE("cis/NE2K.cis");
 MODULE_FIRMWARE("cis/NE2K.cis");
 MODULE_FIRMWARE("cis/PE-200.cis");
 MODULE_FIRMWARE("cis/PE-200.cis");
 MODULE_FIRMWARE("cis/tamarack.cis");
 MODULE_FIRMWARE("cis/tamarack.cis");

+ 2 - 2
drivers/net/phy/broadcom.c

@@ -331,8 +331,8 @@ static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev)
 	bool clk125en = true;
 	bool clk125en = true;
 
 
 	/* Abort if we are using an untested phy. */
 	/* Abort if we are using an untested phy. */
-	if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 ||
-	    BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 ||
+	if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 &&
+	    BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 &&
 	    BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M)
 	    BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M)
 		return;
 		return;
 
 

+ 64 - 8
drivers/net/phy/mdio_bus.c

@@ -264,6 +264,8 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv)
 		(phydev->phy_id & phydrv->phy_id_mask));
 		(phydev->phy_id & phydrv->phy_id_mask));
 }
 }
 
 
+#ifdef CONFIG_PM
+
 static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
 static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
 {
 {
 	struct device_driver *drv = phydev->dev.driver;
 	struct device_driver *drv = phydev->dev.driver;
@@ -295,34 +297,88 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
 	return true;
 	return true;
 }
 }
 
 
-/* Suspend and resume.  Copied from platform_suspend and
- * platform_resume
- */
-static int mdio_bus_suspend(struct device * dev, pm_message_t state)
+static int mdio_bus_suspend(struct device *dev)
 {
 {
 	struct phy_driver *phydrv = to_phy_driver(dev->driver);
 	struct phy_driver *phydrv = to_phy_driver(dev->driver);
 	struct phy_device *phydev = to_phy_device(dev);
 	struct phy_device *phydev = to_phy_device(dev);
 
 
+	/*
+	 * We must stop the state machine manually, otherwise it stops out of
+	 * control, possibly with the phydev->lock held. Upon resume, netdev
+	 * may call phy routines that try to grab the same lock, and that may
+	 * lead to a deadlock.
+	 */
+	if (phydev->attached_dev)
+		phy_stop_machine(phydev);
+
 	if (!mdio_bus_phy_may_suspend(phydev))
 	if (!mdio_bus_phy_may_suspend(phydev))
 		return 0;
 		return 0;
+
 	return phydrv->suspend(phydev);
 	return phydrv->suspend(phydev);
 }
 }
 
 
-static int mdio_bus_resume(struct device * dev)
+static int mdio_bus_resume(struct device *dev)
 {
 {
 	struct phy_driver *phydrv = to_phy_driver(dev->driver);
 	struct phy_driver *phydrv = to_phy_driver(dev->driver);
 	struct phy_device *phydev = to_phy_device(dev);
 	struct phy_device *phydev = to_phy_device(dev);
+	int ret;
 
 
 	if (!mdio_bus_phy_may_suspend(phydev))
 	if (!mdio_bus_phy_may_suspend(phydev))
+		goto no_resume;
+
+	ret = phydrv->resume(phydev);
+	if (ret < 0)
+		return ret;
+
+no_resume:
+	if (phydev->attached_dev)
+		phy_start_machine(phydev, NULL);
+
+	return 0;
+}
+
+static int mdio_bus_restore(struct device *dev)
+{
+	struct phy_device *phydev = to_phy_device(dev);
+	struct net_device *netdev = phydev->attached_dev;
+	int ret;
+
+	if (!netdev)
 		return 0;
 		return 0;
-	return phydrv->resume(phydev);
+
+	ret = phy_init_hw(phydev);
+	if (ret < 0)
+		return ret;
+
+	/* The PHY needs to renegotiate. */
+	phydev->link = 0;
+	phydev->state = PHY_UP;
+
+	phy_start_machine(phydev, NULL);
+
+	return 0;
 }
 }
 
 
+static struct dev_pm_ops mdio_bus_pm_ops = {
+	.suspend = mdio_bus_suspend,
+	.resume = mdio_bus_resume,
+	.freeze = mdio_bus_suspend,
+	.thaw = mdio_bus_resume,
+	.restore = mdio_bus_restore,
+};
+
+#define MDIO_BUS_PM_OPS (&mdio_bus_pm_ops)
+
+#else
+
+#define MDIO_BUS_PM_OPS NULL
+
+#endif /* CONFIG_PM */
+
 struct bus_type mdio_bus_type = {
 struct bus_type mdio_bus_type = {
 	.name		= "mdio_bus",
 	.name		= "mdio_bus",
 	.match		= mdio_bus_match,
 	.match		= mdio_bus_match,
-	.suspend	= mdio_bus_suspend,
-	.resume		= mdio_bus_resume,
+	.pm		= MDIO_BUS_PM_OPS,
 };
 };
 EXPORT_SYMBOL(mdio_bus_type);
 EXPORT_SYMBOL(mdio_bus_type);
 
 

+ 15 - 15
drivers/net/phy/phy_device.c

@@ -378,6 +378,20 @@ void phy_disconnect(struct phy_device *phydev)
 }
 }
 EXPORT_SYMBOL(phy_disconnect);
 EXPORT_SYMBOL(phy_disconnect);
 
 
+int phy_init_hw(struct phy_device *phydev)
+{
+	int ret;
+
+	if (!phydev->drv || !phydev->drv->config_init)
+		return 0;
+
+	ret = phy_scan_fixups(phydev);
+	if (ret < 0)
+		return ret;
+
+	return phydev->drv->config_init(phydev);
+}
+
 /**
 /**
  * phy_attach_direct - attach a network device to a given PHY device pointer
  * phy_attach_direct - attach a network device to a given PHY device pointer
  * @dev: network device to attach
  * @dev: network device to attach
@@ -425,21 +439,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 	/* Do initial configuration here, now that
 	/* Do initial configuration here, now that
 	 * we have certain key parameters
 	 * we have certain key parameters
 	 * (dev_flags and interface) */
 	 * (dev_flags and interface) */
-	if (phydev->drv->config_init) {
-		int err;
-
-		err = phy_scan_fixups(phydev);
-
-		if (err < 0)
-			return err;
-
-		err = phydev->drv->config_init(phydev);
-
-		if (err < 0)
-			return err;
-	}
-
-	return 0;
+	return phy_init_hw(phydev);
 }
 }
 EXPORT_SYMBOL(phy_attach_direct);
 EXPORT_SYMBOL(phy_attach_direct);
 
 

+ 1 - 1
drivers/net/rrunner.c

@@ -1293,7 +1293,7 @@ static void rr_dump(struct net_device *dev)
 
 
 	printk("Error code 0x%x\n", readl(&regs->Fail1));
 	printk("Error code 0x%x\n", readl(&regs->Fail1));
 
 
-	index = (((readl(&regs->EvtPrd) >> 8) & 0xff ) - 1) % EVT_RING_ENTRIES;
+	index = (((readl(&regs->EvtPrd) >> 8) & 0xff) - 1) % TX_RING_ENTRIES;
 	cons = rrpriv->dirty_tx;
 	cons = rrpriv->dirty_tx;
 	printk("TX ring index %i, TX consumer %i\n",
 	printk("TX ring index %i, TX consumer %i\n",
 	       index, cons);
 	       index, cons);

+ 1 - 1
drivers/net/sh_eth.c

@@ -110,7 +110,7 @@ static void sh_eth_reset(struct net_device *ndev)
 		mdelay(1);
 		mdelay(1);
 		cnt--;
 		cnt--;
 	}
 	}
-	if (cnt < 0)
+	if (cnt == 0)
 		printk(KERN_ERR "Device reset fail\n");
 		printk(KERN_ERR "Device reset fail\n");
 
 
 	/* Table Init */
 	/* Table Init */

+ 2 - 1
drivers/net/sky2.c

@@ -1844,7 +1844,8 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
 	sky2->tx_cons = idx;
 	sky2->tx_cons = idx;
 	smp_mb();
 	smp_mb();
 
 
-	if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
+	/* Wake unless it's detached, and called e.g. from sky2_down() */
+	if (tx_avail(sky2) > MAX_SKB_TX_LE + 4 && netif_device_present(dev))
 		netif_wake_queue(dev);
 		netif_wake_queue(dev);
 }
 }
 
 

+ 4 - 0
drivers/net/tulip/Kconfig

@@ -101,6 +101,10 @@ config TULIP_NAPI_HW_MITIGATION
 
 
 	  If in doubt, say Y.
 	  If in doubt, say Y.
 
 
+config TULIP_DM910X
+	def_bool y
+	depends on TULIP && SPARC
+
 config DE4X5
 config DE4X5
 	tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA"
 	tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA"
 	depends on PCI || EISA
 	depends on PCI || EISA

+ 21 - 0
drivers/net/tulip/dmfe.c

@@ -92,6 +92,10 @@
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 #include <asm/irq.h>
 
 
+#ifdef CONFIG_TULIP_DM910X
+#include <linux/of.h>
+#endif
+
 
 
 /* Board/System/Debug information/definition ---------------- */
 /* Board/System/Debug information/definition ---------------- */
 #define PCI_DM9132_ID   0x91321282      /* Davicom DM9132 ID */
 #define PCI_DM9132_ID   0x91321282      /* Davicom DM9132 ID */
@@ -377,6 +381,23 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
 	if (!printed_version++)
 	if (!printed_version++)
 		printk(version);
 		printk(version);
 
 
+	/*
+	 *	SPARC on-board DM910x chips should be handled by the main
+	 *	tulip driver, except for early DM9100s.
+	 */
+#ifdef CONFIG_TULIP_DM910X
+	if ((ent->driver_data == PCI_DM9100_ID && pdev->revision >= 0x30) ||
+	    ent->driver_data == PCI_DM9102_ID) {
+		struct device_node *dp = pci_device_to_OF_node(pdev);
+
+		if (dp && of_get_property(dp, "local-mac-address", NULL)) {
+			printk(KERN_INFO DRV_NAME
+			       ": skipping on-board DM910x (use tulip)\n");
+			return -ENODEV;
+		}
+	}
+#endif
+
 	/* Init network device */
 	/* Init network device */
 	dev = alloc_etherdev(sizeof(*db));
 	dev = alloc_etherdev(sizeof(*db));
 	if (dev == NULL)
 	if (dev == NULL)

+ 25 - 7
drivers/net/tulip/tulip_core.c

@@ -196,9 +196,13 @@ struct tulip_chip_table tulip_tbl[] = {
 	| HAS_NWAY | HAS_PCI_MWI, tulip_timer, tulip_media_task },
 	| HAS_NWAY | HAS_PCI_MWI, tulip_timer, tulip_media_task },
 
 
   /* DM910X */
   /* DM910X */
+#ifdef CONFIG_TULIP_DM910X
   { "Davicom DM9102/DM9102A", 128, 0x0001ebef,
   { "Davicom DM9102/DM9102A", 128, 0x0001ebef,
 	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI,
 	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI,
 	tulip_timer, tulip_media_task },
 	tulip_timer, tulip_media_task },
+#else
+  { NULL },
+#endif
 
 
   /* RS7112 */
   /* RS7112 */
   { "Conexant LANfinity", 256, 0x0001ebef,
   { "Conexant LANfinity", 256, 0x0001ebef,
@@ -228,8 +232,10 @@ static struct pci_device_id tulip_pci_tbl[] = {
 	{ 0x1259, 0xa120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1259, 0xa120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 },
 	{ 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 },
 	{ 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 },
 	{ 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 },
+#ifdef CONFIG_TULIP_DM910X
 	{ 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
 	{ 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
 	{ 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
 	{ 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
+#endif
 	{ 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
 	{ 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
 	{ 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
@@ -1299,18 +1305,30 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
 	}
 	}
 
 
 	/*
 	/*
-	 *	Early DM9100's need software CRC and the DMFE driver
+	 *	DM910x chips should be handled by the dmfe driver, except
+	 *	on-board chips on SPARC systems.  Also, early DM9100s need
+	 *	software CRC which only the dmfe driver supports.
 	 */
 	 */
 
 
-	if (pdev->vendor == 0x1282 && pdev->device == 0x9100)
-	{
-		/* Read Chip revision */
-		if (pdev->revision < 0x30)
-		{
-			printk(KERN_ERR PFX "skipping early DM9100 with Crc bug (use dmfe)\n");
+#ifdef CONFIG_TULIP_DM910X
+	if (chip_idx == DM910X) {
+		struct device_node *dp;
+
+		if (pdev->vendor == 0x1282 && pdev->device == 0x9100 &&
+		    pdev->revision < 0x30) {
+			printk(KERN_INFO PFX
+			       "skipping early DM9100 with Crc bug (use dmfe)\n");
+			return -ENODEV;
+		}
+
+		dp = pci_device_to_OF_node(pdev);
+		if (!(dp && of_get_property(dp, "local-mac-address", NULL))) {
+			printk(KERN_INFO PFX
+			       "skipping DM910x expansion card (use dmfe)\n");
 			return -ENODEV;
 			return -ENODEV;
 		}
 		}
 	}
 	}
+#endif
 
 
 	/*
 	/*
 	 *	Looks for early PCI chipsets where people report hangs
 	 *	Looks for early PCI chipsets where people report hangs

+ 2 - 1
drivers/net/ucc_geth.c

@@ -3607,6 +3607,7 @@ static int ucc_geth_suspend(struct of_device *ofdev, pm_message_t state)
 	if (!netif_running(ndev))
 	if (!netif_running(ndev))
 		return 0;
 		return 0;
 
 
+	netif_device_detach(ndev);
 	napi_disable(&ugeth->napi);
 	napi_disable(&ugeth->napi);
 
 
 	/*
 	/*
@@ -3665,7 +3666,7 @@ static int ucc_geth_resume(struct of_device *ofdev)
 	phy_start(ugeth->phydev);
 	phy_start(ugeth->phydev);
 
 
 	napi_enable(&ugeth->napi);
 	napi_enable(&ugeth->napi);
-	netif_start_queue(ndev);
+	netif_device_attach(ndev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 7 - 6
drivers/net/ucc_geth.h

@@ -838,13 +838,13 @@ struct ucc_geth_hardware_statistics {
 							   using the maximum is
 							   using the maximum is
 							   easier */
 							   easier */
 #define UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT	32
 #define UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT	32
-#define UCC_GETH_SCHEDULER_ALIGNMENT		4	/* This is a guess */
+#define UCC_GETH_SCHEDULER_ALIGNMENT		8	/* This is a guess */
 #define UCC_GETH_TX_STATISTICS_ALIGNMENT	4	/* This is a guess */
 #define UCC_GETH_TX_STATISTICS_ALIGNMENT	4	/* This is a guess */
 #define UCC_GETH_RX_STATISTICS_ALIGNMENT	4	/* This is a guess */
 #define UCC_GETH_RX_STATISTICS_ALIGNMENT	4	/* This is a guess */
 #define UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT	64
 #define UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT	64
 #define UCC_GETH_RX_BD_QUEUES_ALIGNMENT		8	/* This is a guess */
 #define UCC_GETH_RX_BD_QUEUES_ALIGNMENT		8	/* This is a guess */
 #define UCC_GETH_RX_PREFETCHED_BDS_ALIGNMENT	128	/* This is a guess */
 #define UCC_GETH_RX_PREFETCHED_BDS_ALIGNMENT	128	/* This is a guess */
-#define UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 4	/* This
+#define UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 8	/* This
 									   is a
 									   is a
 									   guess
 									   guess
 									 */
 									 */
@@ -899,16 +899,17 @@ struct ucc_geth_hardware_statistics {
 #define UCC_GETH_UTFS_INIT                      512	/* Tx virtual FIFO size
 #define UCC_GETH_UTFS_INIT                      512	/* Tx virtual FIFO size
 							 */
 							 */
 #define UCC_GETH_UTFET_INIT                     256	/* 1/2 utfs */
 #define UCC_GETH_UTFET_INIT                     256	/* 1/2 utfs */
-#define UCC_GETH_UTFTT_INIT                     128
+#define UCC_GETH_UTFTT_INIT                     512
 /* Gigabit Ethernet (1000 Mbps) */
 /* Gigabit Ethernet (1000 Mbps) */
 #define UCC_GETH_URFS_GIGA_INIT                 4096/*2048*/	/* Rx virtual
 #define UCC_GETH_URFS_GIGA_INIT                 4096/*2048*/	/* Rx virtual
 								   FIFO size */
 								   FIFO size */
 #define UCC_GETH_URFET_GIGA_INIT                2048/*1024*/	/* 1/2 urfs */
 #define UCC_GETH_URFET_GIGA_INIT                2048/*1024*/	/* 1/2 urfs */
 #define UCC_GETH_URFSET_GIGA_INIT               3072/*1536*/	/* 3/4 urfs */
 #define UCC_GETH_URFSET_GIGA_INIT               3072/*1536*/	/* 3/4 urfs */
-#define UCC_GETH_UTFS_GIGA_INIT                 8192/*2048*/	/* Tx virtual
+#define UCC_GETH_UTFS_GIGA_INIT                 4096/*2048*/	/* Tx virtual
+								   FIFO size */
+#define UCC_GETH_UTFET_GIGA_INIT                2048/*1024*/	/* 1/2 utfs */
+#define UCC_GETH_UTFTT_GIGA_INIT                4096/*0x40*/	/* Tx virtual
 								   FIFO size */
 								   FIFO size */
-#define UCC_GETH_UTFET_GIGA_INIT                4096/*1024*/	/* 1/2 utfs */
-#define UCC_GETH_UTFTT_GIGA_INIT                0x400/*0x40*/	/* */
 
 
 #define UCC_GETH_REMODER_INIT                   0	/* bits that must be
 #define UCC_GETH_REMODER_INIT                   0	/* bits that must be
 							   set */
 							   set */

+ 77 - 28
drivers/net/usb/hso.c

@@ -286,6 +286,7 @@ struct hso_device {
 	u8 usb_gone;
 	u8 usb_gone;
 	struct work_struct async_get_intf;
 	struct work_struct async_get_intf;
 	struct work_struct async_put_intf;
 	struct work_struct async_put_intf;
+	struct work_struct reset_device;
 
 
 	struct usb_device *usb;
 	struct usb_device *usb;
 	struct usb_interface *interface;
 	struct usb_interface *interface;
@@ -332,7 +333,8 @@ static void hso_kick_transmit(struct hso_serial *serial);
 /* Helper functions */
 /* Helper functions */
 static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int,
 static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int,
 				   struct usb_device *usb, gfp_t gfp);
 				   struct usb_device *usb, gfp_t gfp);
-static void log_usb_status(int status, const char *function);
+static void handle_usb_error(int status, const char *function,
+			     struct hso_device *hso_dev);
 static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf,
 static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf,
 						  int type, int dir);
 						  int type, int dir);
 static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports);
 static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports);
@@ -350,6 +352,7 @@ static void async_put_intf(struct work_struct *data);
 static int hso_put_activity(struct hso_device *hso_dev);
 static int hso_put_activity(struct hso_device *hso_dev);
 static int hso_get_activity(struct hso_device *hso_dev);
 static int hso_get_activity(struct hso_device *hso_dev);
 static void tiocmget_intr_callback(struct urb *urb);
 static void tiocmget_intr_callback(struct urb *urb);
+static void reset_device(struct work_struct *data);
 /*****************************************************************************/
 /*****************************************************************************/
 /* Helping functions                                                         */
 /* Helping functions                                                         */
 /*****************************************************************************/
 /*****************************************************************************/
@@ -461,10 +464,17 @@ static const struct usb_device_id hso_ids[] = {
 	{USB_DEVICE(0x0af0, 0x7501)},		/* GTM 382 */
 	{USB_DEVICE(0x0af0, 0x7501)},		/* GTM 382 */
 	{USB_DEVICE(0x0af0, 0x7601)},		/* GE40x */
 	{USB_DEVICE(0x0af0, 0x7601)},		/* GE40x */
 	{USB_DEVICE(0x0af0, 0x7701)},
 	{USB_DEVICE(0x0af0, 0x7701)},
+	{USB_DEVICE(0x0af0, 0x7706)},
 	{USB_DEVICE(0x0af0, 0x7801)},
 	{USB_DEVICE(0x0af0, 0x7801)},
 	{USB_DEVICE(0x0af0, 0x7901)},
 	{USB_DEVICE(0x0af0, 0x7901)},
+	{USB_DEVICE(0x0af0, 0x7A01)},
+	{USB_DEVICE(0x0af0, 0x7A05)},
 	{USB_DEVICE(0x0af0, 0x8200)},
 	{USB_DEVICE(0x0af0, 0x8200)},
 	{USB_DEVICE(0x0af0, 0x8201)},
 	{USB_DEVICE(0x0af0, 0x8201)},
+	{USB_DEVICE(0x0af0, 0x8300)},
+	{USB_DEVICE(0x0af0, 0x8302)},
+	{USB_DEVICE(0x0af0, 0x8304)},
+	{USB_DEVICE(0x0af0, 0x8400)},
 	{USB_DEVICE(0x0af0, 0xd035)},
 	{USB_DEVICE(0x0af0, 0xd035)},
 	{USB_DEVICE(0x0af0, 0xd055)},
 	{USB_DEVICE(0x0af0, 0xd055)},
 	{USB_DEVICE(0x0af0, 0xd155)},
 	{USB_DEVICE(0x0af0, 0xd155)},
@@ -473,6 +483,8 @@ static const struct usb_device_id hso_ids[] = {
 	{USB_DEVICE(0x0af0, 0xd157)},
 	{USB_DEVICE(0x0af0, 0xd157)},
 	{USB_DEVICE(0x0af0, 0xd257)},
 	{USB_DEVICE(0x0af0, 0xd257)},
 	{USB_DEVICE(0x0af0, 0xd357)},
 	{USB_DEVICE(0x0af0, 0xd357)},
+	{USB_DEVICE(0x0af0, 0xd058)},
+	{USB_DEVICE(0x0af0, 0xc100)},
 	{}
 	{}
 };
 };
 MODULE_DEVICE_TABLE(usb, hso_ids);
 MODULE_DEVICE_TABLE(usb, hso_ids);
@@ -655,8 +667,8 @@ static void set_serial_by_index(unsigned index, struct hso_serial *serial)
 	spin_unlock_irqrestore(&serial_table_lock, flags);
 	spin_unlock_irqrestore(&serial_table_lock, flags);
 }
 }
 
 
-/* log a meaningful explanation of an USB status */
-static void log_usb_status(int status, const char *function)
+static void handle_usb_error(int status, const char *function,
+			     struct hso_device *hso_dev)
 {
 {
 	char *explanation;
 	char *explanation;
 
 
@@ -685,10 +697,20 @@ static void log_usb_status(int status, const char *function)
 	case -EMSGSIZE:
 	case -EMSGSIZE:
 		explanation = "internal error";
 		explanation = "internal error";
 		break;
 		break;
+	case -EILSEQ:
+	case -EPROTO:
+	case -ETIME:
+	case -ETIMEDOUT:
+		explanation = "protocol error";
+		if (hso_dev)
+			schedule_work(&hso_dev->reset_device);
+		break;
 	default:
 	default:
 		explanation = "unknown status";
 		explanation = "unknown status";
 		break;
 		break;
 	}
 	}
+
+	/* log a meaningful explanation of an USB status */
 	D1("%s: received USB status - %s (%d)", function, explanation, status);
 	D1("%s: received USB status - %s (%d)", function, explanation, status);
 }
 }
 
 
@@ -762,7 +784,7 @@ static void write_bulk_callback(struct urb *urb)
 	/* log status, but don't act on it, we don't need to resubmit anything
 	/* log status, but don't act on it, we don't need to resubmit anything
 	 * anyhow */
 	 * anyhow */
 	if (status)
 	if (status)
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, odev->parent);
 
 
 	hso_put_activity(odev->parent);
 	hso_put_activity(odev->parent);
 
 
@@ -806,7 +828,7 @@ static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb,
 	result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC);
 	result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC);
 	if (result) {
 	if (result) {
 		dev_warn(&odev->parent->interface->dev,
 		dev_warn(&odev->parent->interface->dev,
-			"failed mux_bulk_tx_urb %d", result);
+			"failed mux_bulk_tx_urb %d\n", result);
 		net->stats.tx_errors++;
 		net->stats.tx_errors++;
 		netif_start_queue(net);
 		netif_start_queue(net);
 	} else {
 	} else {
@@ -998,7 +1020,7 @@ static void read_bulk_callback(struct urb *urb)
 
 
 	/* is al ok?  (Filip: Who's Al ?) */
 	/* is al ok?  (Filip: Who's Al ?) */
 	if (status) {
 	if (status) {
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, odev->parent);
 		return;
 		return;
 	}
 	}
 
 
@@ -1019,7 +1041,8 @@ static void read_bulk_callback(struct urb *urb)
 	if (odev->parent->port_spec & HSO_INFO_CRC_BUG) {
 	if (odev->parent->port_spec & HSO_INFO_CRC_BUG) {
 		u32 rest;
 		u32 rest;
 		u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
 		u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
-		rest = urb->actual_length % odev->in_endp->wMaxPacketSize;
+		rest = urb->actual_length %
+			le16_to_cpu(odev->in_endp->wMaxPacketSize);
 		if (((rest == 5) || (rest == 6)) &&
 		if (((rest == 5) || (rest == 6)) &&
 		    !memcmp(((u8 *) urb->transfer_buffer) +
 		    !memcmp(((u8 *) urb->transfer_buffer) +
 			    urb->actual_length - 4, crc_check, 4)) {
 			    urb->actual_length - 4, crc_check, 4)) {
@@ -1053,7 +1076,7 @@ static void read_bulk_callback(struct urb *urb)
 	result = usb_submit_urb(urb, GFP_ATOMIC);
 	result = usb_submit_urb(urb, GFP_ATOMIC);
 	if (result)
 	if (result)
 		dev_warn(&odev->parent->interface->dev,
 		dev_warn(&odev->parent->interface->dev,
-			 "%s failed submit mux_bulk_rx_urb %d", __func__,
+			 "%s failed submit mux_bulk_rx_urb %d\n", __func__,
 			 result);
 			 result);
 }
 }
 
 
@@ -1207,7 +1230,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb)
 		D1("serial == NULL");
 		D1("serial == NULL");
 		return;
 		return;
 	} else if (status) {
 	} else if (status) {
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, serial->parent);
 		return;
 		return;
 	}
 	}
 
 
@@ -1225,7 +1248,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb)
 			u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
 			u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
 			rest =
 			rest =
 			    urb->actual_length %
 			    urb->actual_length %
-			    serial->in_endp->wMaxPacketSize;
+			    le16_to_cpu(serial->in_endp->wMaxPacketSize);
 			if (((rest == 5) || (rest == 6)) &&
 			if (((rest == 5) || (rest == 6)) &&
 			    !memcmp(((u8 *) urb->transfer_buffer) +
 			    !memcmp(((u8 *) urb->transfer_buffer) +
 				    urb->actual_length - 4, crc_check, 4)) {
 				    urb->actual_length - 4, crc_check, 4)) {
@@ -1513,7 +1536,7 @@ static void tiocmget_intr_callback(struct urb *urb)
 	if (!serial)
 	if (!serial)
 		return;
 		return;
 	if (status) {
 	if (status) {
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, serial->parent);
 		return;
 		return;
 	}
 	}
 	tiocmget = serial->tiocmget;
 	tiocmget = serial->tiocmget;
@@ -1700,6 +1723,10 @@ static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file,
 		D1("no tty structures");
 		D1("no tty structures");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
+
+	if ((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM)
+		return -EINVAL;
+
 	if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber;
 	if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber;
 
 
 	spin_lock_irqsave(&serial->serial_lock, flags);
 	spin_lock_irqsave(&serial->serial_lock, flags);
@@ -1838,7 +1865,7 @@ static int mux_device_request(struct hso_serial *serial, u8 type, u16 port,
 	result = usb_submit_urb(ctrl_urb, GFP_ATOMIC);
 	result = usb_submit_urb(ctrl_urb, GFP_ATOMIC);
 	if (result) {
 	if (result) {
 		dev_err(&ctrl_urb->dev->dev,
 		dev_err(&ctrl_urb->dev->dev,
-			"%s failed submit ctrl_urb %d type %d", __func__,
+			"%s failed submit ctrl_urb %d type %d\n", __func__,
 			result, type);
 			result, type);
 		return result;
 		return result;
 	}
 	}
@@ -1888,7 +1915,7 @@ static void intr_callback(struct urb *urb)
 
 
 	/* status check */
 	/* status check */
 	if (status) {
 	if (status) {
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, NULL);
 		return;
 		return;
 	}
 	}
 	D4("\n--- Got intr callback 0x%02X ---", status);
 	D4("\n--- Got intr callback 0x%02X ---", status);
@@ -1905,18 +1932,18 @@ static void intr_callback(struct urb *urb)
 			if (serial != NULL) {
 			if (serial != NULL) {
 				D1("Pending read interrupt on port %d\n", i);
 				D1("Pending read interrupt on port %d\n", i);
 				spin_lock(&serial->serial_lock);
 				spin_lock(&serial->serial_lock);
-				if (serial->rx_state == RX_IDLE) {
+				if (serial->rx_state == RX_IDLE &&
+					serial->open_count > 0) {
 					/* Setup and send a ctrl req read on
 					/* Setup and send a ctrl req read on
 					 * port i */
 					 * port i */
-				if (!serial->rx_urb_filled[0]) {
+					if (!serial->rx_urb_filled[0]) {
 						serial->rx_state = RX_SENT;
 						serial->rx_state = RX_SENT;
 						hso_mux_serial_read(serial);
 						hso_mux_serial_read(serial);
 					} else
 					} else
 						serial->rx_state = RX_PENDING;
 						serial->rx_state = RX_PENDING;
-
 				} else {
 				} else {
-					D1("Already pending a read on "
-					   "port %d\n", i);
+					D1("Already a read pending on "
+					   "port %d or port not open\n", i);
 				}
 				}
 				spin_unlock(&serial->serial_lock);
 				spin_unlock(&serial->serial_lock);
 			}
 			}
@@ -1958,7 +1985,7 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb)
 	tty = tty_kref_get(serial->tty);
 	tty = tty_kref_get(serial->tty);
 	spin_unlock(&serial->serial_lock);
 	spin_unlock(&serial->serial_lock);
 	if (status) {
 	if (status) {
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, serial->parent);
 		tty_kref_put(tty);
 		tty_kref_put(tty);
 		return;
 		return;
 	}
 	}
@@ -2014,7 +2041,7 @@ static void ctrl_callback(struct urb *urb)
 	tty = tty_kref_get(serial->tty);
 	tty = tty_kref_get(serial->tty);
 	spin_unlock(&serial->serial_lock);
 	spin_unlock(&serial->serial_lock);
 	if (status) {
 	if (status) {
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, serial->parent);
 		tty_kref_put(tty);
 		tty_kref_put(tty);
 		return;
 		return;
 	}
 	}
@@ -2358,12 +2385,12 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
 	serial->tx_data_length = tx_size;
 	serial->tx_data_length = tx_size;
 	serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL);
 	serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL);
 	if (!serial->tx_data) {
 	if (!serial->tx_data) {
-		dev_err(dev, "%s - Out of memory", __func__);
+		dev_err(dev, "%s - Out of memory\n", __func__);
 		goto exit;
 		goto exit;
 	}
 	}
 	serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL);
 	serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL);
 	if (!serial->tx_buffer) {
 	if (!serial->tx_buffer) {
-		dev_err(dev, "%s - Out of memory", __func__);
+		dev_err(dev, "%s - Out of memory\n", __func__);
 		goto exit;
 		goto exit;
 	}
 	}
 
 
@@ -2391,6 +2418,7 @@ static struct hso_device *hso_create_device(struct usb_interface *intf,
 
 
 	INIT_WORK(&hso_dev->async_get_intf, async_get_intf);
 	INIT_WORK(&hso_dev->async_get_intf, async_get_intf);
 	INIT_WORK(&hso_dev->async_put_intf, async_put_intf);
 	INIT_WORK(&hso_dev->async_put_intf, async_put_intf);
+	INIT_WORK(&hso_dev->reset_device, reset_device);
 
 
 	return hso_dev;
 	return hso_dev;
 }
 }
@@ -2831,13 +2859,14 @@ struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface)
 
 
 	mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL);
 	mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!mux->shared_intr_urb) {
 	if (!mux->shared_intr_urb) {
-		dev_err(&interface->dev, "Could not allocate intr urb?");
+		dev_err(&interface->dev, "Could not allocate intr urb?\n");
 		goto exit;
 		goto exit;
 	}
 	}
-	mux->shared_intr_buf = kzalloc(mux->intr_endp->wMaxPacketSize,
-				       GFP_KERNEL);
+	mux->shared_intr_buf =
+		kzalloc(le16_to_cpu(mux->intr_endp->wMaxPacketSize),
+			GFP_KERNEL);
 	if (!mux->shared_intr_buf) {
 	if (!mux->shared_intr_buf) {
-		dev_err(&interface->dev, "Could not allocate intr buf?");
+		dev_err(&interface->dev, "Could not allocate intr buf?\n");
 		goto exit;
 		goto exit;
 	}
 	}
 
 
@@ -3132,6 +3161,26 @@ static int hso_resume(struct usb_interface *iface)
 	return result;
 	return result;
 }
 }
 
 
+static void reset_device(struct work_struct *data)
+{
+	struct hso_device *hso_dev =
+	    container_of(data, struct hso_device, reset_device);
+	struct usb_device *usb = hso_dev->usb;
+	int result;
+
+	if (hso_dev->usb_gone) {
+		D1("No reset during disconnect\n");
+	} else {
+		result = usb_lock_device_for_reset(usb, hso_dev->interface);
+		if (result < 0)
+			D1("unable to lock device for reset: %d\n", result);
+		else {
+			usb_reset_device(usb);
+			usb_unlock_device(usb);
+		}
+	}
+}
+
 static void hso_serial_ref_free(struct kref *ref)
 static void hso_serial_ref_free(struct kref *ref)
 {
 {
 	struct hso_device *hso_dev = container_of(ref, struct hso_device, ref);
 	struct hso_device *hso_dev = container_of(ref, struct hso_device, ref);
@@ -3232,13 +3281,13 @@ static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int,
 			 usb_rcvintpipe(usb,
 			 usb_rcvintpipe(usb,
 				shared_int->intr_endp->bEndpointAddress & 0x7F),
 				shared_int->intr_endp->bEndpointAddress & 0x7F),
 			 shared_int->shared_intr_buf,
 			 shared_int->shared_intr_buf,
-			 shared_int->intr_endp->wMaxPacketSize,
+			 1,
 			 intr_callback, shared_int,
 			 intr_callback, shared_int,
 			 shared_int->intr_endp->bInterval);
 			 shared_int->intr_endp->bInterval);
 
 
 	result = usb_submit_urb(shared_int->shared_intr_urb, gfp);
 	result = usb_submit_urb(shared_int->shared_intr_urb, gfp);
 	if (result)
 	if (result)
-		dev_warn(&usb->dev, "%s failed mux_intr_urb %d", __func__,
+		dev_warn(&usb->dev, "%s failed mux_intr_urb %d\n", __func__,
 			result);
 			result);
 
 
 	return result;
 	return result;

+ 2 - 2
drivers/net/usb/rtl8150.c

@@ -270,7 +270,7 @@ static int read_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 * reg)
 		get_registers(dev, PHYCNT, 1, data);
 		get_registers(dev, PHYCNT, 1, data);
 	} while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT));
 	} while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT));
 
 
-	if (i < MII_TIMEOUT) {
+	if (i <= MII_TIMEOUT) {
 		get_registers(dev, PHYDAT, 2, data);
 		get_registers(dev, PHYDAT, 2, data);
 		*reg = data[0] | (data[1] << 8);
 		*reg = data[0] | (data[1] << 8);
 		return 0;
 		return 0;
@@ -295,7 +295,7 @@ static int write_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 reg)
 		get_registers(dev, PHYCNT, 1, data);
 		get_registers(dev, PHYCNT, 1, data);
 	} while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT));
 	} while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT));
 
 
-	if (i < MII_TIMEOUT)
+	if (i <= MII_TIMEOUT)
 		return 0;
 		return 0;
 	else
 	else
 		return 1;
 		return 1;

+ 4 - 4
drivers/net/via-velocity.c

@@ -2237,8 +2237,6 @@ static int velocity_open(struct net_device *dev)
 	/* Ensure chip is running */
 	/* Ensure chip is running */
 	pci_set_power_state(vptr->pdev, PCI_D0);
 	pci_set_power_state(vptr->pdev, PCI_D0);
 
 
-	velocity_give_many_rx_descs(vptr);
-
 	velocity_init_registers(vptr, VELOCITY_INIT_COLD);
 	velocity_init_registers(vptr, VELOCITY_INIT_COLD);
 
 
 	ret = request_irq(vptr->pdev->irq, velocity_intr, IRQF_SHARED,
 	ret = request_irq(vptr->pdev->irq, velocity_intr, IRQF_SHARED,
@@ -2250,6 +2248,8 @@ static int velocity_open(struct net_device *dev)
 		goto out;
 		goto out;
 	}
 	}
 
 
+	velocity_give_many_rx_descs(vptr);
+
 	mac_enable_int(vptr->mac_regs);
 	mac_enable_int(vptr->mac_regs);
 	netif_start_queue(dev);
 	netif_start_queue(dev);
 	napi_enable(&vptr->napi);
 	napi_enable(&vptr->napi);
@@ -2339,10 +2339,10 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
 
 
 		dev->mtu = new_mtu;
 		dev->mtu = new_mtu;
 
 
-		velocity_give_many_rx_descs(vptr);
-
 		velocity_init_registers(vptr, VELOCITY_INIT_COLD);
 		velocity_init_registers(vptr, VELOCITY_INIT_COLD);
 
 
+		velocity_give_many_rx_descs(vptr);
+
 		mac_enable_int(vptr->mac_regs);
 		mac_enable_int(vptr->mac_regs);
 		netif_start_queue(dev);
 		netif_start_queue(dev);
 
 

+ 1 - 1
drivers/net/vxge/vxge-main.c

@@ -310,7 +310,7 @@ static int vxge_rx_map(void *dtrh, struct vxge_ring *ring)
 	dma_addr = pci_map_single(ring->pdev, rx_priv->skb_data,
 	dma_addr = pci_map_single(ring->pdev, rx_priv->skb_data,
 				rx_priv->data_size, PCI_DMA_FROMDEVICE);
 				rx_priv->data_size, PCI_DMA_FROMDEVICE);
 
 
-	if (dma_addr == 0) {
+	if (unlikely(pci_dma_mapping_error(ring->pdev, dma_addr))) {
 		ring->stats.pci_map_fail++;
 		ring->stats.pci_map_fail++;
 		return -EIO;
 		return -EIO;
 	}
 	}

+ 1 - 1
drivers/s390/net/claw.c

@@ -3398,7 +3398,7 @@ claw_init(void)
 		goto out_err;
 		goto out_err;
 	}
 	}
 	CLAW_DBF_TEXT(2, setup, "init_mod");
 	CLAW_DBF_TEXT(2, setup, "init_mod");
-	claw_root_dev = root_device_register("qeth");
+	claw_root_dev = root_device_register("claw");
 	ret = IS_ERR(claw_root_dev) ? PTR_ERR(claw_root_dev) : 0;
 	ret = IS_ERR(claw_root_dev) ? PTR_ERR(claw_root_dev) : 0;
 	if (ret)
 	if (ret)
 		goto register_err;
 		goto register_err;

+ 14 - 1
drivers/serial/serial_cs.c

@@ -819,6 +819,7 @@ static struct pcmcia_device_id serial_ids[] = {
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
 	PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
+	PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC860", 0xd85f6206, 0x698f93db, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC860 3G Network Adapter R1 */
 	PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"),  /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
 	PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"),  /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
 	PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
 	PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
 	PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
 	PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
@@ -827,7 +828,7 @@ static struct pcmcia_device_id serial_ids[] = {
 	PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"),
-	PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"),
+	PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "cis/GLOBETROTTER.cis"),
 	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100  1.00.",0x19ca78af,0xf964f42b),
 	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100  1.00.",0x19ca78af,0xf964f42b),
 	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83),
 	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83),
 	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232  1.00.",0x19ca78af,0x69fb7490),
 	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232  1.00.",0x19ca78af,0x69fb7490),
@@ -861,6 +862,18 @@ static struct pcmcia_device_id serial_ids[] = {
 };
 };
 MODULE_DEVICE_TABLE(pcmcia, serial_ids);
 MODULE_DEVICE_TABLE(pcmcia, serial_ids);
 
 
+MODULE_FIRMWARE("cis/PCMLM28.cis");
+MODULE_FIRMWARE("cis/DP83903.cis");
+MODULE_FIRMWARE("cis/3CCFEM556.cis");
+MODULE_FIRMWARE("cis/3CXEM556.cis");
+MODULE_FIRMWARE("cis/SW_8xx_SER.cis");
+MODULE_FIRMWARE("cis/SW_7xx_SER.cis");
+MODULE_FIRMWARE("cis/SW_555_SER.cis");
+MODULE_FIRMWARE("cis/MT5634ZLX.cis");
+MODULE_FIRMWARE("cis/COMpad2.cis");
+MODULE_FIRMWARE("cis/COMpad4.cis");
+MODULE_FIRMWARE("cis/RS-COM-2P.cis");
+
 static struct pcmcia_driver serial_cs_driver = {
 static struct pcmcia_driver serial_cs_driver = {
 	.owner		= THIS_MODULE,
 	.owner		= THIS_MODULE,
 	.drv		= {
 	.drv		= {

+ 2 - 1
firmware/Makefile

@@ -69,7 +69,8 @@ fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
 fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin
 fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin
 fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis \
 fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis \
 				     cis/DP83903.cis cis/NE2K.cis \
 				     cis/DP83903.cis cis/NE2K.cis \
-				     cis/tamarack.cis cis/PE-200.cis
+				     cis/tamarack.cis cis/PE-200.cis \
+				     cis/PE520.cis
 fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis
 fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis
 fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis
 fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis
 fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis \
 fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis \

+ 1 - 0
firmware/WHENCE

@@ -601,6 +601,7 @@ File: cis/LA-PCM.cis
       cis/NE2K.cis
       cis/NE2K.cis
       cis/tamarack.cis
       cis/tamarack.cis
       cis/PE-200.cis
       cis/PE-200.cis
+      cis/PE520.cis
 
 
 Licence: GPL
 Licence: GPL
 
 

+ 9 - 0
firmware/cis/PE520.cis.ihex

@@ -0,0 +1,9 @@
+:1000000001030000FF152304014B544900504535FE
+:10001000323020504C55530050434D434941204508
+:10002000746865726E65740000FF20046101100041
+:10003000210206001A050101D00F0B1B09C101198D
+:0A00400001556530FFFF1400FF00BA
+:00000001FF
+#
+# Replacement CIS for PE520 ethernet card
+#

+ 1 - 0
include/linux/phy.h

@@ -447,6 +447,7 @@ struct phy_device* get_phy_device(struct mii_bus *bus, int addr);
 int phy_device_register(struct phy_device *phy);
 int phy_device_register(struct phy_device *phy);
 int phy_clear_interrupt(struct phy_device *phydev);
 int phy_clear_interrupt(struct phy_device *phydev);
 int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
 int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
+int phy_init_hw(struct phy_device *phydev);
 int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 		u32 flags, phy_interface_t interface);
 		u32 flags, phy_interface_t interface);
 struct phy_device * phy_attach(struct net_device *dev,
 struct phy_device * phy_attach(struct net_device *dev,

+ 16 - 0
include/net/ip.h

@@ -326,6 +326,22 @@ static __inline__ void inet_reset_saddr(struct sock *sk)
 
 
 #endif
 #endif
 
 
+static inline int sk_mc_loop(struct sock *sk)
+{
+	if (!sk)
+		return 1;
+	switch (sk->sk_family) {
+	case AF_INET:
+		return inet_sk(sk)->mc_loop;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		return inet6_sk(sk)->mc_loop;
+#endif
+	}
+	__WARN();
+	return 1;
+}
+
 extern int	ip_call_ra_chain(struct sk_buff *skb);
 extern int	ip_call_ra_chain(struct sk_buff *skb);
 
 
 /*
 /*

+ 6 - 0
net/bridge/netfilter/ebtables.c

@@ -1406,6 +1406,9 @@ static int do_ebt_set_ctl(struct sock *sk,
 {
 {
 	int ret;
 	int ret;
 
 
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
 	switch(cmd) {
 	switch(cmd) {
 	case EBT_SO_SET_ENTRIES:
 	case EBT_SO_SET_ENTRIES:
 		ret = do_replace(sock_net(sk), user, len);
 		ret = do_replace(sock_net(sk), user, len);
@@ -1425,6 +1428,9 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 	struct ebt_replace tmp;
 	struct ebt_replace tmp;
 	struct ebt_table *t;
 	struct ebt_table *t;
 
 
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
 	if (copy_from_user(&tmp, user, sizeof(tmp)))
 	if (copy_from_user(&tmp, user, sizeof(tmp)))
 		return -EFAULT;
 		return -EFAULT;
 
 

+ 4 - 0
net/core/sock.c

@@ -1205,6 +1205,10 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
 
 
 		if (newsk->sk_prot->sockets_allocated)
 		if (newsk->sk_prot->sockets_allocated)
 			percpu_counter_inc(newsk->sk_prot->sockets_allocated);
 			percpu_counter_inc(newsk->sk_prot->sockets_allocated);
+
+		if (sock_flag(newsk, SOCK_TIMESTAMP) ||
+		    sock_flag(newsk, SOCK_TIMESTAMPING_RX_SOFTWARE))
+			net_enable_timestamp();
 	}
 	}
 out:
 out:
 	return newsk;
 	return newsk;

+ 1 - 1
net/ipv4/ip_output.c

@@ -254,7 +254,7 @@ int ip_mc_output(struct sk_buff *skb)
 	 */
 	 */
 
 
 	if (rt->rt_flags&RTCF_MULTICAST) {
 	if (rt->rt_flags&RTCF_MULTICAST) {
-		if ((!sk || inet_sk(sk)->mc_loop)
+		if (sk_mc_loop(sk)
 #ifdef CONFIG_IP_MROUTE
 #ifdef CONFIG_IP_MROUTE
 		/* Small optimization: do not loopback not local frames,
 		/* Small optimization: do not loopback not local frames,
 		   which returned after forwarding; they will be  dropped
 		   which returned after forwarding; they will be  dropped

+ 1 - 2
net/ipv6/ip6_output.c

@@ -121,10 +121,9 @@ static int ip6_output2(struct sk_buff *skb)
 	skb->dev = dev;
 	skb->dev = dev;
 
 
 	if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {
 	if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {
-		struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL;
 		struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
 		struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
 
 
-		if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) &&
+		if (!(dev->flags & IFF_LOOPBACK) && sk_mc_loop(skb->sk) &&
 		    ((mroute6_socket(dev_net(dev)) &&
 		    ((mroute6_socket(dev_net(dev)) &&
 		     !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) ||
 		     !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) ||
 		     ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr,
 		     ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr,

+ 2 - 1
net/netfilter/ipvs/Kconfig

@@ -112,7 +112,8 @@ config	IP_VS_RR
 	  module, choose M here. If unsure, say N.
 	  module, choose M here. If unsure, say N.
  
  
 config	IP_VS_WRR
 config	IP_VS_WRR
-        tristate "weighted round-robin scheduling" 
+	tristate "weighted round-robin scheduling"
+	select GCD
 	---help---
 	---help---
 	  The weighted robin-robin scheduling algorithm directs network
 	  The weighted robin-robin scheduling algorithm directs network
 	  connections to different real servers based on server weights
 	  connections to different real servers based on server weights

+ 13 - 1
net/netfilter/ipvs/ip_vs_ctl.c

@@ -2077,6 +2077,10 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
 	if (!capable(CAP_NET_ADMIN))
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 		return -EPERM;
 
 
+	if (cmd < IP_VS_BASE_CTL || cmd > IP_VS_SO_SET_MAX)
+		return -EINVAL;
+	if (len < 0 || len >  MAX_ARG_LEN)
+		return -EINVAL;
 	if (len != set_arglen[SET_CMDID(cmd)]) {
 	if (len != set_arglen[SET_CMDID(cmd)]) {
 		pr_err("set_ctl: len %u != %u\n",
 		pr_err("set_ctl: len %u != %u\n",
 		       len, set_arglen[SET_CMDID(cmd)]);
 		       len, set_arglen[SET_CMDID(cmd)]);
@@ -2352,17 +2356,25 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 {
 {
 	unsigned char arg[128];
 	unsigned char arg[128];
 	int ret = 0;
 	int ret = 0;
+	unsigned int copylen;
 
 
 	if (!capable(CAP_NET_ADMIN))
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 		return -EPERM;
 
 
+	if (cmd < IP_VS_BASE_CTL || cmd > IP_VS_SO_GET_MAX)
+		return -EINVAL;
+
 	if (*len < get_arglen[GET_CMDID(cmd)]) {
 	if (*len < get_arglen[GET_CMDID(cmd)]) {
 		pr_err("get_ctl: len %u < %u\n",
 		pr_err("get_ctl: len %u < %u\n",
 		       *len, get_arglen[GET_CMDID(cmd)]);
 		       *len, get_arglen[GET_CMDID(cmd)]);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	if (copy_from_user(arg, user, get_arglen[GET_CMDID(cmd)]) != 0)
+	copylen = get_arglen[GET_CMDID(cmd)];
+	if (copylen > 128)
+		return -EINVAL;
+
+	if (copy_from_user(arg, user, copylen) != 0)
 		return -EFAULT;
 		return -EFAULT;
 
 
 	if (mutex_lock_interruptible(&__ip_vs_mutex))
 	if (mutex_lock_interruptible(&__ip_vs_mutex))

+ 1 - 14
net/netfilter/ipvs/ip_vs_wrr.c

@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/net.h>
 #include <linux/net.h>
+#include <linux/gcd.h>
 
 
 #include <net/ip_vs.h>
 #include <net/ip_vs.h>
 
 
@@ -38,20 +39,6 @@ struct ip_vs_wrr_mark {
 };
 };
 
 
 
 
-/*
- *    Get the gcd of server weights
- */
-static int gcd(int a, int b)
-{
-	int c;
-
-	while ((c = a % b)) {
-		a = b;
-		b = c;
-	}
-	return b;
-}
-
 static int ip_vs_wrr_gcd_weight(struct ip_vs_service *svc)
 static int ip_vs_wrr_gcd_weight(struct ip_vs_service *svc)
 {
 {
 	struct ip_vs_dest *dest;
 	struct ip_vs_dest *dest;

+ 9 - 9
net/netfilter/nf_conntrack_ftp.c

@@ -323,24 +323,24 @@ static void update_nl_seq(struct nf_conn *ct, u32 nl_seq,
 			  struct nf_ct_ftp_master *info, int dir,
 			  struct nf_ct_ftp_master *info, int dir,
 			  struct sk_buff *skb)
 			  struct sk_buff *skb)
 {
 {
-	unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
+	unsigned int i, oldest;
 
 
 	/* Look for oldest: if we find exact match, we're done. */
 	/* Look for oldest: if we find exact match, we're done. */
 	for (i = 0; i < info->seq_aft_nl_num[dir]; i++) {
 	for (i = 0; i < info->seq_aft_nl_num[dir]; i++) {
 		if (info->seq_aft_nl[dir][i] == nl_seq)
 		if (info->seq_aft_nl[dir][i] == nl_seq)
 			return;
 			return;
-
-		if (oldest == info->seq_aft_nl_num[dir] ||
-		    before(info->seq_aft_nl[dir][i],
-			   info->seq_aft_nl[dir][oldest]))
-			oldest = i;
 	}
 	}
 
 
 	if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
 	if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
 		info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
 		info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
-	} else if (oldest != NUM_SEQ_TO_REMEMBER &&
-		   after(nl_seq, info->seq_aft_nl[dir][oldest])) {
-		info->seq_aft_nl[dir][oldest] = nl_seq;
+	} else {
+		if (before(info->seq_aft_nl[dir][0], info->seq_aft_nl[dir][1]))
+			oldest = 0;
+		else
+			oldest = 1;
+
+		if (after(nl_seq, info->seq_aft_nl[dir][oldest]))
+			info->seq_aft_nl[dir][oldest] = nl_seq;
 	}
 	}
 }
 }
 
 

+ 14 - 5
net/packet/af_packet.c

@@ -1021,8 +1021,20 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 
 
 		status = TP_STATUS_SEND_REQUEST;
 		status = TP_STATUS_SEND_REQUEST;
 		err = dev_queue_xmit(skb);
 		err = dev_queue_xmit(skb);
-		if (unlikely(err > 0 && (err = net_xmit_errno(err)) != 0))
-			goto out_xmit;
+		if (unlikely(err > 0)) {
+			err = net_xmit_errno(err);
+			if (err && __packet_get_status(po, ph) ==
+				   TP_STATUS_AVAILABLE) {
+				/* skb was destructed already */
+				skb = NULL;
+				goto out_status;
+			}
+			/*
+			 * skb was dropped but not destructed yet;
+			 * let's treat it like congestion or err < 0
+			 */
+			err = 0;
+		}
 		packet_increment_head(&po->tx_ring);
 		packet_increment_head(&po->tx_ring);
 		len_sum += tp_len;
 		len_sum += tp_len;
 	} while (likely((ph != NULL) ||
 	} while (likely((ph != NULL) ||
@@ -1033,9 +1045,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 	err = len_sum;
 	err = len_sum;
 	goto out_put;
 	goto out_put;
 
 
-out_xmit:
-	skb->destructor = sock_wfree;
-	atomic_dec(&po->tx_ring.pending);
 out_status:
 out_status:
 	__packet_set_status(po, ph, status);
 	__packet_set_status(po, ph, status);
 	kfree_skb(skb);
 	kfree_skb(skb);

+ 1 - 1
net/rose/rose_loopback.c

@@ -75,7 +75,7 @@ static void rose_loopback_timer(unsigned long param)
 		lci_i     = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
 		lci_i     = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
 		frametype = skb->data[2];
 		frametype = skb->data[2];
 		dest      = (rose_address *)(skb->data + 4);
 		dest      = (rose_address *)(skb->data + 4);
-		lci_o     = 0xFFF - lci_i;
+		lci_o     = ROSE_DEFAULT_MAXVC + 1 - lci_i;
 
 
 		skb_reset_transport_header(skb);
 		skb_reset_transport_header(skb);
 
 

+ 1 - 2
net/sctp/socket.c

@@ -2087,8 +2087,7 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
 	if (copy_from_user(&sp->autoclose, optval, optlen))
 	if (copy_from_user(&sp->autoclose, optval, optlen))
 		return -EFAULT;
 		return -EFAULT;
 	/* make sure it won't exceed MAX_SCHEDULE_TIMEOUT */
 	/* make sure it won't exceed MAX_SCHEDULE_TIMEOUT */
-	if (sp->autoclose > (MAX_SCHEDULE_TIMEOUT / HZ) )
-		sp->autoclose = (__u32)(MAX_SCHEDULE_TIMEOUT / HZ) ;
+	sp->autoclose = min_t(long, sp->autoclose, MAX_SCHEDULE_TIMEOUT / HZ);
 
 
 	return 0;
 	return 0;
 }
 }