mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/6] staging: et131x: support register dump in ethtool ops
@ 2011-09-25 18:17 Mark Einon
  2011-09-25 18:17 ` [PATCH 2/6] staging: et131x: Add link status to adapter struct Mark Einon
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Mark Einon @ 2011-09-25 18:17 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-kernel, o.hartmann, alan, Mark Einon

Not an exhaustive dump of the et131x registers, used while debugging a specific problem - seems a shame not to keep it around.

Signed-off-by: Mark Einon <mark.einon@gmail.com>
---
 drivers/staging/et131x/et131x_ethtool.c |  138 ++++++++++++++++++++++++++++++-
 1 files changed, 135 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/et131x/et131x_ethtool.c b/drivers/staging/et131x/et131x_ethtool.c
index b92633f..c4555b9 100644
--- a/drivers/staging/et131x/et131x_ethtool.c
+++ b/drivers/staging/et131x/et131x_ethtool.c
@@ -28,6 +28,7 @@
 #include <linux/pci.h>
 
 #include "et131x_adapter.h"
+#include "et1310_phy.h"
 #include "et131x.h"
 
 static int et131x_get_settings(struct net_device *netdev,
@@ -46,6 +47,135 @@ static int et131x_set_settings(struct net_device *netdev,
 	return phy_ethtool_sset(adapter->phydev, cmd);
 }
 
+static int et131x_get_regs_len(struct net_device *netdev)
+{
+#define ET131X_REGS_LEN 256
+	return ET131X_REGS_LEN * sizeof(u32);
+}
+
+static void et131x_get_regs(struct net_device *netdev,
+			    struct ethtool_regs *regs, void *regs_data)
+{
+	struct et131x_adapter *adapter = netdev_priv(netdev);
+	struct address_map __iomem *aregs = adapter->regs;
+	u32 *regs_buff = regs_data;
+	u32 num = 0;
+
+	memset(regs_data, 0, et131x_get_regs_len(netdev));
+
+	regs->version = (1 << 24) | (adapter->pdev->revision << 16) |
+			adapter->pdev->device;
+
+	/* PHY regs */
+	et131x_mii_read(adapter, MII_BMCR, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, MII_BMSR, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, MII_PHYSID1, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, MII_PHYSID2, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, MII_ADVERTISE, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, MII_LPA, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, MII_EXPANSION, (u16 *)&regs_buff[num++]);
+	/* Autoneg next page transmit reg */
+	et131x_mii_read(adapter, 0x07, (u16 *)&regs_buff[num++]);
+	/* Link partner next page reg */
+	et131x_mii_read(adapter, 0x08, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, MII_CTRL1000, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, MII_STAT1000, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, MII_ESTATUS, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, PHY_INDEX_REG, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, PHY_DATA_REG, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG,
+			(u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, PHY_LOOPBACK_CONTROL,
+			(u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, PHY_LOOPBACK_CONTROL+1,
+			(u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, PHY_REGISTER_MGMT_CONTROL,
+			(u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, PHY_CONFIG, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, PHY_PHY_CONTROL, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, PHY_INTERRUPT_MASK, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, PHY_INTERRUPT_STATUS,
+			(u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, PHY_PHY_STATUS, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, PHY_LED_1, (u16 *)&regs_buff[num++]);
+	et131x_mii_read(adapter, PHY_LED_2, (u16 *)&regs_buff[num++]);
+
+	/* Global regs */
+	regs_buff[num++] = readl(&aregs->global.txq_start_addr);
+	regs_buff[num++] = readl(&aregs->global.txq_end_addr);
+	regs_buff[num++] = readl(&aregs->global.rxq_start_addr);
+	regs_buff[num++] = readl(&aregs->global.rxq_end_addr);
+	regs_buff[num++] = readl(&aregs->global.pm_csr);
+	regs_buff[num++] = adapter->stats.interrupt_status;
+	regs_buff[num++] = readl(&aregs->global.int_mask);
+	regs_buff[num++] = readl(&aregs->global.int_alias_clr_en);
+	regs_buff[num++] = readl(&aregs->global.int_status_alias);
+	regs_buff[num++] = readl(&aregs->global.sw_reset);
+	regs_buff[num++] = readl(&aregs->global.slv_timer);
+	regs_buff[num++] = readl(&aregs->global.msi_config);
+	regs_buff[num++] = readl(&aregs->global.loopback);
+	regs_buff[num++] = readl(&aregs->global.watchdog_timer);
+
+	/* TXDMA regs */
+	regs_buff[num++] = readl(&aregs->txdma.csr);
+	regs_buff[num++] = readl(&aregs->txdma.pr_base_hi);
+	regs_buff[num++] = readl(&aregs->txdma.pr_base_lo);
+	regs_buff[num++] = readl(&aregs->txdma.pr_num_des);
+	regs_buff[num++] = readl(&aregs->txdma.txq_wr_addr);
+	regs_buff[num++] = readl(&aregs->txdma.txq_wr_addr_ext);
+	regs_buff[num++] = readl(&aregs->txdma.txq_rd_addr);
+	regs_buff[num++] = readl(&aregs->txdma.dma_wb_base_hi);
+	regs_buff[num++] = readl(&aregs->txdma.dma_wb_base_lo);
+	regs_buff[num++] = readl(&aregs->txdma.service_request);
+	regs_buff[num++] = readl(&aregs->txdma.service_complete);
+	regs_buff[num++] = readl(&aregs->txdma.cache_rd_index);
+	regs_buff[num++] = readl(&aregs->txdma.cache_wr_index);
+	regs_buff[num++] = readl(&aregs->txdma.tx_dma_error);
+	regs_buff[num++] = readl(&aregs->txdma.desc_abort_cnt);
+	regs_buff[num++] = readl(&aregs->txdma.payload_abort_cnt);
+	regs_buff[num++] = readl(&aregs->txdma.writeback_abort_cnt);
+	regs_buff[num++] = readl(&aregs->txdma.desc_timeout_cnt);
+	regs_buff[num++] = readl(&aregs->txdma.payload_timeout_cnt);
+	regs_buff[num++] = readl(&aregs->txdma.writeback_timeout_cnt);
+	regs_buff[num++] = readl(&aregs->txdma.desc_error_cnt);
+	regs_buff[num++] = readl(&aregs->txdma.payload_error_cnt);
+	regs_buff[num++] = readl(&aregs->txdma.writeback_error_cnt);
+	regs_buff[num++] = readl(&aregs->txdma.dropped_tlp_cnt);
+	regs_buff[num++] = readl(&aregs->txdma.new_service_complete);
+	regs_buff[num++] = readl(&aregs->txdma.ethernet_packet_cnt);
+
+	/* RXDMA regs */
+	regs_buff[num++] = readl(&aregs->rxdma.csr);
+	regs_buff[num++] = readl(&aregs->rxdma.dma_wb_base_hi);
+	regs_buff[num++] = readl(&aregs->rxdma.dma_wb_base_lo);
+	regs_buff[num++] = readl(&aregs->rxdma.num_pkt_done);
+	regs_buff[num++] = readl(&aregs->rxdma.max_pkt_time);
+	regs_buff[num++] = readl(&aregs->rxdma.rxq_rd_addr);
+	regs_buff[num++] = readl(&aregs->rxdma.rxq_rd_addr_ext);
+	regs_buff[num++] = readl(&aregs->rxdma.rxq_wr_addr);
+	regs_buff[num++] = readl(&aregs->rxdma.psr_base_hi);
+	regs_buff[num++] = readl(&aregs->rxdma.psr_base_lo);
+	regs_buff[num++] = readl(&aregs->rxdma.psr_num_des);
+	regs_buff[num++] = readl(&aregs->rxdma.psr_avail_offset);
+	regs_buff[num++] = readl(&aregs->rxdma.psr_full_offset);
+	regs_buff[num++] = readl(&aregs->rxdma.psr_access_index);
+	regs_buff[num++] = readl(&aregs->rxdma.psr_min_des);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr0_base_lo);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr0_base_hi);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr0_num_des);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr0_avail_offset);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr0_full_offset);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr0_rd_index);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr0_min_des);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr1_base_lo);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr1_base_hi);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr1_num_des);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr1_avail_offset);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr1_full_offset);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr1_rd_index);
+	regs_buff[num++] = readl(&aregs->rxdma.fbr1_min_des);
+}
+
 #define ET131X_DRVINFO_LEN 32 /* value from ethtool.h */
 static void et131x_get_drvinfo(struct net_device *netdev,
 			       struct ethtool_drvinfo *info)
@@ -58,9 +188,11 @@ static void et131x_get_drvinfo(struct net_device *netdev,
 }
 
 static struct ethtool_ops et131x_ethtool_ops = {
-	.get_settings = et131x_get_settings,
-	.set_settings = et131x_set_settings,
-	.get_drvinfo = et131x_get_drvinfo,
+	.get_settings	= et131x_get_settings,
+	.set_settings	= et131x_set_settings,
+	.get_drvinfo	= et131x_get_drvinfo,
+	.get_regs_len	= et131x_get_regs_len,
+	.get_regs	= et131x_get_regs,
 	.get_link = ethtool_op_get_link,
 };
 
-- 
1.7.6


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/6] staging: et131x: Add link status to adapter struct
  2011-09-25 18:17 [PATCH 1/6] staging: et131x: support register dump in ethtool ops Mark Einon
@ 2011-09-25 18:17 ` Mark Einon
  2011-09-25 18:17 ` [PATCH 3/6] staging: et131x: Remove et131x_check_mii() and move functionality into et131x_adjust_link() Mark Einon
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Mark Einon @ 2011-09-25 18:17 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-kernel, o.hartmann, alan, Mark Einon

This will be used to determine if the link state has changed when the phydev
informs the et131x that a change has occurred (in et131x_adjust_link)

Signed-off-by: Mark Einon <mark.einon@gmail.com>
---
 drivers/staging/et131x/et131x_adapter.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h
index 78f2894..fabc2c5 100644
--- a/drivers/staging/et131x/et131x_adapter.h
+++ b/drivers/staging/et131x/et131x_adapter.h
@@ -147,6 +147,9 @@ struct et131x_adapter {
 	/* Flags that indicate current state of the adapter */
 	u32 flags;
 
+	/* local link state, to determine if a state change has occurred */
+	int link;
+
 	/* Configuration  */
 	u8 rom_addr[ETH_ALEN];
 	u8 addr[ETH_ALEN];
-- 
1.7.6


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/6] staging: et131x: Remove et131x_check_mii() and move functionality into et131x_adjust_link()
  2011-09-25 18:17 [PATCH 1/6] staging: et131x: support register dump in ethtool ops Mark Einon
  2011-09-25 18:17 ` [PATCH 2/6] staging: et131x: Add link status to adapter struct Mark Einon
