diff options
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 186 |
1 files changed, 66 insertions, 120 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 8e6d618b5305..57d3293c65bd 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -3174,7 +3174,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) } skb_checksum_none_assert(skb); - if (bp->rx_csum && + if ((bp->dev->features & NETIF_F_RXCSUM) && (status & (L2_FHDR_STATUS_TCP_SEGMENT | L2_FHDR_STATUS_UDP_DATAGRAM))) { @@ -6696,17 +6696,16 @@ bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) if (bp->autoneg & AUTONEG_SPEED) { cmd->autoneg = AUTONEG_ENABLE; - } - else { + } else { cmd->autoneg = AUTONEG_DISABLE; } if (netif_carrier_ok(dev)) { - cmd->speed = bp->line_speed; + ethtool_cmd_speed_set(cmd, bp->line_speed); cmd->duplex = bp->duplex; } else { - cmd->speed = -1; + ethtool_cmd_speed_set(cmd, -1); cmd->duplex = -1; } spin_unlock_bh(&bp->phy_lock); @@ -6758,21 +6757,21 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) advertising |= ADVERTISED_Autoneg; } else { + u32 speed = ethtool_cmd_speed(cmd); if (cmd->port == PORT_FIBRE) { - if ((cmd->speed != SPEED_1000 && - cmd->speed != SPEED_2500) || + if ((speed != SPEED_1000 && + speed != SPEED_2500) || (cmd->duplex != DUPLEX_FULL)) goto err_out_unlock; - if (cmd->speed == SPEED_2500 && + if (speed == SPEED_2500 && !(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE)) goto err_out_unlock; - } - else if (cmd->speed == SPEED_1000 || cmd->speed == SPEED_2500) + } else if (speed == SPEED_1000 || speed == SPEED_2500) goto err_out_unlock; autoneg &= ~AUTONEG_SPEED; - req_line_speed = cmd->speed; + req_line_speed = speed; req_duplex = cmd->duplex; advertising = 0; } @@ -7189,38 +7188,6 @@ bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) return 0; } -static u32 -bnx2_get_rx_csum(struct net_device *dev) -{ - struct bnx2 *bp = netdev_priv(dev); - - return bp->rx_csum; -} - -static int -bnx2_set_rx_csum(struct net_device *dev, u32 data) -{ - struct bnx2 *bp = netdev_priv(dev); - - bp->rx_csum = data; - return 0; -} - -static int -bnx2_set_tso(struct net_device *dev, u32 data) -{ - struct bnx2 *bp = netdev_priv(dev); - - if (data) { - dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; - if (CHIP_NUM(bp) == CHIP_NUM_5709) - dev->features |= NETIF_F_TSO6; - } else - dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_TSO_ECN); - return 0; -} - static struct { char string[ETH_GSTRING_LEN]; } bnx2_stats_str_arr[] = { @@ -7495,82 +7462,74 @@ bnx2_get_ethtool_stats(struct net_device *dev, } static int -bnx2_phys_id(struct net_device *dev, u32 data) +bnx2_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state) { struct bnx2 *bp = netdev_priv(dev); - int i; - u32 save; - bnx2_set_power_state(bp, PCI_D0); + switch (state) { + case ETHTOOL_ID_ACTIVE: + bnx2_set_power_state(bp, PCI_D0); + + bp->leds_save = REG_RD(bp, BNX2_MISC_CFG); + REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC); + return 1; /* cycle on/off once per second */ + + case ETHTOOL_ID_ON: + REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE | + BNX2_EMAC_LED_1000MB_OVERRIDE | + BNX2_EMAC_LED_100MB_OVERRIDE | + BNX2_EMAC_LED_10MB_OVERRIDE | + BNX2_EMAC_LED_TRAFFIC_OVERRIDE | + BNX2_EMAC_LED_TRAFFIC); + break; - if (data == 0) - data = 2; + case ETHTOOL_ID_OFF: + REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE); + break; - save = REG_RD(bp, BNX2_MISC_CFG); - REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC); + case ETHTOOL_ID_INACTIVE: + REG_WR(bp, BNX2_EMAC_LED, 0); + REG_WR(bp, BNX2_MISC_CFG, bp->leds_save); - for (i = 0; i < (data * 2); i++) { - if ((i % 2) == 0) { - REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE); - } - else { - REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE | - BNX2_EMAC_LED_1000MB_OVERRIDE | - BNX2_EMAC_LED_100MB_OVERRIDE | - BNX2_EMAC_LED_10MB_OVERRIDE | - BNX2_EMAC_LED_TRAFFIC_OVERRIDE | - BNX2_EMAC_LED_TRAFFIC); - } - msleep_interruptible(500); - if (signal_pending(current)) - break; + if (!netif_running(dev)) + bnx2_set_power_state(bp, PCI_D3hot); + break; } - REG_WR(bp, BNX2_EMAC_LED, 0); - REG_WR(bp, BNX2_MISC_CFG, save); - - if (!netif_running(dev)) - bnx2_set_power_state(bp, PCI_D3hot); return 0; } -static int -bnx2_set_tx_csum(struct net_device *dev, u32 data) +static u32 +bnx2_fix_features(struct net_device *dev, u32 features) { struct bnx2 *bp = netdev_priv(dev); - if (CHIP_NUM(bp) == CHIP_NUM_5709) - return ethtool_op_set_tx_ipv6_csum(dev, data); - else - return ethtool_op_set_tx_csum(dev, data); + if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)) + features |= NETIF_F_HW_VLAN_RX; + + return features; } static int -bnx2_set_flags(struct net_device *dev, u32 data) +bnx2_set_features(struct net_device *dev, u32 features) { struct bnx2 *bp = netdev_priv(dev); - int rc; - - if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) && - !(data & ETH_FLAG_RXVLAN)) - return -EINVAL; /* TSO with VLAN tag won't work with current firmware */ - if (!(data & ETH_FLAG_TXVLAN)) - return -EINVAL; - - rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH | ETH_FLAG_RXVLAN | - ETH_FLAG_TXVLAN); - if (rc) - return rc; + if (features & NETIF_F_HW_VLAN_TX) + dev->vlan_features |= (dev->hw_features & NETIF_F_ALL_TSO); + else + dev->vlan_features &= ~NETIF_F_ALL_TSO; - if ((!!(data & ETH_FLAG_RXVLAN) != + if ((!!(features & NETIF_F_HW_VLAN_RX) != !!(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) && netif_running(dev)) { bnx2_netif_stop(bp, false); + dev->features = features; bnx2_set_rx_mode(dev); bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1); bnx2_netif_start(bp, false); + return 1; } return 0; @@ -7595,18 +7554,11 @@ static const struct ethtool_ops bnx2_ethtool_ops = { .set_ringparam = bnx2_set_ringparam, .get_pauseparam = bnx2_get_pauseparam, .set_pauseparam = bnx2_set_pauseparam, - .get_rx_csum = bnx2_get_rx_csum, - .set_rx_csum = bnx2_set_rx_csum, - .set_tx_csum = bnx2_set_tx_csum, - .set_sg = ethtool_op_set_sg, - .set_tso = bnx2_set_tso, .self_test = bnx2_self_test, .get_strings = bnx2_get_strings, - .phys_id = bnx2_phys_id, + .set_phys_id = bnx2_set_phys_id, .get_ethtool_stats = bnx2_get_ethtool_stats, .get_sset_count = bnx2_get_sset_count, - .set_flags = bnx2_set_flags, - .get_flags = ethtool_op_get_flags, }; /* Called with rtnl_lock */ @@ -8118,8 +8070,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->tx_ring_size = MAX_TX_DESC_CNT; bnx2_set_rx_ring_size(bp, 255); - bp->rx_csum = 1; - bp->tx_quick_cons_trip_int = 2; bp->tx_quick_cons_trip = 20; bp->tx_ticks_int = 18; @@ -8311,17 +8261,14 @@ static const struct net_device_ops bnx2_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = bnx2_change_mac_addr, .ndo_change_mtu = bnx2_change_mtu, + .ndo_fix_features = bnx2_fix_features, + .ndo_set_features = bnx2_set_features, .ndo_tx_timeout = bnx2_tx_timeout, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = poll_bnx2, #endif }; -static inline void vlan_features_add(struct net_device *dev, u32 flags) -{ - dev->vlan_features |= flags; -} - static int __devinit bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -8361,20 +8308,17 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) memcpy(dev->dev_addr, bp->mac_addr, 6); memcpy(dev->perm_addr, bp->mac_addr, 6); - dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_GRO | - NETIF_F_RXHASH; - vlan_features_add(dev, NETIF_F_IP_CSUM | NETIF_F_SG); - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - dev->features |= NETIF_F_IPV6_CSUM; - vlan_features_add(dev, NETIF_F_IPV6_CSUM); - } - dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; - vlan_features_add(dev, NETIF_F_TSO | NETIF_F_TSO_ECN); - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - dev->features |= NETIF_F_TSO6; - vlan_features_add(dev, NETIF_F_TSO6); - } + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | + NETIF_F_TSO | NETIF_F_TSO_ECN | + NETIF_F_RXHASH | NETIF_F_RXCSUM; + + if (CHIP_NUM(bp) == CHIP_NUM_5709) + dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6; + + dev->vlan_features = dev->hw_features; + dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + dev->features |= dev->hw_features; + if ((rc = register_netdev(dev))) { dev_err(&pdev->dev, "Cannot register net device\n"); goto error; @@ -8413,6 +8357,8 @@ bnx2_remove_one(struct pci_dev *pdev) unregister_netdev(dev); + del_timer_sync(&bp->timer); + if (bp->mips_firmware) release_firmware(bp->mips_firmware); if (bp->rv2p_firmware) |