diff options
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_main.c')
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 31 | 
1 files changed, 26 insertions, 5 deletions
| diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 8c6b7c1651e5..55e89b3838f1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1097,6 +1097,7 @@ static int init_dma_desc_rings(struct net_device *dev, gfp_t flags)  	priv->dirty_tx = 0;  	priv->cur_tx = 0; +	netdev_reset_queue(priv->dev);  	stmmac_clear_descriptors(priv); @@ -1287,7 +1288,7 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)  		 *    that needs to not insert csum in the TDES.  		 */  		priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE); -		tc = SF_DMA_MODE; +		priv->xstats.threshold = SF_DMA_MODE;  	} else  		priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);  } @@ -1300,6 +1301,7 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)  static void stmmac_tx_clean(struct stmmac_priv *priv)  {  	unsigned int txsize = priv->dma_tx_size; +	unsigned int bytes_compl = 0, pkts_compl = 0;  	spin_lock(&priv->tx_lock); @@ -1356,6 +1358,8 @@ static void stmmac_tx_clean(struct stmmac_priv *priv)  		priv->hw->mode->clean_desc3(priv, p);  		if (likely(skb != NULL)) { +			pkts_compl++; +			bytes_compl += skb->len;  			dev_consume_skb_any(skb);  			priv->tx_skbuff[entry] = NULL;  		} @@ -1364,6 +1368,9 @@ static void stmmac_tx_clean(struct stmmac_priv *priv)  		priv->dirty_tx++;  	} + +	netdev_completed_queue(priv->dev, pkts_compl, bytes_compl); +  	if (unlikely(netif_queue_stopped(priv->dev) &&  		     stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {  		netif_tx_lock(priv->dev); @@ -1418,6 +1425,7 @@ static void stmmac_tx_err(struct stmmac_priv *priv)  						     (i == txsize - 1));  	priv->dirty_tx = 0;  	priv->cur_tx = 0; +	netdev_reset_queue(priv->dev);  	priv->hw->dma->start_tx(priv->ioaddr);  	priv->dev->stats.tx_errors++; @@ -1444,9 +1452,14 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)  	}  	if (unlikely(status & tx_hard_error_bump_tc)) {  		/* Try to bump up the dma threshold on this failure */ -		if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) { +		if (unlikely(priv->xstats.threshold != SF_DMA_MODE) && +		    (tc <= 256)) {  			tc += 64; -			priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); +			if (priv->plat->force_thresh_dma_mode) +				priv->hw->dma->dma_mode(priv->ioaddr, tc, tc); +			else +				priv->hw->dma->dma_mode(priv->ioaddr, tc, +					SF_DMA_MODE);  			priv->xstats.threshold = tc;  		}  	} else if (unlikely(status == tx_hard_error)) @@ -2050,6 +2063,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)  	if (!priv->hwts_tx_en)  		skb_tx_timestamp(skb); +	netdev_sent_queue(dev, skb->len);  	priv->hw->dma->enable_dma_transmission(priv->ioaddr);  	spin_unlock(&priv->tx_lock); @@ -2742,7 +2756,11 @@ static int stmmac_hw_init(struct stmmac_priv *priv)  		priv->plat->enh_desc = priv->dma_cap.enh_desc;  		priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; -		priv->plat->tx_coe = priv->dma_cap.tx_coe; +		/* TXCOE doesn't work in thresh DMA mode */ +		if (priv->plat->force_thresh_dma_mode) +			priv->plat->tx_coe = 0; +		else +			priv->plat->tx_coe = priv->dma_cap.tx_coe;  		if (priv->dma_cap.rx_coe_type2)  			priv->plat->rx_coe = STMMAC_RX_COE_TYPE2; @@ -2778,6 +2796,9 @@ static int stmmac_hw_init(struct stmmac_priv *priv)   * @addr: iobase memory address   * Description: this is the main probe function used to   * call the alloc_etherdev, allocate the priv structure. + * Return: + * on success the new private structure is returned, otherwise the error + * pointer.   */  struct stmmac_priv *stmmac_dvr_probe(struct device *device,  				     struct plat_stmmacenet_data *plat_dat, @@ -2789,7 +2810,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,  	ndev = alloc_etherdev(sizeof(struct stmmac_priv));  	if (!ndev) -		return NULL; +		return ERR_PTR(-ENOMEM);  	SET_NETDEV_DEV(ndev, device); |