diff options
59 files changed, 526 insertions, 313 deletions
diff --git a/Documentation/networking/3c509.txt b/Documentation/networking/3c509.txt index 0643e3b..3c45d5d 100644 --- a/Documentation/networking/3c509.txt +++ b/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 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 -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 @@ -77,6 +77,8 @@ operation. 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 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///// 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; it must always be explicitly enabled via one of these code in order to be activated. + +The transceiver type can be changed using 'ethtool'. (4a) Interpretation of error messages and common problems diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index a6624ad..1a1420d 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/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, 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 */ mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0); return; diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index c5721cb..cc9ed86 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -663,7 +663,7 @@ static int lance_open( struct net_device *dev ) while (--i > 0) if (DREG & CSR0_IDON) 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", dev->name, i, DREG )); DREG = CSR0_STOP; diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index c0451d7..ec52529 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -1959,12 +1959,15 @@ static int atl2_get_eeprom(struct net_device *netdev, return -ENOMEM; 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), eeprom->len); +free: kfree(eeprom_buff); return ret_val; diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 9c5a153..1a72ca0 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -990,7 +990,7 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) goto error_tx_buf; } priv->spi_rx_buf = kmalloc(SPI_TRANSFER_BUF_LEN, GFP_KERNEL); - if (!priv->spi_tx_buf) { + if (!priv->spi_rx_buf) { ret = -ENOMEM; goto error_rx_buf; } diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index af93216..0e79cef 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -1325,8 +1325,7 @@ net_open(struct net_device *dev) write_irq(dev, lp->chip_type, dev->irq); ret = request_irq(dev->irq, net_interrupt, 0, dev->name, dev); 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; } } diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 34e0310..33c4fe2 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -2711,6 +2711,8 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) SET_ETHTOOL_OPS(ndev, ðtool_ops); netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT); + clk_enable(emac_clk); + /* register the network device */ SET_NETDEV_DEV(ndev, &pdev->dev); rc = register_netdev(ndev); @@ -2720,7 +2722,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) goto netdev_reg_err; } - clk_enable(emac_clk); /* MII/Phy intialisation, mdio bus registration */ emac_mii = mdiobus_alloc(); @@ -2760,6 +2761,7 @@ mdiobus_quit: netdev_reg_err: mdio_alloc_err: + clk_disable(emac_clk); no_irq_res: res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, res->end - res->start + 1); diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index b979464..02d67d0 100644 --- a/drivers/net/e1000e/82571.c +++ b/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. */ mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) ? true : false; + /* Adaptive IFS supported */ + mac->adaptive_ifs = true; /* check for link */ switch (hw->phy.media_type) { diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index 3028f23..e2aa3b7 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/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. */ mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) ? true : false; + /* Adaptive IFS not supported */ + mac->adaptive_ifs = false; /* check for link */ switch (hw->phy.media_type) { diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 2784cf4..eccf29b 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -818,6 +818,7 @@ struct e1000_mac_info { u8 forced_speed_duplex; + bool adaptive_ifs; bool arc_subsystem_valid; bool autoneg; bool autoneg_failed; diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 9b09246..ad08cf3 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -454,6 +454,8 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) mac->rar_entry_count--; /* Set if manageability features are enabled. */ mac->arc_subsystem_valid = true; + /* Adaptive IFS supported */ + mac->adaptive_ifs = true; /* LED operations */ switch (mac->type) { diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index a86c175..2fa9b36 100644 --- a/drivers/net/e1000e/lib.c +++ b/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) { u32 i; + u8 mac_addr[ETH_ALEN] = {0}; /* Setup the receive address */ 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 */ 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 |= 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; + if (!mac->adaptive_ifs) { + e_dbg("Not in Adaptive IFS mode!\n"); + goto out; + } + mac->current_ifs_val = 0; mac->ifs_min_val = IFS_MIN; mac->ifs_max_val = IFS_MAX; @@ -1617,6 +1628,8 @@ void e1000e_reset_adaptive(struct e1000_hw *hw) mac->in_ifs_mode = false; ew32(AIT, 0); +out: + return; } /** @@ -1630,6 +1643,11 @@ void e1000e_update_adaptive(struct e1000_hw *hw) { 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->tx_packet_delta > MIN_NUM_XMITS) { mac->in_ifs_mode = true; @@ -1650,6 +1668,8 @@ void e1000e_update_adaptive(struct e1000_hw *hw) 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; u8 i, len; + hw->mac.tx_pkt_filtering = true; + /* No manageability, no filtering */ if (!e1000e_check_mng_mode(hw)) { 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. */ ret_val = e1000_mng_enable_host_if(hw); - if (ret_val != 0) { + if (ret_val) { hw->mac.tx_pkt_filtering = false; - return ret_val; + goto out; } /* 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)) { hw->mac.tx_pkt_filtering = true; - return 1; + goto out; } /* Cookie area is valid, make the final check for filtering. */ if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) { 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; } /** diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 762b697..c45965a 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -3315,24 +3315,24 @@ void e1000e_update_stats(struct e1000_adapter *adapter) if ((hw->phy.type == e1000_phy_82578) || (hw->phy.type == e1000_phy_82577)) { 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_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_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_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_LOWER, &phy_data); - adapter->stats.dc += phy_data; + if (!e1e_rphy(hw, HV_DC_LOWER, &phy_data)) + adapter->stats.dc += phy_data; } else { adapter->stats.scc += er32(SCC); adapter->stats.ecol += er32(ECOL); @@ -3360,8 +3360,8 @@ void e1000e_update_stats(struct e1000_adapter *adapter) if ((hw->phy.type == e1000_phy_82578) || (hw->phy.type == e1000_phy_82577)) { 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 { 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) || (hw->phy.type == e1000_phy_82577)) { 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 { if ((hw->mac.type != e1000_82574) && (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_restore_state(pdev); + pci_save_state(pdev); e1000e_disable_l1aspm(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 { pci_set_master(pdev); pci_restore_state(pdev); + pci_save_state(pdev); pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index 25fabb3..d5160ed 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -46,6 +46,11 @@ #include "gianfar.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, * 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) { - 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 *tbi; + struct fsl_pq_mdio_priv *priv; struct fsl_pq_mdio __iomem *regs = NULL; void __iomem *map; u32 __iomem *tbipa; @@ -274,14 +282,19 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, u64 addr = 0, size = 0; int err = 0; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + new_bus = mdiobus_alloc(); if (NULL == new_bus) - return -ENOMEM; + goto err_free_priv; new_bus->name = "Freescale PowerQUICC MII Bus", new_bus->read = &fsl_pq_mdio_read, new_bus->write = &fsl_pq_mdio_write, new_bus->reset = &fsl_pq_mdio_reset, + new_bus->priv = priv; fsl_pq_mdio_bus_name(new_bus->id, np); /* Set the PHY base address */ @@ -291,6 +304,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, err = -ENOMEM; goto err_free_bus; } + priv->map = map; if (of_device_is_compatible(np, "fsl,gianfar-mdio") || 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")) map -= offsetof(struct fsl_pq_mdio, miimcfg); regs = map; - - new_bus->priv = (void __force *)regs; + priv->regs = regs; 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: kfree(new_bus->irq); err_unmap_regs: - iounmap(regs); + iounmap(priv->map); err_free_bus: kfree(new_bus); - +err_free_priv: + kfree(priv); return err; } @@ -404,14 +418,16 @@ static int fsl_pq_mdio_remove(struct of_device *ofdev) { struct device *device = &ofdev->dev; struct mii_bus *bus = dev_get_drvdata(device); + struct fsl_pq_mdio_priv *priv = bus->priv; mdiobus_unregister(bus); dev_set_drvdata(device, NULL); - iounmap(fsl_pq_mdio_get_regs(bus)); + iounmap(priv->map); bus->priv = NULL; mdiobus_free(bus); + kfree(priv); return 0; } diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index ae5f11c..bdadf3e 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/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; struct bpqdev *bpq; + struct net_device *orig_dev; int size; /* @@ -282,8 +283,9 @@ static netdev_tx_t bpq_xmit(struct sk_buff *skb, struct net_device *dev) bpq = netdev_priv(dev); + orig_dev = dev; if ((dev = bpq_get_ether_dev(dev)) == NULL) { - dev->stats.tx_dropped++; + orig_dev->stats.tx_dropped++; kfree_skb(skb); return NETDEV_TX_OK; } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 1a2ea62..2ad754c 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/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 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; txoff = IXGBE_TFCS_TXOFF0; - } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + break; + case ixgbe_mac_82599EB: tc = 0; txoff = IXGBE_TFCS_TXOFF; if (dcb_i == 8) { @@ -284,6 +286,9 @@ static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter, tc += (reg_idx - 96) >> 4; } } + break; + default: + tc = 0; } txoff <<= tc; } diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 336e7c7..a8522bd 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -134,7 +134,7 @@ static int temac_dma_bd_init(struct net_device *ndev) struct sk_buff *skb; 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. */ /* returns a virtual addres and a physical address. */ lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 1405a17..af67af5 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -656,6 +656,7 @@ static int rxq_refill(struct rx_queue *rxq, int budget) struct sk_buff *skb; int rx; struct rx_desc *rx_desc; + int size; skb = __skb_dequeue(&mp->rx_recycle); if (skb == NULL) @@ -678,10 +679,11 @@ static int rxq_refill(struct rx_queue *rxq, int budget) rx_desc = rxq->rx_desc_area + rx; + size = skb->end - skb->data; rx_desc->buf_ptr = dma_map_single(mp->dev->dev.parent, - skb->data, mp->skb_size, + skb->data, size, DMA_FROM_DEVICE); - rx_desc->buf_size = mp->skb_size; + rx_desc->buf_size = size; rxq->rx_skb[rx] = skb; wmb(); rx_desc->cmd_sts = BUFFER_OWNED_BY_DMA | RX_ENABLE_INTERRUPT; diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 76cd1f3..9bc5bd1d 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -53,8 +53,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #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 _major(v) (((v) >> 24) & 0xff) diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index ddd704a..542f408 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/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_REGS_COUNT 42 +#define NETXEN_NIC_REGS_COUNT 30 #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32)) #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; } -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 netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { 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); + regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | (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) { 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 = (val >> port*8) & 0xff; return (val == XG_LINK_UP) ? 0 : 1; } - return -EIO; } static int diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 2e364fe..85e28e6 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/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 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) @@ -691,6 +690,9 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) struct list_head *head; nx_mac_list_t *cur; + if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) + return; + list_splice_tail_init(&adapter->mac_list, &del_list); nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 02f8d4b..64cff68 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -184,6 +184,8 @@ skip_rds: tx_ring = adapter->tx_ring; vfree(tx_ring->cmd_buf_arr); + kfree(tx_ring); + adapter->tx_ring = NULL; } 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) 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++) { diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 6cae26a..9f9d608 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/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)) { first_boot |= 0x4; 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 */ @@ -1898,12 +1898,8 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) linkup = (val == XG_LINK_UP_P3); } else { 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); diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 8ce58c4..2aed2b3 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -2844,7 +2844,7 @@ static int tcam_wait_bit(struct niu *np, u64 bit) break; udelay(1); } - if (limit < 0) + if (limit <= 0) return -ENODEV; return 0; diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 8a5ae3b..12e3233 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -1402,7 +1402,6 @@ static void BuildLAF(int *ladrf, int *adr) for (i = 0; i < 8; i++) printk(KERN_CONT " %02X", ladrf[i]); printk(KERN_CONT "\n"); - } #endif } /* BuildLAF */ diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 92ed3fb..776cad2 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/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_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.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("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.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/DP83903.cis"); MODULE_FIRMWARE("cis/LA-PCM.cis"); -MODULE_FIRMWARE("PE520.cis"); +MODULE_FIRMWARE("cis/PE520.cis"); MODULE_FIRMWARE("cis/NE2K.cis"); MODULE_FIRMWARE("cis/PE-200.cis"); MODULE_FIRMWARE("cis/tamarack.cis"); diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index c13cf64..33c4b12 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -331,8 +331,8 @@ static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) bool clk125en = true; /* 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) return; diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index bd4e8d7..e17b702 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/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)); } +#ifdef CONFIG_PM + static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) { struct device_driver *drv = phydev->dev.driver; @@ -295,34 +297,88 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) 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_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)) return 0; + 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_device *phydev = to_phy_device(dev); + int ret; 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 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 = { .name = "mdio_bus", .match = mdio_bus_match, - .suspend = mdio_bus_suspend, - .resume = mdio_bus_resume, + .pm = MDIO_BUS_PM_OPS, }; EXPORT_SYMBOL(mdio_bus_type); diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index b10fedd..8212b2b 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -378,6 +378,20 @@ void phy_disconnect(struct phy_device *phydev) } 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 * @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 * we have certain key parameters * (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); diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 20a7174..1c25709 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -1293,7 +1293,7 @@ static void rr_dump(struct net_device *dev) printk("Error code 0x%x\n", readl(®s->Fail1)); - index = (((readl(®s->EvtPrd) >> 8) & 0xff ) - 1) % EVT_RING_ENTRIES; + index = (((readl(®s->EvtPrd) >> 8) & 0xff) - 1) % TX_RING_ENTRIES; cons = rrpriv->dirty_tx; printk("TX ring index %i, TX consumer %i\n", index, cons); diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index ca62850..7402b85 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -110,7 +110,7 @@ static void sh_eth_reset(struct net_device *ndev) mdelay(1); cnt--; } - if (cnt < 0) + if (cnt == 0) printk(KERN_ERR "Device reset fail\n"); /* Table Init */ diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 2d28d58..37f486b 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1844,7 +1844,8 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) sky2->tx_cons = idx; 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); } diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig index 1cc8cf4..516713f 100644 --- a/drivers/net/tulip/Kconfig +++ b/drivers/net/tulip/Kconfig @@ -101,6 +101,10 @@ config TULIP_NAPI_HW_MITIGATION If in doubt, say Y. +config TULIP_DM910X + def_bool y + depends on TULIP && SPARC + config DE4X5 tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA" depends on PCI || EISA diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index ad63621..6f44ebf 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -92,6 +92,10 @@ #include <asm/uaccess.h> #include <asm/irq.h> +#ifdef CONFIG_TULIP_DM910X +#include <linux/of.h> +#endif + /* Board/System/Debug information/definition ---------------- */ #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++) 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 */ dev = alloc_etherdev(sizeof(*db)); if (dev == NULL) diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 0fa3140..595777d 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/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 }, /* DM910X */ +#ifdef CONFIG_TULIP_DM910X { "Davicom DM9102/DM9102A", 128, 0x0001ebef, HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI, tulip_timer, tulip_media_task }, +#else + { NULL }, +#endif /* RS7112 */ { "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 }, { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 }, { 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, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, +#endif { 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, { 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; } } +#endif /* * Looks for early PCI chipsets where people report hangs diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 41ad2f3..96bdc0b 100644 --- a/drivers/net/ucc_geth.c +++ b/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)) return 0; + netif_device_detach(ndev); napi_disable(&ugeth->napi); /* @@ -3665,7 +3666,7 @@ static int ucc_geth_resume(struct of_device *ofdev) phy_start(ugeth->phydev); napi_enable(&ugeth->napi); - netif_start_queue(ndev); + netif_device_attach(ndev); return 0; } diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index a007e2a..ef1fbeb 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h @@ -838,13 +838,13 @@ struct ucc_geth_hardware_statistics { using the maximum is easier */ #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_RX_STATISTICS_ALIGNMENT 4 /* This is a guess */ #define UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT 64 #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_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 4 /* This +#define UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 8 /* This is a guess */ @@ -899,16 +899,17 @@ struct ucc_geth_hardware_statistics { #define UCC_GETH_UTFS_INIT 512 /* Tx virtual FIFO size */ #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) */ #define UCC_GETH_URFS_GIGA_INIT 4096/*2048*/ /* Rx virtual FIFO size */ #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_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 */ -#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 set */ diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index f78f090..6895f15 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -286,6 +286,7 @@ struct hso_device { u8 usb_gone; struct work_struct async_get_intf; struct work_struct async_put_intf; + struct work_struct reset_device; struct usb_device *usb; struct usb_interface *interface; @@ -332,7 +333,8 @@ static void hso_kick_transmit(struct hso_serial *serial); /* Helper functions */ static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int, 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, int type, int dir); 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_get_activity(struct hso_device *hso_dev); static void tiocmget_intr_callback(struct urb *urb); +static void reset_device(struct work_struct *data); /*****************************************************************************/ /* Helping functions */ /*****************************************************************************/ @@ -461,10 +464,17 @@ static const struct usb_device_id hso_ids[] = { {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */ {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */ {USB_DEVICE(0x0af0, 0x7701)}, + {USB_DEVICE(0x0af0, 0x7706)}, {USB_DEVICE(0x0af0, 0x7801)}, {USB_DEVICE(0x0af0, 0x7901)}, + {USB_DEVICE(0x0af0, 0x7A01)}, + {USB_DEVICE(0x0af0, 0x7A05)}, {USB_DEVICE(0x0af0, 0x8200)}, {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, 0xd055)}, {USB_DEVICE(0x0af0, 0xd155)}, @@ -473,6 +483,8 @@ static const struct usb_device_id hso_ids[] = { {USB_DEVICE(0x0af0, 0xd157)}, {USB_DEVICE(0x0af0, 0xd257)}, {USB_DEVICE(0x0af0, 0xd357)}, + {USB_DEVICE(0x0af0, 0xd058)}, + {USB_DEVICE(0x0af0, 0xc100)}, {} }; 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); } -/* 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; @@ -685,10 +697,20 @@ static void log_usb_status(int status, const char *function) case -EMSGSIZE: explanation = "internal error"; break; + case -EILSEQ: + case -EPROTO: + case -ETIME: + case -ETIMEDOUT: + explanation = "protocol error"; + if (hso_dev) + schedule_work(&hso_dev->reset_device); + break; default: explanation = "unknown status"; break; } + + /* log a meaningful explanation of an USB 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 * anyhow */ if (status) - log_usb_status(status, __func__); + handle_usb_error(status, __func__, 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); if (result) { 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++; netif_start_queue(net); } else { @@ -998,7 +1020,7 @@ static void read_bulk_callback(struct urb *urb) /* is al ok? (Filip: Who's Al ?) */ if (status) { - log_usb_status(status, __func__); + handle_usb_error(status, __func__, odev->parent); return; } @@ -1019,7 +1041,8 @@ static void read_bulk_callback(struct urb *urb) if (odev->parent->port_spec & HSO_INFO_CRC_BUG) { u32 rest; 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)) && !memcmp(((u8 *) urb->transfer_buffer) + 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); if (result) 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); } @@ -1207,7 +1230,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) D1("serial == NULL"); return; } else if (status) { - log_usb_status(status, __func__); + handle_usb_error(status, __func__, serial->parent); return; } @@ -1225,7 +1248,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; rest = urb->actual_length % - serial->in_endp->wMaxPacketSize; + le16_to_cpu(serial->in_endp->wMaxPacketSize); if (((rest == 5) || (rest == 6)) && !memcmp(((u8 *) urb->transfer_buffer) + urb->actual_length - 4, crc_check, 4)) { @@ -1513,7 +1536,7 @@ static void tiocmget_intr_callback(struct urb *urb) if (!serial) return; if (status) { - log_usb_status(status, __func__); + handle_usb_error(status, __func__, serial->parent); return; } tiocmget = serial->tiocmget; @@ -1700,6 +1723,10 @@ static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, D1("no tty structures"); return -EINVAL; } + + if ((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM) + return -EINVAL; + if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; 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); if (result) { 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); return result; } @@ -1888,7 +1915,7 @@ static void intr_callback(struct urb *urb) /* status check */ if (status) { - log_usb_status(status, __func__); + handle_usb_error(status, __func__, NULL); return; } D4("\n--- Got intr callback 0x%02X ---", status); @@ -1905,18 +1932,18 @@ static void intr_callback(struct urb *urb) if (serial != NULL) { D1("Pending read interrupt on port %d\n", i); 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 * port i */ - if (!serial->rx_urb_filled[0]) { + if (!serial->rx_urb_filled[0]) { serial->rx_state = RX_SENT; hso_mux_serial_read(serial); } else serial->rx_state = RX_PENDING; - } 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); } @@ -1958,7 +1985,7 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) tty = tty_kref_get(serial->tty); spin_unlock(&serial->serial_lock); if (status) { - log_usb_status(status, __func__); + handle_usb_error(status, __func__, serial->parent); tty_kref_put(tty); return; } @@ -2014,7 +2041,7 @@ static void ctrl_callback(struct urb *urb) tty = tty_kref_get(serial->tty); spin_unlock(&serial->serial_lock); if (status) { - log_usb_status(status, __func__); + handle_usb_error(status, __func__, serial->parent); tty_kref_put(tty); 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 = kzalloc(serial->tx_data_length, GFP_KERNEL); if (!serial->tx_data) { - dev_err(dev, "%s - Out of memory", __func__); + dev_err(dev, "%s - Out of memory\n", __func__); goto exit; } serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL); if (!serial->tx_buffer) { - dev_err(dev, "%s - Out of memory", __func__); + dev_err(dev, "%s - Out of memory\n", __func__); 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_put_intf, async_put_intf); + INIT_WORK(&hso_dev->reset_device, reset_device); 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); 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; } - 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) { - dev_err(&interface->dev, "Could not allocate intr buf?"); + dev_err(&interface->dev, "Could not allocate intr buf?\n"); goto exit; } @@ -3132,6 +3161,26 @@ out: 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) { 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, shared_int->intr_endp->bEndpointAddress & 0x7F), shared_int->shared_intr_buf, - shared_int->intr_endp->wMaxPacketSize, + 1, intr_callback, shared_int, shared_int->intr_endp->bInterval); result = usb_submit_urb(shared_int->shared_intr_urb, gfp); 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); return result; diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index f14d225..fd19db0 100644 --- a/drivers/net/usb/rtl8150.c +++ b/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); } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); - if (i < MII_TIMEOUT) { + if (i <= MII_TIMEOUT) { get_registers(dev, PHYDAT, 2, data); *reg = data[0] | (data[1] << 8); 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); } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); - if (i < MII_TIMEOUT) + if (i <= MII_TIMEOUT) return 0; else return 1; diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 4ceb441..c93f58f 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -2237,8 +2237,6 @@ static int velocity_open(struct net_device *dev) /* Ensure chip is running */ pci_set_power_state(vptr->pdev, PCI_D0); - velocity_give_many_rx_descs(vptr); - velocity_init_registers(vptr, VELOCITY_INIT_COLD); ret = request_irq(vptr->pdev->irq, velocity_intr, IRQF_SHARED, @@ -2250,6 +2248,8 @@ static int velocity_open(struct net_device *dev) goto out; } + velocity_give_many_rx_descs(vptr); + mac_enable_int(vptr->mac_regs); netif_start_queue(dev); napi_enable(&vptr->napi); @@ -2339,10 +2339,10 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu) dev->mtu = new_mtu; - velocity_give_many_rx_descs(vptr); - velocity_init_registers(vptr, VELOCITY_INIT_COLD); + velocity_give_many_rx_descs(vptr); + mac_enable_int(vptr->mac_regs); netif_start_queue(dev); diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 0fdfd58..b9685e8 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/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, 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++; return -EIO; } diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index 3c77bfe..147bb1a 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c @@ -3398,7 +3398,7 @@ claw_init(void) goto out_err; } 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; if (ret) goto register_err; diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index fc413f0..0ee7239 100644 --- a/drivers/serial/serial_cs.c +++ b/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, 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", "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_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 */ @@ -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_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_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",0x19ca78af,0x71d98e83), 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_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 = { .owner = THIS_MODULE, .drv = { diff --git a/firmware/Makefile b/firmware/Makefile index 6d5c3ab..1c00d05 100644 --- a/firmware/Makefile +++ b/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_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.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_3C574) += cis/3CCFEM556.cis fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis \ diff --git a/firmware/WHENCE b/firmware/WHENCE index 34b5d0a..ac174fe 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -601,6 +601,7 @@ File: cis/LA-PCM.cis cis/NE2K.cis cis/tamarack.cis cis/PE-200.cis + cis/PE520.cis Licence: GPL diff --git a/firmware/cis/PE520.cis.ihex b/firmware/cis/PE520.cis.ihex new file mode 100644 index 0000000..97a745b --- /dev/null +++ b/firmware/cis/PE520.cis.ihex @@ -0,0 +1,9 @@ +:1000000001030000FF152304014B544900504535FE +:10001000323020504C55530050434D434941204508 +:10002000746865726E65740000FF20046101100041 +:10003000210206001A050101D00F0B1B09C101198D +:0A00400001556530FFFF1400FF00BA +:00000001FF +# +# Replacement CIS for PE520 ethernet card +# diff --git a/include/linux/phy.h b/include/linux/phy.h index b1368b8..7968def 100644 --- a/include/linux/phy.h +++ b/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_clear_interrupt(struct phy_device *phydev); 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, u32 flags, phy_interface_t interface); struct phy_device * phy_attach(struct net_device *dev, diff --git a/include/net/ip.h b/include/net/ip.h index 85108cf..d9a0e74 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -326,6 +326,22 @@ static __inline__ void inet_reset_saddr(struct sock *sk) #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); /* diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index bd1c654..0b7f262 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -1406,6 +1406,9 @@ static int do_ebt_set_ctl(struct sock *sk, { int ret; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + switch(cmd) { case EBT_SO_SET_ENTRIES: 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_table *t; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (copy_from_user(&tmp, user, sizeof(tmp))) return -EFAULT; diff --git a/net/core/sock.c b/net/core/sock.c index 76ff58d..e1f6f22 100644 --- a/net/core/sock.c +++ b/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) 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: return newsk; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index e34013a..3451799 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -254,7 +254,7 @@ int ip_mc_output(struct sk_buff *skb) */ if (rt->rt_flags&RTCF_MULTICAST) { - if ((!sk || inet_sk(sk)->mc_loop) + if (sk_mc_loop(sk) #ifdef CONFIG_IP_MROUTE /* Small optimization: do not loopback not local frames, which returned after forwarding; they will be dropped diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index cd48801a..eb6d097 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -121,10 +121,9 @@ static int ip6_output2(struct sk_buff *skb) skb->dev = dev; 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)); - if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && + if (!(dev->flags & IFF_LOOPBACK) && sk_mc_loop(skb->sk) && ((mroute6_socket(dev_net(dev)) && !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) || ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr, diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig index 79a6980..f2d7623 100644 --- a/net/netfilter/ipvs/Kconfig +++ b/net/netfilter/ipvs/Kconfig @@ -112,7 +112,8 @@ config IP_VS_RR module, choose M here. If unsure, say N. config IP_VS_WRR - tristate "weighted round-robin scheduling" + tristate "weighted round-robin scheduling" + select GCD ---help--- The weighted robin-robin scheduling algorithm directs network connections to different real servers based on server weights diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 6bde12d..c37ac2d 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/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)) 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)]) { pr_err("set_ctl: len %u != %u\n", 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]; int ret = 0; + unsigned int copylen; if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (cmd < IP_VS_BASE_CTL || cmd > IP_VS_SO_GET_MAX) + return -EINVAL; + if (*len < get_arglen[GET_CMDID(cmd)]) { pr_err("get_ctl: len %u < %u\n", *len, get_arglen[GET_CMDID(cmd)]); 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; if (mutex_lock_interruptible(&__ip_vs_mutex)) diff --git a/net/netfilter/ipvs/ip_vs_wrr.c b/net/netfilter/ipvs/ip_vs_wrr.c index 6182e8e..3c115fc 100644 --- a/net/netfilter/ipvs/ip_vs_wrr.c +++ b/net/netfilter/ipvs/ip_vs_wrr.c @@ -24,6 +24,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/net.h> +#include <linux/gcd.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) { struct ip_vs_dest *dest; diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index 38ea7ef..f0732aa 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/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 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. */ for (i = 0; i < info->seq_aft_nl_num[dir]; i++) { if (info->seq_aft_nl[dir][i] == nl_seq) 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) { 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; } } diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index e0516a2..f126d18 100644 --- a/net/packet/af_packet.c +++ b/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; 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); len_sum += tp_len; } while (likely((ph != NULL) || @@ -1033,9 +1045,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) err = len_sum; goto out_put; -out_xmit: - skb->destructor = sock_wfree; - atomic_dec(&po->tx_ring.pending); out_status: __packet_set_status(po, ph, status); kfree_skb(skb); diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c index 114df6e..968e8ba 100644 --- a/net/rose/rose_loopback.c +++ b/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); frametype = skb->data[2]; dest = (rose_address *)(skb->data + 4); - lci_o = 0xFFF - lci_i; + lci_o = ROSE_DEFAULT_MAXVC + 1 - lci_i; skb_reset_transport_header(skb); diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 89ab66e..67fdac9 100644 --- a/net/sctp/socket.c +++ b/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)) return -EFAULT; /* 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; } |