Commit e8b03391 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-lan743x-pci11010-pci11414-devices-enhancements'

Raju Lakkaraju says:

====================
net: lan743x: PCI11010 / PCI11414 devices Enhancements

This patch series continues with the addition of supported features
for the Ethernet function of the PCI11010 / PCI11414 devices to
the LAN743x driver.
====================

Link: https://lore.kernel.org/r/20220616041226.26996-1-Raju.Lakkaraju@microchip.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents f0502724 311abcdd
Loading
Loading
Loading
Loading
+60 −3
Original line number Diff line number Diff line
@@ -155,7 +155,7 @@ static int lan743x_otp_write(struct lan743x_adapter *adapter, u32 offset,
	return 0;
}

static int lan743x_hs_syslock_acquire(struct lan743x_adapter *adapter,
int lan743x_hs_syslock_acquire(struct lan743x_adapter *adapter,
			       u16 timeout)
{
	u16 timeout_cnt = 0;
@@ -192,7 +192,7 @@ static int lan743x_hs_syslock_acquire(struct lan743x_adapter *adapter,
	return 0;
}

static void lan743x_hs_syslock_release(struct lan743x_adapter *adapter)
void lan743x_hs_syslock_release(struct lan743x_adapter *adapter)
{
	u32 val;

@@ -1149,7 +1149,12 @@ static void lan743x_ethtool_get_wol(struct net_device *netdev,
	wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST |
		WAKE_MAGIC | WAKE_PHY | WAKE_ARP;

	if (adapter->is_pci11x1x)
		wol->supported |= WAKE_MAGICSECURE;

	wol->wolopts |= adapter->wolopts;
	if (adapter->wolopts & WAKE_MAGICSECURE)
		memcpy(wol->sopass, adapter->sopass, sizeof(wol->sopass));
}

static int lan743x_ethtool_set_wol(struct net_device *netdev,
@@ -1170,6 +1175,13 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev,
		adapter->wolopts |= WAKE_PHY;
	if (wol->wolopts & WAKE_ARP)
		adapter->wolopts |= WAKE_ARP;
	if (wol->wolopts & WAKE_MAGICSECURE &&
	    wol->wolopts & WAKE_MAGIC) {
		memcpy(adapter->sopass, wol->sopass, sizeof(wol->sopass));
		adapter->wolopts |= WAKE_MAGICSECURE;
	} else {
		memset(adapter->sopass, 0, sizeof(u8) * SOPASS_MAX);
	}

	device_set_wakeup_enable(&adapter->pdev->dev, (bool)wol->wolopts);

@@ -1178,6 +1190,49 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev,
}
#endif /* CONFIG_PM */

static void lan743x_common_regs(struct net_device *dev,
				struct ethtool_regs *regs, void *p)

{
	struct lan743x_adapter *adapter = netdev_priv(dev);
	u32 *rb = p;

	memset(p, 0, (MAX_LAN743X_ETH_REGS * sizeof(u32)));

	rb[ETH_PRIV_FLAGS] = adapter->flags;
	rb[ETH_ID_REV]     = lan743x_csr_read(adapter, ID_REV);
	rb[ETH_FPGA_REV]   = lan743x_csr_read(adapter, FPGA_REV);
	rb[ETH_STRAP_READ] = lan743x_csr_read(adapter, STRAP_READ);
	rb[ETH_INT_STS]    = lan743x_csr_read(adapter, INT_STS);
	rb[ETH_HW_CFG]     = lan743x_csr_read(adapter, HW_CFG);
	rb[ETH_PMT_CTL]    = lan743x_csr_read(adapter, PMT_CTL);
	rb[ETH_E2P_CMD]    = lan743x_csr_read(adapter, E2P_CMD);
	rb[ETH_E2P_DATA]   = lan743x_csr_read(adapter, E2P_DATA);
	rb[ETH_MAC_CR]     = lan743x_csr_read(adapter, MAC_CR);
	rb[ETH_MAC_RX]     = lan743x_csr_read(adapter, MAC_RX);
	rb[ETH_MAC_TX]     = lan743x_csr_read(adapter, MAC_TX);
	rb[ETH_FLOW]       = lan743x_csr_read(adapter, MAC_FLOW);
	rb[ETH_MII_ACC]    = lan743x_csr_read(adapter, MAC_MII_ACC);
	rb[ETH_MII_DATA]   = lan743x_csr_read(adapter, MAC_MII_DATA);
	rb[ETH_EEE_TX_LPI_REQ_DLY]  = lan743x_csr_read(adapter,
						       MAC_EEE_TX_LPI_REQ_DLY_CNT);
	rb[ETH_WUCSR]      = lan743x_csr_read(adapter, MAC_WUCSR);
	rb[ETH_WK_SRC]     = lan743x_csr_read(adapter, MAC_WK_SRC);
}

static int lan743x_get_regs_len(struct net_device *dev)
{
	return MAX_LAN743X_ETH_REGS * sizeof(u32);
}

static void lan743x_get_regs(struct net_device *dev,
			     struct ethtool_regs *regs, void *p)
{
	regs->version = LAN743X_ETH_REG_VERSION;

	lan743x_common_regs(dev, regs, p);
}

const struct ethtool_ops lan743x_ethtool_ops = {
	.get_drvinfo = lan743x_ethtool_get_drvinfo,
	.get_msglevel = lan743x_ethtool_get_msglevel,
@@ -1202,6 +1257,8 @@ const struct ethtool_ops lan743x_ethtool_ops = {
	.set_eee = lan743x_ethtool_set_eee,
	.get_link_ksettings = phy_ethtool_get_link_ksettings,
	.set_link_ksettings = phy_ethtool_set_link_ksettings,
	.get_regs_len = lan743x_get_regs_len,
	.get_regs = lan743x_get_regs,
#ifdef CONFIG_PM
	.get_wol = lan743x_ethtool_get_wol,
	.set_wol = lan743x_ethtool_set_wol,
+26 −0
Original line number Diff line number Diff line
@@ -6,6 +6,32 @@

#include "linux/ethtool.h"

#define LAN743X_ETH_REG_VERSION         1

enum {
	ETH_PRIV_FLAGS,
	ETH_ID_REV,
	ETH_FPGA_REV,
	ETH_STRAP_READ,
	ETH_INT_STS,
	ETH_HW_CFG,
	ETH_PMT_CTL,
	ETH_E2P_CMD,
	ETH_E2P_DATA,
	ETH_MAC_CR,
	ETH_MAC_RX,
	ETH_MAC_TX,
	ETH_FLOW,
	ETH_MII_ACC,
	ETH_MII_DATA,
	ETH_EEE_TX_LPI_REQ_DLY,
	ETH_WUCSR,
	ETH_WK_SRC,

	/* Add new registers above */
	MAX_LAN743X_ETH_REGS
};

extern const struct ethtool_ops lan743x_ethtool_ops;

#endif /* _LAN743X_ETHTOOL_H */
+372 −6
Original line number Diff line number Diff line
@@ -22,20 +22,36 @@
#define MMD_ACCESS_WRITE	1
#define MMD_ACCESS_READ		2
#define MMD_ACCESS_READ_INC	3
#define PCS_POWER_STATE_DOWN	0x6
#define PCS_POWER_STATE_UP	0x4

static void pci11x1x_strap_get_status(struct lan743x_adapter *adapter)
{
	u32 chip_rev;
	u32 cfg_load;
	u32 hw_cfg;
	u32 strap;
	int ret;

	/* Timeout = 100 (i.e. 1 sec (10 msce * 100)) */
	ret = lan743x_hs_syslock_acquire(adapter, 100);
	if (ret < 0) {
		netif_err(adapter, drv, adapter->netdev,
			  "Sys Lock acquire failed ret:%d\n", ret);
		return;
	}

	cfg_load = lan743x_csr_read(adapter, ETH_SYS_CONFIG_LOAD_STARTED_REG);
	lan743x_hs_syslock_release(adapter);
	hw_cfg = lan743x_csr_read(adapter, HW_CFG);

	if (cfg_load & GEN_SYS_LOAD_STARTED_REG_ETH_ ||
	    hw_cfg & HW_CFG_RST_PROTECT_) {
		strap = lan743x_csr_read(adapter, STRAP_READ);
	if (strap & STRAP_READ_USE_SGMII_EN_) {
		if (strap & STRAP_READ_SGMII_EN_)
			adapter->is_sgmii_en = true;
		else
			adapter->is_sgmii_en = false;
		netif_dbg(adapter, drv, adapter->netdev,
			  "STRAP_READ: 0x%08X\n", strap);
	} else {
		chip_rev = lan743x_csr_read(adapter, FPGA_REV);
		if (chip_rev) {
@@ -43,12 +59,12 @@ static void pci11x1x_strap_get_status(struct lan743x_adapter *adapter)
				adapter->is_sgmii_en = true;
			else
				adapter->is_sgmii_en = false;
			netif_dbg(adapter, drv, adapter->netdev,
				  "FPGA_REV: 0x%08X\n", chip_rev);
		} else {
			adapter->is_sgmii_en = false;
		}
	}
	netif_dbg(adapter, drv, adapter->netdev,
		  "SGMII I/F %sable\n", adapter->is_sgmii_en ? "En" : "Dis");
}

static bool is_pci11x1x_chip(struct lan743x_adapter *adapter)
@@ -909,6 +925,318 @@ static int lan743x_mdiobus_c45_write(struct mii_bus *bus,
	return ret;
}

static int lan743x_sgmii_wait_till_not_busy(struct lan743x_adapter *adapter)
{
	u32 data;
	int ret;

	ret = readx_poll_timeout(LAN743X_CSR_READ_OP, SGMII_ACC, data,
				 !(data & SGMII_ACC_SGMII_BZY_), 100, 1000000);
	if (ret < 0)
		netif_err(adapter, drv, adapter->netdev,
			  "%s: error %d sgmii wait timeout\n", __func__, ret);

	return ret;
}

static int lan743x_sgmii_read(struct lan743x_adapter *adapter, u8 mmd, u16 addr)
{
	u32 mmd_access;
	int ret;
	u32 val;

	if (mmd > 31) {
		netif_err(adapter, probe, adapter->netdev,
			  "%s mmd should <= 31\n", __func__);
		return -EINVAL;
	}

	mutex_lock(&adapter->sgmii_rw_lock);
	/* Load Register Address */
	mmd_access = mmd << SGMII_ACC_SGMII_MMD_SHIFT_;
	mmd_access |= (addr | SGMII_ACC_SGMII_BZY_);
	lan743x_csr_write(adapter, SGMII_ACC, mmd_access);
	ret = lan743x_sgmii_wait_till_not_busy(adapter);
	if (ret < 0)
		goto sgmii_unlock;

	val = lan743x_csr_read(adapter, SGMII_DATA);
	ret = (int)(val & SGMII_DATA_MASK_);

sgmii_unlock:
	mutex_unlock(&adapter->sgmii_rw_lock);

	return ret;
}

static int lan743x_sgmii_write(struct lan743x_adapter *adapter,
			       u8 mmd, u16 addr, u16 val)
{
	u32 mmd_access;
	int ret;

	if (mmd > 31) {
		netif_err(adapter, probe, adapter->netdev,
			  "%s mmd should <= 31\n", __func__);
		return -EINVAL;
	}
	mutex_lock(&adapter->sgmii_rw_lock);
	/* Load Register Data */
	lan743x_csr_write(adapter, SGMII_DATA, (u32)(val & SGMII_DATA_MASK_));
	/* Load Register Address */
	mmd_access = mmd << SGMII_ACC_SGMII_MMD_SHIFT_;
	mmd_access |= (addr | SGMII_ACC_SGMII_BZY_ | SGMII_ACC_SGMII_WR_);
	lan743x_csr_write(adapter, SGMII_ACC, mmd_access);
	ret = lan743x_sgmii_wait_till_not_busy(adapter);
	mutex_unlock(&adapter->sgmii_rw_lock);

	return ret;
}

static int lan743x_sgmii_mpll_set(struct lan743x_adapter *adapter,
				  u16 baud)
{
	int mpllctrl0;
	int mpllctrl1;
	int miscctrl1;
	int ret;

	mpllctrl0 = lan743x_sgmii_read(adapter, MDIO_MMD_VEND2,
				       VR_MII_GEN2_4_MPLL_CTRL0);
	if (mpllctrl0 < 0)
		return mpllctrl0;

	mpllctrl0 &= ~VR_MII_MPLL_CTRL0_USE_REFCLK_PAD_;
	if (baud == VR_MII_BAUD_RATE_1P25GBPS) {
		mpllctrl1 = VR_MII_MPLL_MULTIPLIER_100;
		/* mpll_baud_clk/4 */
		miscctrl1 = 0xA;
	} else {
		mpllctrl1 = VR_MII_MPLL_MULTIPLIER_125;
		/* mpll_baud_clk/2 */
		miscctrl1 = 0x5;
	}

	ret = lan743x_sgmii_write(adapter, MDIO_MMD_VEND2,
				  VR_MII_GEN2_4_MPLL_CTRL0, mpllctrl0);
	if (ret < 0)
		return ret;

	ret = lan743x_sgmii_write(adapter, MDIO_MMD_VEND2,
				  VR_MII_GEN2_4_MPLL_CTRL1, mpllctrl1);
	if (ret < 0)
		return ret;

	return lan743x_sgmii_write(adapter, MDIO_MMD_VEND2,
				  VR_MII_GEN2_4_MISC_CTRL1, miscctrl1);
}

static int lan743x_sgmii_2_5G_mode_set(struct lan743x_adapter *adapter,
				       bool enable)
{
	if (enable)
		return lan743x_sgmii_mpll_set(adapter,
					      VR_MII_BAUD_RATE_3P125GBPS);
	else
		return lan743x_sgmii_mpll_set(adapter,
					      VR_MII_BAUD_RATE_1P25GBPS);
}

static int lan743x_is_sgmii_2_5G_mode(struct lan743x_adapter *adapter,
				      bool *status)
{
	int ret;

	ret = lan743x_sgmii_read(adapter, MDIO_MMD_VEND2,
				 VR_MII_GEN2_4_MPLL_CTRL1);
	if (ret < 0)
		return ret;

	if (ret == VR_MII_MPLL_MULTIPLIER_125 ||
	    ret == VR_MII_MPLL_MULTIPLIER_50)
		*status = true;
	else
		*status = false;

	return 0;
}

static int lan743x_sgmii_aneg_update(struct lan743x_adapter *adapter)
{
	enum lan743x_sgmii_lsd lsd = adapter->sgmii_lsd;
	int mii_ctrl;
	int dgt_ctrl;
	int an_ctrl;
	int ret;

	if (lsd == LINK_2500_MASTER || lsd == LINK_2500_SLAVE)
		/* Switch to 2.5 Gbps */
		ret = lan743x_sgmii_2_5G_mode_set(adapter, true);
	else
		/* Switch to 10/100/1000 Mbps clock */
		ret = lan743x_sgmii_2_5G_mode_set(adapter, false);
	if (ret < 0)
		return ret;

	/* Enable SGMII Auto NEG */
	mii_ctrl = lan743x_sgmii_read(adapter, MDIO_MMD_VEND2, MII_BMCR);
	if (mii_ctrl < 0)
		return mii_ctrl;

	an_ctrl = lan743x_sgmii_read(adapter, MDIO_MMD_VEND2, VR_MII_AN_CTRL);
	if (an_ctrl < 0)
		return an_ctrl;

	dgt_ctrl = lan743x_sgmii_read(adapter, MDIO_MMD_VEND2,
				      VR_MII_DIG_CTRL1);
	if (dgt_ctrl < 0)
		return dgt_ctrl;

	if (lsd == LINK_2500_MASTER || lsd == LINK_2500_SLAVE) {
		mii_ctrl &= ~(BMCR_ANENABLE | BMCR_ANRESTART | BMCR_SPEED100);
		mii_ctrl |= BMCR_SPEED1000;
		dgt_ctrl |= VR_MII_DIG_CTRL1_CL37_TMR_OVR_RIDE_;
		dgt_ctrl &= ~VR_MII_DIG_CTRL1_MAC_AUTO_SW_;
		/* In order for Auto-Negotiation to operate properly at
		 * 2.5 Gbps the 1.6ms link timer values must be adjusted
		 * The VR_MII_LINK_TIMER_CTRL Register must be set to
		 * 16'h7A1 and The CL37_TMR_OVR_RIDE bit of the
		 * VR_MII_DIG_CTRL1 Register set to 1
		 */
		ret = lan743x_sgmii_write(adapter, MDIO_MMD_VEND2,
					  VR_MII_LINK_TIMER_CTRL, 0x7A1);
		if (ret < 0)
			return ret;
	} else {
		mii_ctrl |= (BMCR_ANENABLE | BMCR_ANRESTART);
		an_ctrl &= ~VR_MII_AN_CTRL_SGMII_LINK_STS_;
		dgt_ctrl &= ~VR_MII_DIG_CTRL1_CL37_TMR_OVR_RIDE_;
		dgt_ctrl |= VR_MII_DIG_CTRL1_MAC_AUTO_SW_;
	}

	ret = lan743x_sgmii_write(adapter, MDIO_MMD_VEND2, MII_BMCR,
				  mii_ctrl);
	if (ret < 0)
		return ret;

	ret = lan743x_sgmii_write(adapter, MDIO_MMD_VEND2,
				  VR_MII_DIG_CTRL1, dgt_ctrl);
	if (ret < 0)
		return ret;

	return lan743x_sgmii_write(adapter, MDIO_MMD_VEND2,
				  VR_MII_AN_CTRL, an_ctrl);
}

static int lan743x_pcs_seq_state(struct lan743x_adapter *adapter, u8 state)
{
	u8 wait_cnt = 0;
	u32 dig_sts;

	do {
		dig_sts = lan743x_sgmii_read(adapter, MDIO_MMD_VEND2,
					     VR_MII_DIG_STS);
		if (((dig_sts & VR_MII_DIG_STS_PSEQ_STATE_MASK_) >>
		      VR_MII_DIG_STS_PSEQ_STATE_POS_) == state)
			break;
		usleep_range(1000, 2000);
	} while (wait_cnt++ < 10);

	if (wait_cnt >= 10)
		return -ETIMEDOUT;

	return 0;
}

static int lan743x_sgmii_config(struct lan743x_adapter *adapter)
{
	struct net_device *netdev = adapter->netdev;
	struct phy_device *phydev = netdev->phydev;
	enum lan743x_sgmii_lsd lsd = POWER_DOWN;
	int mii_ctl;
	bool status;
	int ret;

	switch (phydev->speed) {
	case SPEED_2500:
		if (phydev->master_slave_state == MASTER_SLAVE_STATE_MASTER)
			lsd = LINK_2500_MASTER;
		else
			lsd = LINK_2500_SLAVE;
		break;
	case SPEED_1000:
		if (phydev->master_slave_state == MASTER_SLAVE_STATE_MASTER)
			lsd = LINK_1000_MASTER;
		else
			lsd = LINK_1000_SLAVE;
		break;
	case SPEED_100:
		if (phydev->duplex)
			lsd = LINK_100FD;
		else
			lsd = LINK_100HD;
		break;
	case SPEED_10:
		if (phydev->duplex)
			lsd = LINK_10FD;
		else
			lsd = LINK_10HD;
		break;
	default:
		netif_err(adapter, drv, adapter->netdev,
			  "Invalid speed %d\n", phydev->speed);
		return -EINVAL;
	}

	adapter->sgmii_lsd = lsd;
	ret = lan743x_sgmii_aneg_update(adapter);
	if (ret < 0) {
		netif_err(adapter, drv, adapter->netdev,
			  "error %d SGMII cfg failed\n", ret);
		return ret;
	}

	ret = lan743x_is_sgmii_2_5G_mode(adapter, &status);
	if (ret < 0) {
		netif_err(adapter, drv, adapter->netdev,
			  "erro %d SGMII get mode failed\n", ret);
		return ret;
	}

	if (status)
		netif_dbg(adapter, drv, adapter->netdev,
			  "SGMII 2.5G mode enable\n");
	else
		netif_dbg(adapter, drv, adapter->netdev,
			  "SGMII 1G mode enable\n");

	/* SGMII/1000/2500BASE-X PCS power down */
	mii_ctl = lan743x_sgmii_read(adapter, MDIO_MMD_VEND2, MII_BMCR);
	if (ret < 0)
		return ret;

	mii_ctl |= BMCR_PDOWN;
	ret = lan743x_sgmii_write(adapter, MDIO_MMD_VEND2, MII_BMCR, mii_ctl);
	if (ret < 0)
		return ret;

	ret = lan743x_pcs_seq_state(adapter, PCS_POWER_STATE_DOWN);
	if (ret < 0)
		return ret;

	/* SGMII/1000/2500BASE-X PCS power up */
	mii_ctl &= ~BMCR_PDOWN;
	ret = lan743x_sgmii_write(adapter, MDIO_MMD_VEND2, MII_BMCR, mii_ctl);
	if (ret < 0)
		return ret;

	ret = lan743x_pcs_seq_state(adapter, PCS_POWER_STATE_UP);
	if (ret < 0)
		return ret;

	return 0;
}

static void lan743x_mac_set_address(struct lan743x_adapter *adapter,
				    u8 *addr)
{
@@ -1124,6 +1452,10 @@ static void lan743x_phy_link_status_change(struct net_device *netdev)
			data |= MAC_CR_CFG_H_;
			data &= ~MAC_CR_CFG_L_;
		break;
		case SPEED_2500:
			data |= MAC_CR_CFG_H_;
			data |= MAC_CR_CFG_L_;
		break;
		}
		lan743x_csr_write(adapter, MAC_CR, data);

@@ -1135,6 +1467,10 @@ static void lan743x_phy_link_status_change(struct net_device *netdev)
		lan743x_phy_update_flowcontrol(adapter, local_advertisement,
					       remote_advertisement);
		lan743x_ptp_update_latency(adapter, phydev->speed);
		if (phydev->interface == PHY_INTERFACE_MODE_SGMII ||
		    phydev->interface == PHY_INTERFACE_MODE_1000BASEX ||
		    phydev->interface == PHY_INTERFACE_MODE_2500BASEX)
			lan743x_sgmii_config(adapter);
	}
}

@@ -2875,6 +3211,7 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter,
		adapter->max_vector_count = PCI11X1X_MAX_VECTOR_COUNT;
		pci11x1x_strap_get_status(adapter);
		spin_lock_init(&adapter->eth_syslock_spinlock);
		mutex_init(&adapter->sgmii_rw_lock);
	} else {
		adapter->max_tx_channels = LAN743X_MAX_TX_CHANNELS;
		adapter->used_tx_channels = LAN743X_USED_TX_CHANNELS;
@@ -3124,6 +3461,7 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter)
	const u8 ipv6_multicast[3] = { 0x33, 0x33 };
	const u8 arp_type[2] = { 0x08, 0x06 };
	int mask_index;
	u32 sopass;
	u32 pmtctl;
	u32 wucsr;
	u32 macrx;
@@ -3218,6 +3556,14 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter)
		pmtctl |= PMT_CTL_RX_FCT_RFE_D3_CLK_OVR_;
	}

	if (adapter->wolopts & WAKE_MAGICSECURE) {
		sopass = *(u32 *)adapter->sopass;
		lan743x_csr_write(adapter, MAC_MP_SO_LO, sopass);
		sopass = *(u16 *)&adapter->sopass[4];
		lan743x_csr_write(adapter, MAC_MP_SO_HI, sopass);
		wucsr |= MAC_MP_SO_EN_;
	}

	lan743x_csr_write(adapter, MAC_WUCSR, wucsr);
	lan743x_csr_write(adapter, PMT_CTL, pmtctl);
	lan743x_csr_write(adapter, MAC_RX, macrx);
@@ -3228,6 +3574,7 @@ static int lan743x_pm_suspend(struct device *dev)
	struct pci_dev *pdev = to_pci_dev(dev);
	struct net_device *netdev = pci_get_drvdata(pdev);
	struct lan743x_adapter *adapter = netdev_priv(netdev);
	u32 data;

	lan743x_pcidev_shutdown(pdev);

@@ -3239,6 +3586,18 @@ static int lan743x_pm_suspend(struct device *dev)
	if (adapter->wolopts)
		lan743x_pm_set_wol(adapter);

	if (adapter->is_pci11x1x) {
		/* Save HW_CFG to config again in PM resume */
		data = lan743x_csr_read(adapter, HW_CFG);
		adapter->hw_cfg = data;
		data |= (HW_CFG_RST_PROTECT_PCIE_ |
			 HW_CFG_D3_RESET_DIS_ |
			 HW_CFG_D3_VAUX_OVR_ |
			 HW_CFG_HOT_RESET_DIS_ |
			 HW_CFG_RST_PROTECT_);
		lan743x_csr_write(adapter, HW_CFG, data);
	}

	/* Host sets PME_En, put D3hot */
	return pci_prepare_to_sleep(pdev);
}
@@ -3254,6 +3613,10 @@ static int lan743x_pm_resume(struct device *dev)
	pci_restore_state(pdev);
	pci_save_state(pdev);

	/* Restore HW_CFG that was saved during pm suspend */
	if (adapter->is_pci11x1x)
		lan743x_csr_write(adapter, HW_CFG, adapter->hw_cfg);

	ret = lan743x_hardware_init(adapter, pdev);
	if (ret) {
		netif_err(adapter, probe, adapter->netdev,
@@ -3270,6 +3633,9 @@ static int lan743x_pm_resume(struct device *dev)
		lan743x_netdev_open(netdev);

	netif_device_attach(netdev);
	ret = lan743x_csr_read(adapter, MAC_WK_SRC);
	netif_info(adapter, drv, adapter->netdev,
		   "Wakeup source : 0x%08X\n", ret);

	return 0;
}
+106 −0
Original line number Diff line number Diff line
@@ -43,6 +43,11 @@
#define STRAP_READ_ADV_PM_DISABLE_	BIT(0)

#define HW_CFG					(0x010)
#define HW_CFG_RST_PROTECT_PCIE_		BIT(19)
#define HW_CFG_HOT_RESET_DIS_			BIT(15)
#define HW_CFG_D3_VAUX_OVR_			BIT(14)
#define HW_CFG_D3_RESET_DIS_			BIT(13)
#define HW_CFG_RST_PROTECT_			BIT(12)
#define HW_CFG_RELOAD_TYPE_ALL_			(0x00000FC0)
#define HW_CFG_EE_OTP_RELOAD_			BIT(4)
#define HW_CFG_LRST_				BIT(1)
@@ -92,6 +97,11 @@
#define CONFIG_REG_ADDR_BASE		(0x0000)
#define ETH_EEPROM_REG_ADDR_BASE	(0x0E00)
#define ETH_OTP_REG_ADDR_BASE		(0x1000)
#define GEN_SYS_CONFIG_LOAD_STARTED_REG	(0x0078)
#define ETH_SYS_CONFIG_LOAD_STARTED_REG (ETH_SYS_REG_ADDR_BASE + \
					 CONFIG_REG_ADDR_BASE + \
					 GEN_SYS_CONFIG_LOAD_STARTED_REG)
