diff options
Diffstat (limited to 'drivers/net/ethernet/calxeda/xgmac.c')
| -rw-r--r-- | drivers/net/ethernet/calxeda/xgmac.c | 42 | 
1 files changed, 22 insertions, 20 deletions
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c index 78d6d6b970e..25d6b2a10e4 100644 --- a/drivers/net/ethernet/calxeda/xgmac.c +++ b/drivers/net/ethernet/calxeda/xgmac.c @@ -14,7 +14,6 @@   * this program.  If not, see <http://www.gnu.org/licenses/>.   */  #include <linux/module.h> -#include <linux/init.h>  #include <linux/kernel.h>  #include <linux/circ_buf.h>  #include <linux/interrupt.h> @@ -106,7 +105,6 @@  #define XGMAC_DMA_HW_FEATURE	0x00000f58	/* Enabled Hardware Features */  #define XGMAC_ADDR_AE		0x80000000 -#define XGMAC_MAX_FILTER_ADDR	31  /* PMT Control and Status */  #define XGMAC_PMT_POINTER_RESET	0x80000000 @@ -384,6 +382,7 @@ struct xgmac_priv {  	struct device *device;  	struct napi_struct napi; +	int max_macs;  	struct xgmac_extra_stats xstats;  	spinlock_t stats_lock; @@ -898,7 +897,7 @@ static void xgmac_tx_complete(struct xgmac_priv *priv)  		/* Check tx error on the last segment */  		if (desc_get_tx_ls(p)) {  			desc_get_tx_status(priv, p); -			dev_kfree_skb(skb); +			dev_consume_skb_any(skb);  		}  		priv->tx_skbuff[entry] = NULL; @@ -1060,13 +1059,13 @@ static int xgmac_stop(struct net_device *dev)  {  	struct xgmac_priv *priv = netdev_priv(dev); -	netif_stop_queue(dev); -  	if (readl(priv->base + XGMAC_DMA_INTR_ENA))  		napi_disable(&priv->napi);  	writel(0, priv->base + XGMAC_DMA_INTR_ENA); +	netif_tx_disable(dev); +  	/* Disable the MAC core */  	xgmac_mac_disable(priv->base); @@ -1106,7 +1105,7 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev)  	len = skb_headlen(skb);  	paddr = dma_map_single(priv->device, skb->data, len, DMA_TO_DEVICE);  	if (dma_mapping_error(priv->device, paddr)) { -		dev_kfree_skb(skb); +		dev_kfree_skb_any(skb);  		return NETDEV_TX_OK;  	}  	priv->tx_skbuff[entry] = skb; @@ -1170,7 +1169,7 @@ dma_err:  	desc = first;  	dma_unmap_single(priv->device, desc_get_buf_addr(desc),  			 desc_get_buf_len(desc), DMA_TO_DEVICE); -	dev_kfree_skb(skb); +	dev_kfree_skb_any(skb);  	return NETDEV_TX_OK;  } @@ -1291,14 +1290,12 @@ static void xgmac_set_rx_mode(struct net_device *dev)  	netdev_dbg(priv->dev, "# mcasts %d, # unicast %d\n",  		 netdev_mc_count(dev), netdev_uc_count(dev)); -	if (dev->flags & IFF_PROMISC) { -		writel(XGMAC_FRAME_FILTER_PR, ioaddr + XGMAC_FRAME_FILTER); -		return; -	} +	if (dev->flags & IFF_PROMISC) +		value |= XGMAC_FRAME_FILTER_PR;  	memset(hash_filter, 0, sizeof(hash_filter)); -	if (netdev_uc_count(dev) > XGMAC_MAX_FILTER_ADDR) { +	if (netdev_uc_count(dev) > priv->max_macs) {  		use_hash = true;  		value |= XGMAC_FRAME_FILTER_HUC | XGMAC_FRAME_FILTER_HPF;  	} @@ -1321,7 +1318,7 @@ static void xgmac_set_rx_mode(struct net_device *dev)  		goto out;  	} -	if ((netdev_mc_count(dev) + reg - 1) > XGMAC_MAX_FILTER_ADDR) { +	if ((netdev_mc_count(dev) + reg - 1) > priv->max_macs) {  		use_hash = true;  		value |= XGMAC_FRAME_FILTER_HMC | XGMAC_FRAME_FILTER_HPF;  	} else { @@ -1342,8 +1339,8 @@ static void xgmac_set_rx_mode(struct net_device *dev)  	}  out: -	for (i = reg; i < XGMAC_MAX_FILTER_ADDR; i++) -		xgmac_set_mac_addr(ioaddr, NULL, reg); +	for (i = reg; i <= priv->max_macs; i++) +		xgmac_set_mac_addr(ioaddr, NULL, i);  	for (i = 0; i < XGMAC_NUM_HASH; i++)  		writel(hash_filter[i], ioaddr + XGMAC_HASH(i)); @@ -1372,11 +1369,8 @@ static int xgmac_change_mtu(struct net_device *dev, int new_mtu)  	}  	old_mtu = dev->mtu; -	dev->mtu = new_mtu;  	/* return early if the buffer sizes will not change */ -	if (old_mtu <= ETH_DATA_LEN && new_mtu <= ETH_DATA_LEN) -		return 0;  	if (old_mtu == new_mtu)  		return 0; @@ -1384,8 +1378,9 @@ static int xgmac_change_mtu(struct net_device *dev, int new_mtu)  	if (!netif_running(dev))  		return 0; -	/* Bring the interface down and then back up */ +	/* Bring interface down, change mtu and bring interface back up */  	xgmac_stop(dev); +	dev->mtu = new_mtu;  	return xgmac_open(dev);  } @@ -1742,7 +1737,7 @@ static int xgmac_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, ndev);  	ether_setup(ndev);  	ndev->netdev_ops = &xgmac_netdev_ops; -	SET_ETHTOOL_OPS(ndev, &xgmac_ethtool_ops); +	ndev->ethtool_ops = &xgmac_ethtool_ops;  	spin_lock_init(&priv->stats_lock);  	INIT_WORK(&priv->tx_timeout_work, xgmac_tx_timeout_work); @@ -1761,6 +1756,13 @@ static int xgmac_probe(struct platform_device *pdev)  	uid = readl(priv->base + XGMAC_VERSION);  	netdev_info(ndev, "h/w version is 0x%x\n", uid); +	/* Figure out how many valid mac address filter registers we have */ +	writel(1, priv->base + XGMAC_ADDR_HIGH(31)); +	if (readl(priv->base + XGMAC_ADDR_HIGH(31)) == 1) +		priv->max_macs = 31; +	else +		priv->max_macs = 7; +  	writel(0, priv->base + XGMAC_DMA_INTR_ENA);  	ndev->irq = platform_get_irq(pdev, 0);  	if (ndev->irq == -ENXIO) {  | 