@ 2011-09-25 18:17 ` Mark Einon
  2011-09-25 18:17 ` [PATCH 4/6] staging: et131x: Create et131x_[dis|en]able_txrx() calls Mark Einon
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Mark Einon @ 2011-09-25 18:17 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-kernel, o.hartmann, alan, Mark Einon

et131x_check_mii() is now only being called from et131x_adjust_link.
Removed this call and associated subroutines, putting the functionality directly into et131x_adjust_link(), in preparation for further simplification.
Changed register checks from bare BMSR checks to use phydev/netif versions, also now uses adapter->link to track link state changes.

Signed-off-by: Mark Einon <mark.einon@gmail.com>
---
 drivers/staging/et131x/et1310_phy.c     |  167 -------------------------------
 drivers/staging/et131x/et131x_initpci.c |  115 ++++++++++++++++++---
 2 files changed, 98 insertions(+), 184 deletions(-)

diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c
index c4bc41d..fc37b18 100644
--- a/drivers/staging/et131x/et1310_phy.c
+++ b/drivers/staging/et131x/et1310_phy.c
@@ -298,68 +298,6 @@ void et1310_phy_power_down(struct et131x_adapter *adapter, bool down)
 	et131x_mii_write(adapter, MII_BMCR, data);
 }
 
-/**
- *	et1310_phy_link_status	-	read link state
- *	@adapter: device to read
- *	@link_status: reported link state
- *	@autoneg: reported autonegotiation state (complete/incomplete/disabled)
- *	@linkspeed: returnedlink speed in use
- *	@duplex_mode: reported half/full duplex state
- *	@mdi_mdix: not yet working
- *	@masterslave: report whether we are master or slave
- *	@polarity: link polarity
- *
- *	I can read your lan like a magazine
- *	I see if your up
- *	I know your link speed
- *	I see all the setting that you'd rather keep
- */
-static void et1310_phy_link_status(struct et131x_adapter *adapter,
-			  u8 *link_status,
-			  u32 *autoneg,
-			  u32 *linkspeed,
-			  u32 *duplex_mode,
-			  u32 *mdi_mdix,
-			  u32 *masterslave, u32 *polarity)
-{
-	u16 mistatus = 0;
-	u16 is1000BaseT = 0;
-	u16 vmi_phystatus = 0;
-	u16 control = 0;
-
-	et131x_mii_read(adapter, MII_BMSR, &mistatus);
-	et131x_mii_read(adapter, MII_STAT1000, &is1000BaseT);
-	et131x_mii_read(adapter, PHY_PHY_STATUS, &vmi_phystatus);
-	et131x_mii_read(adapter, MII_BMCR, &control);
-
-	*link_status = (vmi_phystatus & ET_PHY_LSTATUS) ? 1 : 0;
-	*autoneg = (control & ET_PHY_AUTONEG_STATUS) ?
-			((vmi_phystatus & ET_PHY_AUTONEG_ENABLE) ?
-					    TRUEPHY_ANEG_COMPLETE :
-					    TRUEPHY_ANEG_NOT_COMPLETE) :
-							TRUEPHY_ANEG_DISABLED;
-	*linkspeed = (vmi_phystatus & ET_PHY_SPEED_STATUS) >> 8;
-	*duplex_mode = (vmi_phystatus & ET_PHY_DUPLEX_STATUS) >> 7;
-	/* NOTE: Need to complete this */
-	*mdi_mdix = 0;
-
-	*masterslave = (is1000BaseT & ET_1000BT_MSTR_SLV) ?
-			TRUEPHY_CFG_MASTER : TRUEPHY_CFG_SLAVE;
-	*polarity = (vmi_phystatus & ET_PHY_POLARITY_STATUS) ?
-			TRUEPHY_POLARITY_INVERTED : TRUEPHY_POLARITY_NORMAL;
-}
-
-static void et1310_phy_and_or_reg(struct et131x_adapter *adapter,
-				  u16 regnum, u16 and_mask, u16 or_mask)
-{
-	u16 reg;
-
-	et131x_mii_read(adapter, regnum, &reg);
-	reg &= and_mask;
-	reg |= or_mask;
-	et131x_mii_write(adapter, regnum, reg);
-}
-
 /* Still used from _mac for BIT_READ */
 void et1310_phy_access_mii_bit(struct et131x_adapter *adapter, u16 action,
 			       u16 regnum, u16 bitnum, u8 *value)
