ath79: Make upstream ag71xx driver work
* Fix some bugs in the driver * Add missing clock and reset references in dts * Rename mdio-bus to mdio so the driver find it Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
		 Hauke Mehrtens
					Hauke Mehrtens
				
			
				
					committed by
					
						 Koen Vandeputte
						Koen Vandeputte
					
				
			
			
				
	
			
			
			 Koen Vandeputte
						Koen Vandeputte
					
				
			
						parent
						
							53ab9865c2
						
					
				
				
					commit
					1e95f9b3ea
				
			| @@ -232,6 +232,8 @@ | |||||||
| 	pll-handle = <&pll>; | 	pll-handle = <&pll>; | ||||||
| 	resets = <&rst 9>, <&rst 22>; | 	resets = <&rst 9>, <&rst 22>; | ||||||
| 	reset-names = "mac", "mdio"; | 	reset-names = "mac", "mdio"; | ||||||
|  | 	clocks = <&pll ATH79_CLK_AHB>, <&pll ATH79_CLK_AHB>; | ||||||
|  | 	clock-names = "eth", "mdio"; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| &mdio1 { | &mdio1 { | ||||||
| @@ -272,8 +274,10 @@ | |||||||
| ð1 { | ð1 { | ||||||
| 	compatible = "qca,ar9340-eth", "syscon"; | 	compatible = "qca,ar9340-eth", "syscon"; | ||||||
|  |  | ||||||
| 	resets = <&rst 13>; | 	resets = <&rst 13>, <&rst 23>; | ||||||
| 	reset-names = "mac"; | 	reset-names = "mac", "mdio"; | ||||||
|  | 	clocks = <&pll ATH79_CLK_AHB>, <&pll ATH79_CLK_AHB>; | ||||||
|  | 	clock-names = "eth", "mdio"; | ||||||
| 	phy-mode = "gmii"; | 	phy-mode = "gmii"; | ||||||
|  |  | ||||||
| 	fixed-link { | 	fixed-link { | ||||||
|   | |||||||
| @@ -49,7 +49,7 @@ | |||||||
| 			interrupts = <4>; | 			interrupts = <4>; | ||||||
| 			phy-mode = "mii"; | 			phy-mode = "mii"; | ||||||
|  |  | ||||||
| 			mdio0: mdio-bus { | 			mdio0: mdio { | ||||||
| 				status = "disabled"; | 				status = "disabled"; | ||||||
|  |  | ||||||
| 				compatible = "qca,ath79-mdio"; | 				compatible = "qca,ath79-mdio"; | ||||||
| @@ -72,7 +72,7 @@ | |||||||
| 			interrupts = <5>; | 			interrupts = <5>; | ||||||
| 			phy-mode = "mii"; | 			phy-mode = "mii"; | ||||||
|  |  | ||||||
| 			mdio1: mdio-bus { | 			mdio1: mdio { | ||||||
| 				status = "disabled"; | 				status = "disabled"; | ||||||
|  |  | ||||||
| 				compatible = "qca,ath79-mdio"; | 				compatible = "qca,ath79-mdio"; | ||||||
|   | |||||||
| @@ -0,0 +1,61 @@ | |||||||
|  | From 2cee757eaf5cc6175bc0ac7b0b808794124ec40a Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Hauke Mehrtens <hauke@hauke-m.de> | ||||||
|  | Date: Mon, 17 Feb 2020 23:40:14 +0100 | ||||||
|  | Subject: [PATCH 1/3] ag71xx: Handle allocation errors in ag71xx_rings_init() | ||||||
|  |  | ||||||
|  | Free the allocated resources in ag71xx_rings_init() in case | ||||||
|  | ag71xx_ring_rx_init() returns an error. | ||||||
|  |  | ||||||
|  | This is only a potential problem, I did not ran into this one. | ||||||
|  |  | ||||||
|  | Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> | ||||||
|  | Fixes: d51b6ce441d3 ("net: ethernet: add ag71xx driver") | ||||||
|  | --- | ||||||
|  |  drivers/net/ethernet/atheros/ag71xx.c | 22 ++++++++++++++++++---- | ||||||
|  |  1 file changed, 18 insertions(+), 4 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/ethernet/atheros/ag71xx.c | ||||||
|  | +++ b/drivers/net/ethernet/atheros/ag71xx.c | ||||||
|  | @@ -1133,6 +1133,7 @@ static int ag71xx_rings_init(struct ag71 | ||||||
|  |  	struct ag71xx_ring *tx = &ag->tx_ring; | ||||||
|  |  	struct ag71xx_ring *rx = &ag->rx_ring; | ||||||
|  |  	int ring_size, tx_size; | ||||||
|  | +	int ret; | ||||||
|  |   | ||||||
|  |  	ring_size = BIT(tx->order) + BIT(rx->order); | ||||||
|  |  	tx_size = BIT(tx->order); | ||||||
|  | @@ -1145,9 +1146,8 @@ static int ag71xx_rings_init(struct ag71 | ||||||
|  |  					   ring_size * AG71XX_DESC_SIZE, | ||||||
|  |  					   &tx->descs_dma, GFP_KERNEL); | ||||||
|  |  	if (!tx->descs_cpu) { | ||||||
|  | -		kfree(tx->buf); | ||||||
|  | -		tx->buf = NULL; | ||||||
|  | -		return -ENOMEM; | ||||||
|  | +		ret = -ENOMEM; | ||||||
|  | +		goto err_free_buf; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	rx->buf = &tx->buf[tx_size]; | ||||||
|  | @@ -1155,7 +1155,21 @@ static int ag71xx_rings_init(struct ag71 | ||||||
|  |  	rx->descs_dma = tx->descs_dma + tx_size * AG71XX_DESC_SIZE; | ||||||
|  |   | ||||||
|  |  	ag71xx_ring_tx_init(ag); | ||||||
|  | -	return ag71xx_ring_rx_init(ag); | ||||||
|  | +	ret = ag71xx_ring_rx_init(ag); | ||||||
|  | +	if (ret) | ||||||
|  | +		goto err_free_dma; | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | + | ||||||
|  | +err_free_dma: | ||||||
|  | +	dma_free_coherent(&ag->pdev->dev, ring_size * AG71XX_DESC_SIZE, | ||||||
|  | +			  tx->descs_cpu, tx->descs_dma); | ||||||
|  | +	rx->buf = NULL; | ||||||
|  | +err_free_buf: | ||||||
|  | +	kfree(tx->buf); | ||||||
|  | +	tx->buf = NULL; | ||||||
|  | + | ||||||
|  | +	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void ag71xx_rings_free(struct ag71xx *ag) | ||||||
| @@ -0,0 +1,45 @@ | |||||||
|  | From 2f8c5a68d0030ae5e65fca1bf5ca44929d5b3b06 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Hauke Mehrtens <hauke@hauke-m.de> | ||||||
|  | Date: Mon, 17 Feb 2020 23:50:23 +0100 | ||||||
|  | Subject: [PATCH 2/3] ag71xx: Call ag71xx_hw_disable() in case phy_conenct | ||||||
|  |  fails | ||||||
|  |  | ||||||
|  | When the ag71xx_phy_connect() failed only parts of the actions done | ||||||
|  | previously in this function wrere reverted, because only | ||||||
|  | ag71xx_rings_cleanup() was called. My system crashed the next time | ||||||
|  | open() was called because napi_disable() was not called again and this | ||||||
|  | resulted in two calls to napi_enable(), which is not allowed. | ||||||
|  |  | ||||||
|  | Fix this by disabling the device again. | ||||||
|  |  | ||||||
|  | Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> | ||||||
|  | Fixes: d51b6ce441d3 ("net: ethernet: add ag71xx driver") | ||||||
|  | --- | ||||||
|  |  drivers/net/ethernet/atheros/ag71xx.c | 8 ++++---- | ||||||
|  |  1 file changed, 4 insertions(+), 4 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/ethernet/atheros/ag71xx.c | ||||||
|  | +++ b/drivers/net/ethernet/atheros/ag71xx.c | ||||||
|  | @@ -1263,18 +1263,18 @@ static int ag71xx_open(struct net_device | ||||||
|  |   | ||||||
|  |  	ret = ag71xx_hw_enable(ag); | ||||||
|  |  	if (ret) | ||||||
|  | -		goto err; | ||||||
|  | +		return ret; | ||||||
|  |   | ||||||
|  |  	ret = ag71xx_phy_connect(ag); | ||||||
|  |  	if (ret) | ||||||
|  | -		goto err; | ||||||
|  | +		goto err_hw_disable; | ||||||
|  |   | ||||||
|  |  	phy_start(ndev->phydev); | ||||||
|  |   | ||||||
|  |  	return 0; | ||||||
|  |   | ||||||
|  | -err: | ||||||
|  | -	ag71xx_rings_cleanup(ag); | ||||||
|  | +err_hw_disable: | ||||||
|  | +	ag71xx_hw_disable(ag); | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
| @@ -0,0 +1,69 @@ | |||||||
|  | From d42c6bf2752a46bdf3931bd6e56db419742fbb20 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Hauke Mehrtens <hauke@hauke-m.de> | ||||||
|  | Date: Mon, 17 Feb 2020 23:55:22 +0100 | ||||||
|  | Subject: [PATCH 3/3] ag71xx: Run ag71xx_link_adjust() only when needed | ||||||
|  |  | ||||||
|  | My system printed this line every second: | ||||||
|  |   ag71xx 19000000.eth eth0: Link is Up - 1Gbps/Full - flow control off | ||||||
|  | The function ag71xx_phy_link_adjust() was called by the PHY layer every | ||||||
|  | second even when nothing changed. | ||||||
|  |  | ||||||
|  | With this patch the old status is stored and the real | ||||||
|  | ag71xx_link_adjust() function is only called when when something really | ||||||
|  | changed. This way the update and also this print is only done once any | ||||||
|  | more. | ||||||
|  |  | ||||||
|  | Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> | ||||||
|  | Fixes: d51b6ce441d3 ("net: ethernet: add ag71xx driver") | ||||||
|  | --- | ||||||
|  |  drivers/net/ethernet/atheros/ag71xx.c | 24 +++++++++++++++++++++++- | ||||||
|  |  1 file changed, 23 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/ethernet/atheros/ag71xx.c | ||||||
|  | +++ b/drivers/net/ethernet/atheros/ag71xx.c | ||||||
|  | @@ -307,6 +307,10 @@ struct ag71xx { | ||||||
|  |  	u32 msg_enable; | ||||||
|  |  	const struct ag71xx_dcfg *dcfg; | ||||||
|  |   | ||||||
|  | +	unsigned int		link; | ||||||
|  | +	unsigned int		speed; | ||||||
|  | +	int			duplex; | ||||||
|  | + | ||||||
|  |  	/* From this point onwards we're not looking at per-packet fields. */ | ||||||
|  |  	void __iomem *mac_base; | ||||||
|  |   | ||||||
|  | @@ -854,6 +858,7 @@ static void ag71xx_link_adjust(struct ag | ||||||
|  |   | ||||||
|  |  	if (!phydev->link && update) { | ||||||
|  |  		ag71xx_hw_stop(ag); | ||||||
|  | +		phy_print_status(phydev); | ||||||
|  |  		return; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -907,8 +912,25 @@ static void ag71xx_link_adjust(struct ag | ||||||
|  |  static void ag71xx_phy_link_adjust(struct net_device *ndev) | ||||||
|  |  { | ||||||
|  |  	struct ag71xx *ag = netdev_priv(ndev); | ||||||
|  | +	struct phy_device *phydev = ndev->phydev; | ||||||
|  | +	int status_change = 0; | ||||||
|  | + | ||||||
|  | +	if (phydev->link) { | ||||||
|  | +		if (ag->duplex != phydev->duplex | ||||||
|  | +		    || ag->speed != phydev->speed) { | ||||||
|  | +			status_change = 1; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (phydev->link != ag->link) | ||||||
|  | +		status_change = 1; | ||||||
|  | + | ||||||
|  | +	ag->link = phydev->link; | ||||||
|  | +	ag->duplex = phydev->duplex; | ||||||
|  | +	ag->speed = phydev->speed; | ||||||
|  |   | ||||||
|  | -	ag71xx_link_adjust(ag, true); | ||||||
|  | +	if (status_change) | ||||||
|  | +		ag71xx_link_adjust(ag, true); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static int ag71xx_phy_connect(struct ag71xx *ag) | ||||||
		Reference in New Issue
	
	Block a user