mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 17:24:17 +08:00
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: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
e8b03391b6
@ -155,8 +155,8 @@ static int lan743x_otp_write(struct lan743x_adapter *adapter, u32 offset,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lan743x_hs_syslock_acquire(struct lan743x_adapter *adapter,
|
||||
u16 timeout)
|
||||
int lan743x_hs_syslock_acquire(struct lan743x_adapter *adapter,
|
||||
u16 timeout)
|
||||
{
|
||||
u16 timeout_cnt = 0;
|
||||
u32 val;
|
||||
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
strap = lan743x_csr_read(adapter, STRAP_READ);
|
||||
if (strap & STRAP_READ_USE_SGMII_EN_) {
|
||||
/* 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_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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user