diff options
Diffstat (limited to 'drivers/net/bnx2.c')
| -rw-r--r-- | drivers/net/bnx2.c | 184 | 
1 files changed, 64 insertions, 120 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index d8383a9af9a..57d3293c65b 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); -	if (data == 0) -		data = 2; +		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 */ -	save = REG_RD(bp, BNX2_MISC_CFG); -	REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC); +	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; -	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; -	} -	REG_WR(bp, BNX2_EMAC_LED, 0); -	REG_WR(bp, BNX2_MISC_CFG, save); +	case ETHTOOL_ID_OFF: +		REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE); +		break; -	if (!netif_running(dev)) -		bnx2_set_power_state(bp, PCI_D3hot); +	case ETHTOOL_ID_INACTIVE: +		REG_WR(bp, BNX2_EMAC_LED, 0); +		REG_WR(bp, BNX2_MISC_CFG, bp->leds_save); + +		if (!netif_running(dev)) +			bnx2_set_power_state(bp, PCI_D3hot); +		break; +	}  	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;  |