@@ -437,108 +375,3 @@ void et131x_xcvr_init(struct et131x_adapter *adapter)
 	}
 }
 
-void et131x_mii_check(struct et131x_adapter *adapter,
-		      u16 bmsr, u16 bmsr_ints)
-{
-	struct phy_device *phydev = adapter->phydev;
-	u8 link_status;
-	u32 autoneg_status;
-	u32 speed;
-	u32 duplex;
-	u32 mdi_mdix;
-	u32 masterslave;
-	u32 polarity;
-
-	if (bmsr_ints & BMSR_LSTATUS) {
-		if (bmsr & BMSR_LSTATUS) {
-			adapter->boot_coma = 20;
-		} else {
-			dev_warn(&adapter->pdev->dev,
-			    "Link down - cable problem ?\n");
-
-			if (phydev && phydev->speed == SPEED_10) {
-				/* NOTE - Is there a way to query this without
-				 * TruePHY?
-				 * && TRU_QueryCoreType(adapter->hTruePhy, 0) ==
-				 * EMI_TRUEPHY_A13O) {
-				 */
-				u16 register18;
-
-				et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG,
-						 &register18);
-				et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG,
-						 register18 | 0x4);
-				et131x_mii_write(adapter, PHY_INDEX_REG,
-						 register18 | 0x8402);
-				et131x_mii_write(adapter, PHY_DATA_REG,
-						 register18 | 511);
-				et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG,
-						 register18);
-			}
-
-			/* Free the packets being actively sent & stopped */
-			et131x_free_busy_send_packets(adapter);
-
-			/* Re-initialize the send structures */
-			et131x_init_send(adapter);
-
-			/* Reset the RFD list and re-start RU */
-			et131x_reset_recv(adapter);
-
-			/*
-			 * Bring the device back to the state it was during
-			 * init prior to autonegotiation being complete. This
-			 * way, when we get the auto-neg complete interrupt,
-			 * we can complete init by calling config_mac_regs2.
-			 */
-			et131x_soft_reset(adapter);
-
-			/* Setup ET1310 as per the documentation */
-			et131x_adapter_setup(adapter);
-		}
-	}
-
-	if (bmsr_ints & BMSR_ANEGCOMPLETE) {
-		if (bmsr & BMSR_ANEGCOMPLETE) {
-			et1310_phy_link_status(adapter,
-					     &link_status, &autoneg_status,
-					     &speed, &duplex, &mdi_mdix,
-					     &masterslave, &polarity);
-
-			adapter->boot_coma = 20;
-
-			if (phydev && phydev->speed == SPEED_10) {
-				/*
-				 * NOTE - Is there a way to query this without
-				 * TruePHY?
-				 * && TRU_QueryCoreType(adapter->hTruePhy, 0)==
-				 * EMI_TRUEPHY_A13O) {
-				 */
-				u16 register18;
-
-				et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG,
-						 &register18);
-				et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG,
-						 register18 | 0x4);
-				et131x_mii_write(adapter, PHY_INDEX_REG,
-						 register18 | 0x8402);
-				et131x_mii_write(adapter, PHY_DATA_REG,
-						 register18 | 511);
-				et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG,
-						 register18);
-			}
-
-			et1310_config_flow_control(adapter);
-
-			if (phydev && phydev->speed == SPEED_1000 &&
-					adapter->registry_jumbo_packet > 2048)
-				et1310_phy_and_or_reg(adapter, PHY_CONFIG,
-						~ET_PHY_CONFIG_TX_FIFO_DEPTH,
-						ET_PHY_CONFIG_FIFO_DEPTH_32);
-
-			et131x_set_rx_dma_timer(adapter);
-			et1310_config_mac_regs2(adapter);
-		}
-	}
-}
-
diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c
index 799aad6..618f844 100644
--- a/drivers/staging/et131x/et131x_initpci.c
+++ b/drivers/staging/et131x/et131x_initpci.c
@@ -446,29 +446,110 @@ static void et131x_adjust_link(struct net_device *netdev)
 	struct address_map __iomem *iomem = adapter->regs;
 
 	u32 pm_csr;
