diff options
Diffstat (limited to 'drivers/net/ethernet/cadence/macb_main.c')
| -rw-r--r-- | drivers/net/ethernet/cadence/macb_main.c | 47 | 
1 files changed, 35 insertions, 12 deletions
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 6e141a8bbf43..29a1199dad14 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -94,8 +94,7 @@ struct sifive_fu540_macb_mgmt {  /* Graceful stop timeouts in us. We should allow up to   * 1 frame time (10 Mbits/s, full-duplex, ignoring collisions)   */ -#define MACB_HALT_TIMEOUT	1230 - +#define MACB_HALT_TIMEOUT	14000  #define MACB_PM_TIMEOUT  100 /* ms */  #define MACB_MDIO_TIMEOUT	1000000 /* in usecs */ @@ -288,6 +287,11 @@ static void macb_set_hwaddr(struct macb *bp)  	top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4)));  	macb_or_gem_writel(bp, SA1T, top); +	if (gem_has_ptp(bp)) { +		gem_writel(bp, RXPTPUNI, bottom); +		gem_writel(bp, TXPTPUNI, bottom); +	} +  	/* Clear unused address register sets */  	macb_or_gem_writel(bp, SA2B, 0);  	macb_or_gem_writel(bp, SA2T, 0); @@ -774,8 +778,12 @@ static void macb_mac_link_up(struct phylink_config *config,  	spin_unlock_irqrestore(&bp->lock, flags); -	/* Enable Rx and Tx */ -	macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(RE) | MACB_BIT(TE)); +	/* Enable Rx and Tx; Enable PTP unicast */ +	ctrl = macb_readl(bp, NCR); +	if (gem_has_ptp(bp)) +		ctrl |= MACB_BIT(PTPUNI); + +	macb_writel(bp, NCR, ctrl | MACB_BIT(RE) | MACB_BIT(TE));  	netif_tx_wake_all_queues(ndev);  } @@ -1064,6 +1072,10 @@ static dma_addr_t macb_get_addr(struct macb *bp, struct macb_dma_desc *desc)  	}  #endif  	addr |= MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, desc->addr)); +#ifdef CONFIG_MACB_USE_HWSTAMP +	if (bp->hw_dma_cap & HW_DMA_CAP_PTP) +		addr &= ~GEM_BIT(DMA_RXVALID); +#endif  	return addr;  } @@ -1071,6 +1083,7 @@ static void macb_tx_error_task(struct work_struct *work)  {  	struct macb_queue	*queue = container_of(work, struct macb_queue,  						      tx_error_task); +	bool			halt_timeout = false;  	struct macb		*bp = queue->bp;  	struct macb_tx_skb	*tx_skb;  	struct macb_dma_desc	*desc; @@ -1098,9 +1111,11 @@ static void macb_tx_error_task(struct work_struct *work)  	 * (in case we have just queued new packets)  	 * macb/gem must be halted to write TBQP register  	 */ -	if (macb_halt_tx(bp)) -		/* Just complain for now, reinitializing TX path can be good */ +	if (macb_halt_tx(bp)) {  		netdev_err(bp->dev, "BUG: halt tx timed out\n"); +		macb_writel(bp, NCR, macb_readl(bp, NCR) & (~MACB_BIT(TE))); +		halt_timeout = true; +	}  	/* Treat frames in TX queue including the ones that caused the error.  	 * Free transmit buffers in upper layer. @@ -1171,6 +1186,9 @@ static void macb_tx_error_task(struct work_struct *work)  	macb_writel(bp, TSR, macb_readl(bp, TSR));  	queue_writel(queue, IER, MACB_TX_INT_FLAGS); +	if (halt_timeout) +		macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE)); +  	/* Now we are ready to start transmission again */  	netif_tx_start_all_queues(bp->dev);  	macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); @@ -2641,8 +2659,12 @@ static u32 gem_mdc_clk_div(struct macb *bp)  		config = GEM_BF(CLK, GEM_CLK_DIV48);  	else if (pclk_hz <= 160000000)  		config = GEM_BF(CLK, GEM_CLK_DIV64); -	else +	else if (pclk_hz <= 240000000)  		config = GEM_BF(CLK, GEM_CLK_DIV96); +	else if (pclk_hz <= 320000000) +		config = GEM_BF(CLK, GEM_CLK_DIV128); +	else +		config = GEM_BF(CLK, GEM_CLK_DIV224);  	return config;  } @@ -3880,17 +3902,17 @@ static void macb_configure_caps(struct macb *bp,  		dcfg = gem_readl(bp, DCFG2);  		if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0)  			bp->caps |= MACB_CAPS_FIFO_MODE; -#ifdef CONFIG_MACB_USE_HWSTAMP  		if (gem_has_ptp(bp)) {  			if (!GEM_BFEXT(TSU, gem_readl(bp, DCFG5)))  				dev_err(&bp->pdev->dev,  					"GEM doesn't support hardware ptp.\n");  			else { +#ifdef CONFIG_MACB_USE_HWSTAMP  				bp->hw_dma_cap |= HW_DMA_CAP_PTP;  				bp->ptp_info = &gem_ptp_info; +#endif  			}  		} -#endif  	}  	dev_dbg(&bp->pdev->dev, "Cadence caps 0x%08x\n", bp->caps); @@ -4844,7 +4866,7 @@ static const struct macb_config mpfs_config = {  static const struct macb_config sama7g5_gem_config = {  	.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_CLK_HW_CHG | -		MACB_CAPS_MIIONRGMII, +		MACB_CAPS_MIIONRGMII | MACB_CAPS_GEM_HAS_PTP,  	.dma_burst_length = 16,  	.clk_init = macb_clk_init,  	.init = macb_init, @@ -4853,7 +4875,8 @@ static const struct macb_config sama7g5_gem_config = {  static const struct macb_config sama7g5_emac_config = {  	.caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | -		MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_MIIONRGMII, +		MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_MIIONRGMII | +		MACB_CAPS_GEM_HAS_PTP,  	.dma_burst_length = 16,  	.clk_init = macb_clk_init,  	.init = macb_init, @@ -4990,7 +5013,7 @@ static int macb_probe(struct platform_device *pdev)  		bp->jumbo_max_len = macb_config->jumbo_max_len;  	bp->wol = 0; -	if (of_get_property(np, "magic-packet", NULL)) +	if (of_property_read_bool(np, "magic-packet"))  		bp->wol |= MACB_WOL_HAS_MAGIC_PACKET;  	device_set_wakeup_capable(&pdev->dev, bp->wol & MACB_WOL_HAS_MAGIC_PACKET);  |