diff options
Diffstat (limited to 'drivers/net/ethernet/rdc')
| -rw-r--r-- | drivers/net/ethernet/rdc/r6040.c | 91 | 
1 files changed, 34 insertions, 57 deletions
diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index 6b541e57c96a..cb29ee24cf1b 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -4,7 +4,7 @@   * Copyright (C) 2004 Sten Wang <[email protected]>   * Copyright (C) 2007   *	Daniel Gimpelevich <[email protected]> - * Copyright (C) 2007-2012 Florian Fainelli <[email protected]> + * Copyright (C) 2007-2012 Florian Fainelli <[email protected]>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License @@ -48,8 +48,8 @@  #include <asm/processor.h>  #define DRV_NAME	"r6040" -#define DRV_VERSION	"0.28" -#define DRV_RELDATE	"07Oct2011" +#define DRV_VERSION	"0.29" +#define DRV_RELDATE	"04Jul2016"  /* Time in jiffies before concluding the transmitter is hung. */  #define TX_TIMEOUT	(6000 * HZ / 1000) @@ -162,7 +162,7 @@  MODULE_AUTHOR("Sten Wang <[email protected]>,"  	"Daniel Gimpelevich <[email protected]>," -	"Florian Fainelli <[email protected]>"); +	"Florian Fainelli <[email protected]>");  MODULE_LICENSE("GPL");  MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver");  MODULE_VERSION(DRV_VERSION " " DRV_RELDATE); @@ -200,7 +200,6 @@ struct r6040_private {  	struct mii_bus *mii_bus;  	struct napi_struct napi;  	void __iomem *base; -	struct phy_device *phydev;  	int old_link;  	int old_duplex;  }; @@ -474,7 +473,7 @@ static void r6040_down(struct net_device *dev)  	iowrite16(adrp[1], ioaddr + MID_0M);  	iowrite16(adrp[2], ioaddr + MID_0H); -	phy_stop(lp->phydev); +	phy_stop(dev->phydev);  }  static int r6040_close(struct net_device *dev) @@ -515,12 +514,10 @@ static int r6040_close(struct net_device *dev)  static int r6040_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)  { -	struct r6040_private *lp = netdev_priv(dev); - -	if (!lp->phydev) +	if (!dev->phydev)  		return -EINVAL; -	return phy_mii_ioctl(lp->phydev, rq, cmd); +	return phy_mii_ioctl(dev->phydev, rq, cmd);  }  static int r6040_rx(struct net_device *dev, int limit) @@ -617,10 +614,15 @@ static void r6040_tx(struct net_device *dev)  		if (descptr->status & DSC_OWNER_MAC)  			break; /* Not complete */  		skb_ptr = descptr->skb_ptr; + +		/* Statistic Counter */ +		dev->stats.tx_packets++; +		dev->stats.tx_bytes += skb_ptr->len; +  		pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf),  			skb_ptr->len, PCI_DMA_TODEVICE);  		/* Free buffer */ -		dev_kfree_skb_irq(skb_ptr); +		dev_kfree_skb(skb_ptr);  		descptr->skb_ptr = NULL;  		/* To next descriptor */  		descptr = descptr->vndescp; @@ -641,12 +643,15 @@ static int r6040_poll(struct napi_struct *napi, int budget)  	void __iomem *ioaddr = priv->base;  	int work_done; +	r6040_tx(dev); +  	work_done = r6040_rx(dev, budget);  	if (work_done < budget) { -		napi_complete(napi); -		/* Enable RX interrupt */ -		iowrite16(ioread16(ioaddr + MIER) | RX_INTS, ioaddr + MIER); +		napi_complete_done(napi, work_done); +		/* Enable RX/TX interrupt */ +		iowrite16(ioread16(ioaddr + MIER) | RX_INTS | TX_INTS, +			  ioaddr + MIER);  	}  	return work_done;  } @@ -673,7 +678,7 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)  	}  	/* RX interrupt request */ -	if (status & RX_INTS) { +	if (status & (RX_INTS | TX_INTS)) {  		if (status & RX_NO_DESC) {  			/* RX descriptor unavailable */  			dev->stats.rx_dropped++; @@ -684,15 +689,11 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)  		if (likely(napi_schedule_prep(&lp->napi))) {  			/* Mask off RX interrupt */ -			misr &= ~RX_INTS; -			__napi_schedule(&lp->napi); +			misr &= ~(RX_INTS | TX_INTS); +			__napi_schedule_irqoff(&lp->napi);  		}  	} -	/* TX interrupt request */ -	if (status & TX_INTS) -		r6040_tx(dev); -  	/* Restore RDC MAC interrupt */  	iowrite16(misr, ioaddr + MIER); @@ -732,7 +733,7 @@ static int r6040_up(struct net_device *dev)  	/* Initialize all MAC registers */  	r6040_init_mac_regs(dev); -	phy_start(lp->phydev); +	phy_start(dev->phydev);  	return 0;  } @@ -813,6 +814,9 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,  	void __iomem *ioaddr = lp->base;  	unsigned long flags; +	if (skb_put_padto(skb, ETH_ZLEN) < 0) +		return NETDEV_TX_OK; +  	/* Critical Section */  	spin_lock_irqsave(&lp->lock, flags); @@ -824,17 +828,10 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,  		return NETDEV_TX_BUSY;  	} -	/* Statistic Counter */ -	dev->stats.tx_packets++; -	dev->stats.tx_bytes += skb->len;  	/* Set TX descriptor & Transmit it */  	lp->tx_free_desc--;  	descptr = lp->tx_insert_ptr; -	if (skb->len < ETH_ZLEN) -		descptr->len = ETH_ZLEN; -	else -		descptr->len = skb->len; - +	descptr->len = skb->len;  	descptr->skb_ptr = skb;  	descptr->buf = cpu_to_le32(pci_map_single(lp->pdev,  		skb->data, skb->len, PCI_DMA_TODEVICE)); @@ -843,7 +840,8 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,  	skb_tx_timestamp(skb);  	/* Trigger the MAC to check the TX descriptor */ -	iowrite16(TM2TX, ioaddr + MTPR); +	if (!skb->xmit_more || netif_queue_stopped(dev)) +		iowrite16(TM2TX, ioaddr + MTPR);  	lp->tx_insert_ptr = descptr->vndescp;  	/* If no tx resource, stop */ @@ -957,26 +955,12 @@ static void netdev_get_drvinfo(struct net_device *dev,  	strlcpy(info->bus_info, pci_name(rp->pdev), sizeof(info->bus_info));  } -static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ -	struct r6040_private *rp = netdev_priv(dev); - -	return  phy_ethtool_gset(rp->phydev, cmd); -} - -static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ -	struct r6040_private *rp = netdev_priv(dev); - -	return phy_ethtool_sset(rp->phydev, cmd); -} -  static const struct ethtool_ops netdev_ethtool_ops = {  	.get_drvinfo		= netdev_get_drvinfo, -	.get_settings		= netdev_get_settings, -	.set_settings		= netdev_set_settings,  	.get_link		= ethtool_op_get_link,  	.get_ts_info		= ethtool_op_get_ts_info, +	.get_link_ksettings     = phy_ethtool_get_link_ksettings, +	.set_link_ksettings     = phy_ethtool_set_link_ksettings,  };  static const struct net_device_ops r6040_netdev_ops = { @@ -998,7 +982,7 @@ static const struct net_device_ops r6040_netdev_ops = {  static void r6040_adjust_link(struct net_device *dev)  {  	struct r6040_private *lp = netdev_priv(dev); -	struct phy_device *phydev = lp->phydev; +	struct phy_device *phydev = dev->phydev;  	int status_changed = 0;  	void __iomem *ioaddr = lp->base; @@ -1018,14 +1002,8 @@ static void r6040_adjust_link(struct net_device *dev)  		lp->old_duplex = phydev->duplex;  	} -	if (status_changed) { -		pr_info("%s: link %s", dev->name, phydev->link ? -			"UP" : "DOWN"); -		if (phydev->link) -			pr_cont(" - %d/%s", phydev->speed, -			DUPLEX_FULL == phydev->duplex ? "full" : "half"); -		pr_cont("\n"); -	} +	if (status_changed) +		phy_print_status(phydev);  }  static int r6040_mii_probe(struct net_device *dev) @@ -1057,7 +1035,6 @@ static int r6040_mii_probe(struct net_device *dev)  				| SUPPORTED_TP);  	phydev->advertising = phydev->supported; -	lp->phydev = phydev;  	lp->old_link = 0;  	lp->old_duplex = -1;  |