-	u16 bmsr_ints;
-	u16 bmsr_data;
 
-	/* If we are in coma mode, we need to disable it. */
-	pm_csr = readl(&iomem->global.pm_csr);
-	if (pm_csr & ET_PM_PHY_SW_COMA) {
-		/*
-		 * Check to see if we are in coma mode and if
-		 * so, disable it because we will not be able
-		 * to read PHY values until we are out.
-		 */
-		et1310_disable_phy_coma(adapter);
+	if (netif_carrier_ok(netdev)) {
+		adapter->boot_coma = 20;
+
+		if (phydev && phydev->speed == SPEED_10) {
+			/*
+			 * NOTE - Is there a way to query this without
+			 * TruePHY?
+			 * && TRU_QueryCoreType(adapter->hTruePhy, 0)==
+			 * EMI_TRUEPHY_A13O) {
+			 */
+			u16 register18;
+
+			et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG,
+					 &register18);
+			et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG,
+					 register18 | 0x4);
+			et131x_mii_write(adapter, PHY_INDEX_REG,
+					 register18 | 0x8402);
+			et131x_mii_write(adapter, PHY_DATA_REG,
+					 register18 | 511);
+			et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG,
+					 register18);
+		}
+
+		et1310_config_flow_control(adapter);
+
+		if (phydev && phydev->speed == SPEED_1000 &&
+				adapter->registry_jumbo_packet > 2048) {
+			u16 reg;
+
+			et131x_mii_read(adapter, PHY_CONFIG, &reg);
+			reg &= ~ET_PHY_CONFIG_TX_FIFO_DEPTH;
+			reg |= ET_PHY_CONFIG_FIFO_DEPTH_32;
+			et131x_mii_write(adapter, PHY_CONFIG, reg);
+		}
+
+		et131x_set_rx_dma_timer(adapter);
+		et1310_config_mac_regs2(adapter);
 	}
 