#define GEN_SYS_LOAD_STARTED_REG_ETH_	BIT(4)
#define SYS_LOCK_REG			(0x00A0)
#define SYS_LOCK_REG_MAIN_LOCK_		BIT(7)
#define SYS_LOCK_REG_GEN_PERI_LOCK_	BIT(5)
@@ -214,6 +224,7 @@
#define MAC_EEE_TX_LPI_REQ_DLY_CNT		(0x130)

#define MAC_WUCSR				(0x140)
#define MAC_MP_SO_EN_				BIT(21)
#define MAC_WUCSR_RFE_WAKE_EN_			BIT(14)
#define MAC_WUCSR_PFDA_EN_			BIT(3)
#define MAC_WUCSR_WAKE_EN_			BIT(2)
@@ -221,6 +232,8 @@
#define MAC_WUCSR_BCST_EN_			BIT(0)

#define MAC_WK_SRC				(0x144)
#define MAC_MP_SO_HI				(0x148)
#define MAC_MP_SO_LO				(0x14C)

#define MAC_WUF_CFG0			(0x150)
#define MAC_NUM_OF_WUF_CFG		(32)
@@ -280,11 +293,82 @@

#define MAC_WUCSR2			(0x600)

#define SGMII_ACC			(0x720)
#define SGMII_ACC_SGMII_BZY_		BIT(31)
#define SGMII_ACC_SGMII_WR_		BIT(30)
#define SGMII_ACC_SGMII_MMD_SHIFT_	(16)
#define SGMII_ACC_SGMII_MMD_MASK_	GENMASK(20, 16)
#define SGMII_ACC_SGMII_MMD_VSR_	BIT(15)
#define SGMII_ACC_SGMII_ADDR_SHIFT_	(0)
#define SGMII_ACC_SGMII_ADDR_MASK_	GENMASK(15, 0)
#define SGMII_DATA			(0x724)
#define SGMII_DATA_SHIFT_		(0)
#define SGMII_DATA_MASK_		GENMASK(15, 0)
#define SGMII_CTL			(0x728)
#define SGMII_CTL_SGMII_ENABLE_		BIT(31)
#define SGMII_CTL_LINK_STATUS_SOURCE_	BIT(8)
#define SGMII_CTL_SGMII_POWER_DN_	BIT(1)

