diff options
Diffstat (limited to 'drivers/net/ethernet/marvell/sky2.c')
| -rw-r--r-- | drivers/net/ethernet/marvell/sky2.c | 46 | 
1 files changed, 30 insertions, 16 deletions
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index e09a8c6f853..69693384b58 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -44,6 +44,8 @@  #include <linux/prefetch.h>  #include <linux/debugfs.h>  #include <linux/mii.h> +#include <linux/of_device.h> +#include <linux/of_net.h>  #include <asm/irq.h> @@ -2000,7 +2002,7 @@ mapping_unwind:  mapping_error:  	if (net_ratelimit())  		dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name); -	dev_kfree_skb(skb); +	dev_kfree_skb_any(skb);  	return NETDEV_TX_OK;  } @@ -2495,7 +2497,7 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2,  		skb_copy_from_linear_data(re->skb, skb->data, length);  		skb->ip_summed = re->skb->ip_summed;  		skb->csum = re->skb->csum; -		skb->rxhash = re->skb->rxhash; +		skb_copy_hash(skb, re->skb);  		skb->vlan_proto = re->skb->vlan_proto;  		skb->vlan_tci = re->skb->vlan_tci; @@ -2503,7 +2505,7 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2,  					       length, PCI_DMA_FROMDEVICE);  		re->skb->vlan_proto = 0;  		re->skb->vlan_tci = 0; -		re->skb->rxhash = 0; +		skb_clear_hash(re->skb);  		re->skb->ip_summed = CHECKSUM_NONE;  		skb_put(skb, length);  	} @@ -2723,7 +2725,7 @@ static void sky2_rx_hash(struct sky2_port *sky2, u32 status)  	struct sk_buff *skb;  	skb = sky2->rx_ring[sky2->rx_next].skb; -	skb->rxhash = le32_to_cpu(status); +	skb_set_hash(skb, le32_to_cpu(status), PKT_HASH_TYPE_L3);  }  /* Process status response ring */ @@ -2733,6 +2735,9 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)  	unsigned int total_bytes[2] = { 0 };  	unsigned int total_packets[2] = { 0 }; +	if (to_do <= 0) +		return work_done; +  	rmb();  	do {  		struct sky2_port *sky2; @@ -3906,19 +3911,19 @@ static struct rtnl_link_stats64 *sky2_get_stats(struct net_device *dev,  	u64 _bytes, _packets;  	do { -		start = u64_stats_fetch_begin_bh(&sky2->rx_stats.syncp); +		start = u64_stats_fetch_begin_irq(&sky2->rx_stats.syncp);  		_bytes = sky2->rx_stats.bytes;  		_packets = sky2->rx_stats.packets; -	} while (u64_stats_fetch_retry_bh(&sky2->rx_stats.syncp, start)); +	} while (u64_stats_fetch_retry_irq(&sky2->rx_stats.syncp, start));  	stats->rx_packets = _packets;  	stats->rx_bytes = _bytes;  	do { -		start = u64_stats_fetch_begin_bh(&sky2->tx_stats.syncp); +		start = u64_stats_fetch_begin_irq(&sky2->tx_stats.syncp);  		_bytes = sky2->tx_stats.bytes;  		_packets = sky2->tx_stats.packets; -	} while (u64_stats_fetch_retry_bh(&sky2->tx_stats.syncp, start)); +	} while (u64_stats_fetch_retry_irq(&sky2->tx_stats.syncp, start));  	stats->tx_packets = _packets;  	stats->tx_bytes = _bytes; @@ -4748,13 +4753,14 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port,  {  	struct sky2_port *sky2;  	struct net_device *dev = alloc_etherdev(sizeof(*sky2)); +	const void *iap;  	if (!dev)  		return NULL;  	SET_NETDEV_DEV(dev, &hw->pdev->dev);  	dev->irq = hw->pdev->irq; -	SET_ETHTOOL_OPS(dev, &sky2_ethtool_ops); +	dev->ethtool_ops = &sky2_ethtool_ops;  	dev->watchdog_timeo = TX_WATCHDOG;  	dev->netdev_ops = &sky2_netdev_ops[port]; @@ -4763,6 +4769,9 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port,  	sky2->hw = hw;  	sky2->msg_enable = netif_msg_init(debug, default_msg); +	u64_stats_init(&sky2->tx_stats.syncp); +	u64_stats_init(&sky2->rx_stats.syncp); +  	/* Auto speed and flow control */  	sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE;  	if (hw->chip_id != CHIP_ID_YUKON_XL) @@ -4802,8 +4811,16 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port,  	dev->features |= dev->hw_features; -	/* read the mac address */ -	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN); +	/* try to get mac address in the following order: +	 * 1) from device tree data +	 * 2) from internal registers set by bootloader +	 */ +	iap = of_get_mac_address(hw->pdev->dev.of_node); +	if (iap) +		memcpy(dev->dev_addr, iap, ETH_ALEN); +	else +		memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, +			      ETH_ALEN);  	return dev;  } @@ -5017,6 +5034,8 @@ static int sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  		}   	} +	netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT); +  	err = register_netdev(dev);  	if (err) {  		dev_err(&pdev->dev, "cannot register net device\n"); @@ -5025,8 +5044,6 @@ static int sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	netif_carrier_off(dev); -	netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT); -  	sky2_show_addr(dev);  	if (hw->ports > 1) { @@ -5081,7 +5098,6 @@ err_out_free_regions:  err_out_disable:  	pci_disable_device(pdev);  err_out: -	pci_set_drvdata(pdev, NULL);  	return err;  } @@ -5124,8 +5140,6 @@ static void sky2_remove(struct pci_dev *pdev)  	iounmap(hw->regs);  	kfree(hw); - -	pci_set_drvdata(pdev, NULL);  }  static int sky2_suspend(struct device *dev)  | 