-	et131x_phy_mii_read(adapter, phydev->addr, MII_BMSR, &bmsr_data);
+	if (phydev->link != adapter->link) {
+		/* If we are in coma mode, we need to disable it. */
+		pm_csr = readl(&iomem->global.pm_csr);
+		if (pm_csr & ET_PM_PHY_SW_COMA) {
+			/*
+			 * Check to see if we are in coma mode and if
+			 * so, disable it because we will not be able
+			 * to read PHY values until we are out.
+			 */
+			et1310_disable_phy_coma(adapter);
+		}
+
+		if (phydev->link) {
+			adapter->boot_coma = 20;
+		} else {
+			dev_warn(&adapter->pdev->dev,
+			    "Link down - cable problem ?\n");
+
+			if (phydev && phydev->speed == SPEED_10) {
+				/* NOTE - Is there a way to query this without
+				 * TruePHY?
+				 * && TRU_QueryCoreType(adapter->hTruePhy, 0) ==
+				 * EMI_TRUEPHY_A13O)
+				 */
+				u16 register18;
+
+				et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG,
+						 &register18);
+				et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG,
+						 register18 | 0x4);
+				et131x_mii_write(adapter, PHY_INDEX_REG,
+						 register18 | 0x8402);
+				et131x_mii_write(adapter, PHY_DATA_REG,
+						 register18 | 511);
+				et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG,
+						 register18);
+			}
+
+			/* Free the packets being actively sent & stopped */
+			et131x_free_busy_send_packets(adapter);
+
+			/* Re-initialize the send structures */
+			et131x_init_send(adapter);
 
-	bmsr_ints = adapter->bmsr ^ bmsr_data;
-	adapter->bmsr = bmsr_data;
+			/* Reset the RFD list and re-start RU */
+			et131x_reset_recv(adapter);
 
