lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 26 Jun 2018 17:06:07 -0700
From:   Paul Burton <paul.burton@...s.com>
To:     netdev@...r.kernel.org
Cc:     "David S . Miller" <davem@...emloft.net>,
        Andrew Lunn <andrew@...n.ch>, paul.burton@...s.com
Subject: [PATCH v7 06/11] net: pch_gbe: Only enable MAC when PHY link is active

When using a PHY connected via RGMII, as the pch_gbe driver presumes is
the case, the RX clock is provided by the PHY to the MAC. Various PHYs,
including both the AR8031 used by the Minnowboard & the RTL8211E used by
the MIPS Boston development board, will stop generating the RX clock
when the ethernet link is down (eg. the ethernet cable is unplugged).

Various pieces of functionality in the EG20T MAC, ranging from basics
like completing a MAC reset to programming MAC addresses, rely upon the
RX clock being provided. When the clock is not provided these pieces of
functionality simply never complete, and the busy bits that indicate
they're in progress remain set indefinitely.

The pch_gbe driver currently requires that the RX clock is always
provided, and attempts to enforce this by disabling the hibernation
feature of the AR8031 PHY to keep it generating the RX clock. This patch
moves us away from this model by only configuring the MAC when the PHY
indicates that the ethernet link is up. When the link is up we should be
able to safely expect that the RX clock is being provided, and therefore
safely reset & configure the MAC.

Signed-off-by: Paul Burton <paul.burton@...s.com>
Cc: Andrew Lunn <andrew@...n.ch>
Cc: David S. Miller <davem@...emloft.net>
Cc: netdev@...r.kernel.org
---

Changes in v7: New patch

 .../ethernet/oki-semi/pch_gbe/pch_gbe_main.c  | 44 +++++++++----------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index eb290c1edce0..721ce29b6467 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -1837,7 +1837,6 @@ static int pch_gbe_request_irq(struct pch_gbe_adapter *adapter)
 int pch_gbe_up(struct pch_gbe_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
 	struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
 	int err = -EINVAL;
 
@@ -1847,14 +1846,6 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter)
 		goto out;
 	}
 
-	/* hardware has been reset, we need to reload some things */
-	pch_gbe_set_multi(netdev);
-
-	pch_gbe_setup_tctl(adapter);
-	pch_gbe_configure_tx(adapter);
-	pch_gbe_setup_rctl(adapter);
-	pch_gbe_configure_rx(adapter);
-
 	err = pch_gbe_request_irq(adapter);
 	if (err) {
 		netdev_err(netdev,
@@ -1867,18 +1858,9 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter)
 			   "Error: can't bring device up - alloc rx buffers pool failed\n");
 		goto freeirq;
 	}
-	pch_gbe_alloc_tx_buffers(adapter, tx_ring);
-	pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count);
 	adapter->tx_queue_len = netdev->tx_queue_len;
-	pch_gbe_enable_dma_rx(&adapter->hw);
-	pch_gbe_enable_mac_rx(&adapter->hw);
 
 	mod_timer(&adapter->watchdog_timer, jiffies);
-
-	napi_enable(&adapter->napi);
-	pch_gbe_irq_enable(adapter);
-	netif_start_queue(adapter->netdev);
-
 	return 0;
 
 freeirq:
@@ -1930,6 +1912,8 @@ static void pch_gbe_watchdog(struct timer_list *t)
 {
 	struct pch_gbe_adapter *adapter = from_timer(adapter, t,
 						     watchdog_timer);
+	struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
+	struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
 	struct net_device *netdev = adapter->netdev;
 	struct pch_gbe_hw *hw = &adapter->hw;
 
@@ -1950,12 +1934,32 @@ static void pch_gbe_watchdog(struct timer_list *t)
 		}
 		hw->mac.link_speed = ethtool_cmd_speed(&cmd);
 		hw->mac.link_duplex = cmd.duplex;
+
+		pch_gbe_reset(adapter);
+
 		/* Set the RGMII control. */
 		pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed,
 				       hw->mac.link_duplex);
 		/* Set the communication mode */
 		pch_gbe_set_mode(adapter, hw->mac.link_speed,
 				 hw->mac.link_duplex);
+
+		pch_gbe_set_multi(netdev);
+		pch_gbe_setup_tctl(adapter);
+		pch_gbe_configure_tx(adapter);
+		pch_gbe_setup_rctl(adapter);
+		pch_gbe_configure_rx(adapter);
+
+		pch_gbe_alloc_tx_buffers(adapter, tx_ring);
+		pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count);
+
+		pch_gbe_enable_dma_rx(&adapter->hw);
+		pch_gbe_enable_mac_rx(&adapter->hw);
+
+		napi_enable(&adapter->napi);
+		pch_gbe_irq_enable(adapter);
+		netif_start_queue(adapter->netdev);
+
 		netdev_dbg(netdev,
 			   "Link is Up %d Mbps %s-Duplex\n",
 			   hw->mac.link_speed,
@@ -2568,7 +2572,6 @@ static int pch_gbe_probe(struct pci_dev *pdev,
 			  (ETH_HLEN + ETH_FCS_LEN);
 
 	pch_gbe_mac_load_mac_addr(&adapter->hw);
-	pch_gbe_mac_reset_hw(&adapter->hw);
 
 	/* setup the private structure */
 	ret = pch_gbe_sw_init(adapter);
@@ -2610,9 +2613,6 @@ static int pch_gbe_probe(struct pci_dev *pdev,
 	adapter->wake_up_evt = PCH_GBE_WL_INIT_SETTING;
 	dev_info(&pdev->dev, "MAC address : %pM\n", netdev->dev_addr);
 
-	/* reset the hardware with the new settings */
-	pch_gbe_reset(adapter);
-
 	ret = register_netdev(netdev);
 	if (ret)
 		goto err_free_adapter;
-- 
2.18.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