/* Vendor Specific SGMII MMD details */
#define SR_VSMMD_PCS_ID1		0x0004
#define SR_VSMMD_PCS_ID2		0x0005
#define SR_VSMMD_STS			0x0008
#define SR_VSMMD_CTRL			0x0009

#define VR_MII_DIG_CTRL1			0x8000
#define VR_MII_DIG_CTRL1_VR_RST_		BIT(15)
#define VR_MII_DIG_CTRL1_R2TLBE_		BIT(14)
#define VR_MII_DIG_CTRL1_EN_VSMMD1_		BIT(13)
#define VR_MII_DIG_CTRL1_CS_EN_			BIT(10)
#define VR_MII_DIG_CTRL1_MAC_AUTO_SW_		BIT(9)
#define VR_MII_DIG_CTRL1_INIT_			BIT(8)
#define VR_MII_DIG_CTRL1_DTXLANED_0_		BIT(4)
#define VR_MII_DIG_CTRL1_CL37_TMR_OVR_RIDE_	BIT(3)
#define VR_MII_DIG_CTRL1_EN_2_5G_MODE_		BIT(2)
#define VR_MII_DIG_CTRL1_BYP_PWRUP_		BIT(1)
#define VR_MII_DIG_CTRL1_PHY_MODE_CTRL_		BIT(0)
#define VR_MII_AN_CTRL				0x8001
#define VR_MII_AN_CTRL_MII_CTRL_		BIT(8)
#define VR_MII_AN_CTRL_SGMII_LINK_STS_		BIT(4)
#define VR_MII_AN_CTRL_TX_CONFIG_		BIT(3)
#define VR_MII_AN_CTRL_1000BASE_X_		(0)
#define VR_MII_AN_CTRL_SGMII_MODE_		(2)
#define VR_MII_AN_CTRL_QSGMII_MODE_		(3)
#define VR_MII_AN_CTRL_PCS_MODE_SHIFT_		(1)
#define VR_MII_AN_CTRL_PCS_MODE_MASK_		GENMASK(2, 1)
#define VR_MII_AN_CTRL_MII_AN_INTR_EN_		BIT(0)
#define VR_MII_AN_INTR_STS			0x8002
#define VR_MII_AN_INTR_STS_LINK_UP_		BIT(4)
#define VR_MII_AN_INTR_STS_SPEED_MASK_		GENMASK(3, 2)
#define VR_MII_AN_INTR_STS_1000_MBPS_		BIT(3)
#define VR_MII_AN_INTR_STS_100_MBPS_		BIT(2)
#define VR_MII_AN_INTR_STS_10_MBPS_		(0)
#define VR_MII_AN_INTR_STS_FDX_			BIT(1)
#define VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR_	BIT(0)