-	/* Do all the cable in / cable out stuff */
-	et131x_mii_check(adapter, bmsr_data, bmsr_ints);
+			/*
+			 * Bring the device back to the state it was during
+			 * init prior to autonegotiation being complete. This
+			 * way, when we get the auto-neg complete interrupt,
+			 * we can complete init by calling config_mac_regs2.
+			 */
+			et131x_soft_reset(adapter);
 
-	phy_print_status(phydev);
+			/* Setup ET1310 as per the documentation */
+			et131x_adapter_setup(adapter);
+		}
+
+		adapter->link = phydev->link;
+
+		phy_print_status(phydev);
+	}
 }
 
 int et131x_mii_probe(struct net_device *netdev)
-- 
1.7.6


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/6] staging: et131x: Create et131x_[dis|en]able_txrx() calls
  2011-09-25 18:17 [PATCH 1/6] staging: et131x: support register dump in ethtool ops Mark Einon
  2011-09-25 18:17 ` [PATCH 2/6] staging: et131x: Add link status to adapter struct Mark Einon
  2011-09-25 18:17 ` [PATCH 3/6] staging: et131x: Remove et131x_check_mii() and move functionality into et131x_adjust_link() Mark Einon
@ 2011-09-25 18:17 ` Mark Einon
  2011-09-25 18:17 ` [PATCH 5/6] staging: et131x: Remove header declaration of et131x_check_mii() Mark Einon
  2011-09-25 18:17 ` [PATCH 6/6] staging: et131x: Bugfix - driver doesn't autoreneg after cable unplug/plug events Mark Einon
  4 siblings, 0 replies; 6+ messages in thread
From: Mark Einon @ 2011-09-25 18:17 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-kernel, o.hartmann, alan, Mark Einon

In et131x_netdev.c, a series of calls to enable and diasble the rx/tx engine and queue are being used in several different places.
Create two functions to encapsulate these calls, and replace many calls with just the one.

Signed-off-by: Mark Einon <mark.einon@gmail.com>
---
 drivers/staging/et131x/et131x.h        |    2 +
 drivers/staging/et131x/et131x_netdev.c |  126 ++++++++++++--------------------
 2 files changed, 50 insertions(+), 78 deletions(-)

diff --git a/drivers/staging/et131x/et131x.h b/drivers/staging/et131x/et131x.h
index f52fa18..6f8fef6 100644
--- a/drivers/staging/et131x/et131x.h
+++ b/drivers/staging/et131x/et131x.h
@@ -83,6 +83,8 @@ void et1310_setup_device_for_unicast(struct et131x_adapter *adapter);
 
 /* et131x_netdev.c */
 struct net_device *et131x_device_alloc(void);
+void et131x_enable_txrx(struct net_device *netdev);
+void et131x_disable_txrx(struct net_device *netdev);
 
 /* et1310_pm.c */
 void et1310_enable_phy_coma(struct et131x_adapter *adapter);
diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c
index 5fb4056..6ec4a0f 100644
--- a/drivers/staging/et131x/et131x_netdev.c
+++ b/drivers/staging/et131x/et131x_netdev.c
@@ -137,6 +137,45 @@ static struct net_device_stats *et131x_stats(struct net_device *netdev)
 }
 
 /**
+ * et131x_enable_txrx - Enable tx/rx queues
+ * @netdev: device to be enabled
+ */
+void et131x_enable_txrx(struct net_device *netdev)
+{
+	struct et131x_adapter *adapter = netdev_priv(netdev);
+
+	/* Enable the Tx and Rx DMA engines (if not already enabled) */
+	et131x_rx_dma_enable(adapter);
+	et131x_tx_dma_enable(adapter);
+
+	/* Enable device interrupts */
+	if (adapter->flags & fMP_ADAPTER_INTERRUPT_IN_USE)
+		et131x_enable_interrupts(adapter);
+
+	/* We're ready to move some data, so start the queue */
+	netif_start_queue(netdev);
+}
+
+/**
+ * et131x_disable_txrx - Disable tx/rx queues
+ * @netdev: device to be disabled
+ */
+void et131x_disable_txrx(struct net_device *netdev)
+{
+	struct et131x_adapter *adapter = netdev_priv(netdev);
+
+	/* First thing is to stop the queue */
+	netif_stop_queue(netdev);
+
+	/* Stop the Tx and Rx DMA engines */
+	et131x_rx_dma_disable(adapter);
+	et131x_tx_dma_disable(adapter);
+
+	/* Disable device interrupts */
+	et131x_disable_interrupts(adapter);
+}
+
+/**
  * et131x_open - Open the device for use.
  * @netdev: device to be opened
  *
@@ -159,19 +198,10 @@ int et131x_open(struct net_device *netdev)
 		return result;
 	}
 
-	/* Enable the Tx and Rx DMA engines (if not already enabled) */
-	et131x_rx_dma_enable(adapter);
-	et131x_tx_dma_enable(adapter);
-
-	/* Enable device interrupts */
-	et131x_enable_interrupts(adapter);
-
 	adapter->flags |= fMP_ADAPTER_INTERRUPT_IN_USE;
-
+	et131x_enable_txrx(netdev);
 	phy_start(adapter->phydev);
 
-	/* We're ready to move some data, so start the queue */
-	netif_start_queue(netdev);
 	return result;
 }
 
@@ -188,15 +218,7 @@ int et131x_close(struct net_device *netdev)
 	/* Save the timestamp for the TX watchdog, prevent a timeout */
 	netdev->trans_start = jiffies;
 
-	/* First thing is to stop the queue */
-	netif_stop_queue(netdev);
-
-	/* Stop the Tx and Rx DMA engines */
-	et131x_rx_dma_disable(adapter);
-	et131x_tx_dma_disable(adapter);
-
-	/* Disable device interrupts */
-	et131x_disable_interrupts(adapter);
+	et131x_disable_txrx(netdev);
 
 	/* Deregistering ISR */
 	adapter->flags &= ~fMP_ADAPTER_INTERRUPT_IN_USE;
@@ -442,29 +464,9 @@ void et131x_tx_timeout(struct net_device *netdev)
 
 			adapter->net_stats.tx_errors++;
 
-			/* perform reset */
-			/* First thing is to stop the queue */
-			netif_stop_queue(netdev);
-
-			/* Stop the Tx and Rx DMA engines */
-			et131x_rx_dma_disable(adapter);
-			et131x_tx_dma_disable(adapter);
-
-			/* Disable device interrupts */
-			et131x_disable_interrupts(adapter);
-
-			/*
-			 * Enable the Tx and Rx DMA engines
-			 * (if not already enabled)
-			 */
-			et131x_rx_dma_enable(adapter);
-			et131x_tx_dma_enable(adapter);
-
-			/* Enable device interrupts */
-			et131x_enable_interrupts(adapter);
-
-			/* We're ready to move some data, so start the queue */
-			netif_start_queue(netdev);
+			/* perform reset of tx/rx */
+			et131x_disable_txrx(netdev);
+			et131x_enable_txrx(netdev);
 			return;
 		}
 	}
@@ -488,15 +490,7 @@ int et131x_change_mtu(struct net_device *netdev, int new_mtu)
 	if (new_mtu < 64 || new_mtu > 9216)
 		return -EINVAL;
 
-	/* Stop the netif queue */
-	netif_stop_queue(netdev);
-
-	/* Stop the Tx and Rx DMA engines */
-	et131x_rx_dma_disable(adapter);
-	et131x_tx_dma_disable(adapter);
-
-	/* Disable device interrupts */
-	et131x_disable_interrupts(adapter);
+	et131x_disable_txrx(netdev);
 	et131x_handle_send_interrupt(adapter);
 	et131x_handle_recv_interrupt(adapter);
 
@@ -526,16 +520,8 @@ int et131x_change_mtu(struct net_device *netdev, int new_mtu)
 	/* Init the device with the new settings */
 	et131x_adapter_setup(adapter);
 
-	/* Enable interrupts */
-	if (adapter->flags & fMP_ADAPTER_INTERRUPT_IN_USE)
-		et131x_enable_interrupts(adapter);
+	et131x_enable_txrx(netdev);
 
-	/* Restart the Tx and Rx DMA engines */
-	et131x_rx_dma_enable(adapter);
-	et131x_tx_dma_enable(adapter);
-
-	/* Restart the netif queue */
-	netif_wake_queue(netdev);
 	return result;
 }
 
@@ -563,15 +549,7 @@ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac)
 	if (!is_valid_ether_addr(address->sa_data))
 		return -EINVAL;
 
-	/* Stop the netif queue */
-	netif_stop_queue(netdev);
-
-	/* Stop the Tx and Rx DMA engines */
-	et131x_rx_dma_disable(adapter);
-	et131x_tx_dma_disable(adapter);
-
-	/* Disable device interrupts */
-	et131x_disable_interrupts(adapter);
+	et131x_disable_txrx(netdev);
 	et131x_handle_send_interrupt(adapter);
 	et131x_handle_recv_interrupt(adapter);
 
@@ -603,16 +581,8 @@ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac)
 	/* Init the device with the new settings */
 	et131x_adapter_setup(adapter);
 
-	/* Enable interrupts */
-	if (adapter->flags & fMP_ADAPTER_INTERRUPT_IN_USE)
-		et131x_enable_interrupts(adapter);
-
-	/* Restart the Tx and Rx DMA engines */
-	et131x_rx_dma_enable(adapter);
-	et131x_tx_dma_enable(adapter);
+	et131x_enable_txrx(netdev);
 
-	/* Restart the netif queue */
-	netif_wake_queue(netdev);
 	return result;
 }
 
-- 
1.7.6


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 5/6] staging: et131x: Remove header declaration of et131x_check_mii()
  2011-09-25 18:17 [PATCH 1/6] staging: et131x: support register dump in ethtool ops Mark Einon
                   ` (2 preceding siblings ...)
  2011-09-25 18:17 ` [PATCH 4/6] staging: et131x: Create et131x_[dis|en]able_txrx() calls Mark Einon
@ 2011-09-25 18:17 ` Mark Einon
  2011-09-25 18:17 ` [PATCH 6/6] staging: et131x: Bugfix - driver doesn't autoreneg after cable unplug/plug events Mark Einon
  4 siblings, 0 replies; 6+ messages in thread
From: Mark Einon @ 2011-09-25 18:17 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-kernel, o.hartmann, alan, Mark Einon

et131x_check_mii no longer exists, remove its declaration from the header file

Signed-off-by: Mark Einon <mark.einon@gmail.com>
---
 drivers/staging/et131x/et131x.h |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/et131x/et131x.h b/drivers/staging/et131x/et131x.h
index 6f8fef6..c047e6e 100644
--- a/drivers/staging/et131x/et131x.h
+++ b/drivers/staging/et131x/et131x.h
@@ -107,8 +107,6 @@ int32_t et131x_mii_read(struct et131x_adapter *adapter,
 		u8 reg, u16 *value);
 int32_t et131x_mii_write(struct et131x_adapter *adapter,
 		u8 reg, u16 value);
-void et131x_mii_check(struct et131x_adapter *adapter,
-		      u16 bmsr, u16 bmsr_ints);
 
 int et131x_mdio_read(struct mii_bus *bus, int phy_addr, int reg);
 int et131x_mdio_write(struct mii_bus *bus, int phy_addr, int reg, u16 value);
-- 
1.7.6


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 6/6] staging: et131x: Bugfix - driver doesn't autoreneg after cable unplug/plug events
  2011-09-25 18:17 [PATCH 1/6] staging: et131x: support register dump in ethtool ops Mark Einon
                   ` (3 preceding siblings ...)
  2011-09-25 18:17 ` [PATCH 5/6] staging: et131x: Remove header declaration of et131x_check_mii() Mark Einon
@ 2011-09-25 18:17 ` Mark Einon
  4 siblings, 0 replies; 6+ messages in thread
From: Mark Einon @ 2011-09-25 18:17 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-kernel, o.hartmann, alan, Mark Einon

This driver has a long standing bug where removing and inserting the ethernet cable results in no packets being
trnasmitted / received and hence no autonegotiation occurring.

Fixed by resetting the rx/tx engines and queue on detecting a cable being removed.

Signed-off-by: Mark Einon <mark.einon@gmail.com>
---
 drivers/staging/et131x/et131x_initpci.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c
index 618f844..e9daa73 100644
--- a/drivers/staging/et131x/et131x_initpci.c
+++ b/drivers/staging/et131x/et131x_initpci.c
@@ -544,6 +544,10 @@ static void et131x_adjust_link(struct net_device *netdev)
 
 			/* Setup ET1310 as per the documentation */
 			et131x_adapter_setup(adapter);
+
+			/* perform reset of tx/rx */
+			et131x_disable_txrx(netdev);
+			et131x_enable_txrx(netdev);
 		}
 
 		adapter->link = phydev->link;
-- 
1.7.6


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-09-25 18:19 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-25 18:17 [PATCH 1/6] staging: et131x: support register dump in ethtool ops Mark Einon
2011-09-25 18:17 ` [PATCH 2/6] staging: et131x: Add link status to adapter struct Mark Einon
2011-09-25 18:17 ` [PATCH 3/6] staging: et131x: Remove et131x_check_mii() and move functionality into et131x_adjust_link() Mark Einon
2011-09-25 18:17 ` [PATCH 4/6] staging: et131x: Create et131x_[dis|en]able_txrx() calls Mark Einon
2011-09-25 18:17 ` [PATCH 5/6] staging: et131x: Remove header declaration of et131x_check_mii() Mark Einon
2011-09-25 18:17 ` [PATCH 6/6] staging: et131x: Bugfix - driver doesn't autoreneg after cable unplug/plug events Mark Einon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®