#define VR_MII_LINK_TIMER_CTRL			0x800A
#define VR_MII_DIG_STS                          0x8010
#define VR_MII_DIG_STS_PSEQ_STATE_MASK_         GENMASK(4, 2)
#define VR_MII_DIG_STS_PSEQ_STATE_POS_          (2)
#define VR_MII_GEN2_4_MPLL_CTRL0		0x8078
#define VR_MII_MPLL_CTRL0_REF_CLK_DIV2_		BIT(12)
#define VR_MII_MPLL_CTRL0_USE_REFCLK_PAD_	BIT(4)
#define VR_MII_GEN2_4_MPLL_CTRL1		0x8079
#define VR_MII_MPLL_CTRL1_MPLL_MULTIPLIER_	GENMASK(6, 0)
#define VR_MII_BAUD_RATE_3P125GBPS		(3125)
#define VR_MII_BAUD_RATE_1P25GBPS		(1250)
#define VR_MII_MPLL_MULTIPLIER_125		(125)
#define VR_MII_MPLL_MULTIPLIER_100		(100)
#define VR_MII_MPLL_MULTIPLIER_50		(50)
#define VR_MII_MPLL_MULTIPLIER_40		(40)
#define VR_MII_GEN2_4_MISC_CTRL1		0x809A
#define VR_MII_CTRL1_RX_RATE_0_MASK_		GENMASK(3, 2)
#define VR_MII_CTRL1_RX_RATE_0_SHIFT_		(2)
#define VR_MII_CTRL1_TX_RATE_0_MASK_		GENMASK(1, 0)
#define VR_MII_MPLL_BAUD_CLK			(0)
#define VR_MII_MPLL_BAUD_CLK_DIV_2		(1)
#define VR_MII_MPLL_BAUD_CLK_DIV_4		(2)

#define INT_STS				(0x780)
#define INT_BIT_DMA_RX_(channel)	BIT(24 + (channel))
#define INT_BIT_ALL_RX_			(0x0F000000)
@@ -906,12 +990,28 @@ struct lan743x_rx {
	struct sk_buff *skb_head, *skb_tail;
};

/* SGMII Link Speed Duplex status */
enum lan743x_sgmii_lsd {
	POWER_DOWN = 0,
	LINK_DOWN,
	ANEG_BUSY,
	LINK_10HD,
	LINK_10FD,
	LINK_100HD,
	LINK_100FD,
	LINK_1000_MASTER,
	LINK_1000_SLAVE,
	LINK_2500_MASTER,
	LINK_2500_SLAVE
};

struct lan743x_adapter {
	struct net_device       *netdev;
	struct mii_bus		*mdiobus;
	int                     msg_enable;
#ifdef CONFIG_PM
	u32			wolopts;
	u8			sopass[SOPASS_MAX];
#endif
	struct pci_dev		*pdev;
	struct lan743x_csr      csr;
@@ -931,12 +1031,16 @@ struct lan743x_adapter {
	spinlock_t		eth_syslock_spinlock;
	bool			eth_syslock_en;
	u32			eth_syslock_acquire_cnt;
	struct mutex		sgmii_rw_lock;
	/* SGMII Link Speed & Duplex status */
	enum			lan743x_sgmii_lsd sgmii_lsd;
	u8			max_tx_channels;
	u8			used_tx_channels;
	u8			max_vector_count;

#define LAN743X_ADAPTER_FLAG_OTP		BIT(0)
	u32			flags;
	u32			hw_cfg;
};

#define LAN743X_COMPONENT_FLAG_RX(channel)  BIT(20 + (channel))
@@ -1049,5 +1153,7 @@ struct lan743x_rx_buffer_info {

u32 lan743x_csr_read(struct lan743x_adapter *adapter, int offset);
void lan743x_csr_write(struct lan743x_adapter *adapter, int offset, u32 data);
int lan743x_hs_syslock_acquire(struct lan743x_adapter *adapter, u16 timeout);
void lan743x_hs_syslock_release(struct lan743x_adapter *adapter);

#endif /* _LAN743X_H */
+3 −0
Original line number Diff line number Diff line
@@ -295,6 +295,9 @@ static void gpy_update_interface(struct phy_device *phydev)
				   ret);
		break;
	}

	if (phydev->speed == SPEED_2500 || phydev->speed == SPEED_1000)
		genphy_read_master_slave(phydev);
}

static int gpy_read_status(struct phy_device *phydev)