generic: refresh phy driver

This commit is contained in:
AmadeusGhost 2020-04-15 18:05:10 +08:00
parent 61bad53e93
commit e7c65ce31c
6 changed files with 934 additions and 156 deletions

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@
#define AR8216_PORT_CPU 0
#define AR8216_NUM_PORTS 6
#define AR8216_NUM_VLANS 16
#define AR7240SW_NUM_PORTS 5
#define AR8316_NUM_VLANS 4096
/* size of the vlan table */
@ -55,6 +56,8 @@
#define AR8216_REG_FLOOD_MASK 0x002C
#define AR8216_FM_UNI_DEST_PORTS BITS(0, 6)
#define AR8216_FM_MULTI_DEST_PORTS BITS(16, 6)
#define AR8229_FLOOD_MASK_MC_DP(_p) BIT(16 + (_p))
#define AR8229_FLOOD_MASK_BC_DP(_p) BIT(25 + (_p))
#define AR8236_FM_CPU_BROADCAST_EN BIT(26)
#define AR8236_FM_CPU_BCAST_FWD_EN BIT(25)
@ -130,6 +133,14 @@
#define AR8216_ATU_CTRL_AGE_TIME BITS(0, 16)
#define AR8216_ATU_CTRL_AGE_TIME_S 0
#define AR8236_ATU_CTRL_RES BIT(20)
#define AR8216_ATU_CTRL_LEARN_CHANGE BIT(18)
#define AR8216_ATU_CTRL_RESERVED BIT(19)
#define AR8216_ATU_CTRL_ARP_EN BIT(20)
#define AR8216_REG_TAG_PRIORITY 0x0070
#define AR8216_REG_SERVICE_TAG 0x0074
#define AR8216_SERVICE_TAG_M BITS(0, 16)
#define AR8216_REG_MIB_FUNC 0x0080
#define AR8216_MIB_TIMER BITS(0, 16)
@ -145,6 +156,16 @@
#define AR8216_REG_GLOBAL_CPUPORT 0x0078
#define AR8216_GLOBAL_CPUPORT_MIRROR_PORT BITS(4, 4)
#define AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S 4
#define AR8216_GLOBAL_CPUPORT_EN BIT(8)
#define AR8216_REG_MDIO_CTRL 0x98
#define AR8216_MDIO_CTRL_DATA_M BITS(0, 16)
#define AR8216_MDIO_CTRL_REG_ADDR_S 16
#define AR8216_MDIO_CTRL_PHY_ADDR_S 21
#define AR8216_MDIO_CTRL_CMD_WRITE 0
#define AR8216_MDIO_CTRL_CMD_READ BIT(27)
#define AR8216_MDIO_CTRL_MASTER_EN BIT(30)
#define AR8216_MDIO_CTRL_BUSY BIT(31)
#define AR8216_PORT_OFFSET(_i) (0x0100 * (_i + 1))
#define AR8216_REG_PORT_STATUS(_i) (AR8216_PORT_OFFSET(_i) + 0x0000)
@ -240,6 +261,19 @@
#define AR8216_STATS_TXDEFER 0x98
#define AR8216_STATS_TXLATECOL 0x9c
#define AR8216_MIB_RXB_ID 14 /* RxGoodByte */
#define AR8216_MIB_TXB_ID 29 /* TxByte */
#define AR8229_REG_OPER_MODE0 0x04
#define AR8229_OPER_MODE0_MAC_GMII_EN BIT(6)
#define AR8229_OPER_MODE0_PHY_MII_EN BIT(10)
#define AR8229_REG_OPER_MODE1 0x08
#define AR8229_REG_OPER_MODE1_PHY4_MII_EN BIT(28)
#define AR8229_REG_QM_CTRL 0x3c
#define AR8229_QM_CTRL_ARP_EN BIT(15)
#define AR8236_REG_PORT_VLAN(_i) (AR8216_PORT_OFFSET((_i)) + 0x0008)
#define AR8236_PORT_VLAN_DEFAULT_ID BITS(16, 12)
#define AR8236_PORT_VLAN_DEFAULT_ID_S 16
@ -293,6 +327,9 @@
#define AR8236_STATS_TXDEFER 0xa0
#define AR8236_STATS_TXLATECOL 0xa4
#define AR8236_MIB_RXB_ID 15 /* RxGoodByte */
#define AR8236_MIB_TXB_ID 31 /* TxByte */
#define AR8316_REG_POSTRIP 0x0008
#define AR8316_POSTRIP_MAC0_GMII_EN BIT(0)
#define AR8316_POSTRIP_MAC0_RGMII_EN BIT(1)
@ -355,6 +392,12 @@ enum {
AR8216_PORT_STATE_FORWARD = 4
};
/* mib counter type */
enum {
AR8XXX_MIB_BASIC = 0,
AR8XXX_MIB_EXTENDED = 1
};
enum {
AR8XXX_VER_AR8216 = 0x01,
AR8XXX_VER_AR8236 = 0x03,
@ -381,6 +424,7 @@ struct ar8xxx_mib_desc {
unsigned int size;
unsigned int offset;
const char *name;
u8 type;
};
struct ar8xxx_chip {
@ -417,16 +461,22 @@ struct ar8xxx_chip {
u32 *status, enum arl_op op);
int (*sw_hw_apply)(struct switch_dev *dev);
void (*phy_rgmii_set)(struct ar8xxx_priv *priv, struct phy_device *phydev);
int (*phy_read)(struct ar8xxx_priv *priv, int addr, int regnum);
int (*phy_write)(struct ar8xxx_priv *priv, int addr, int regnum, u16 val);
const struct ar8xxx_mib_desc *mib_decs;
unsigned num_mibs;
unsigned mib_func;
int mib_rxb_id;
int mib_txb_id;
};
struct ar8xxx_priv {
struct switch_dev dev;
struct mii_bus *mii_bus;
struct mii_bus *sw_mii_bus;
struct phy_device *phy;
struct device *pdev;
int (*get_port_link)(unsigned port);
@ -448,8 +498,9 @@ struct ar8xxx_priv {
struct mutex mib_lock;
struct delayed_work mib_work;
int mib_next_port;
u64 *mib_stats;
u32 mib_poll_interval;
u8 mib_type;
struct list_head list;
unsigned int use_count;
@ -505,6 +556,22 @@ ar8xxx_sw_set_reset_mibs(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val);
int
ar8xxx_sw_set_mib_poll_interval(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val);
int
ar8xxx_sw_get_mib_poll_interval(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val);
int
ar8xxx_sw_set_mib_type(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val);
int
ar8xxx_sw_get_mib_type(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val);
int
ar8xxx_sw_set_mirror_rx_enable(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val);
@ -576,6 +643,9 @@ ar8xxx_sw_set_flush_port_arl_table(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val);
int
ar8xxx_sw_get_port_stats(struct switch_dev *dev, int port,
struct switch_port_stats *stats);
int
ar8216_wait_bit(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val);
static inline struct ar8xxx_priv *

View File

@ -139,7 +139,7 @@ ar8327_phy_rgmii_set(struct ar8xxx_priv *priv, struct phy_device *phydev)
if (!of_property_read_bool(np, "qca,phy-rgmii-en")) {
pr_err("ar8327: qca,phy-rgmii-en is not specified\n");
return -EINVAL;
return;
}
ar8xxx_phy_dbg_read(priv, phyaddr,
AR8327_PHY_MODE_SEL, &phy_val);
@ -150,7 +150,7 @@ ar8327_phy_rgmii_set(struct ar8xxx_priv *priv, struct phy_device *phydev)
/* set rgmii tx clock delay if needed */
if (!of_property_read_bool(np, "qca,txclk-delay-en")) {
pr_err("ar8327: qca,txclk-delay-en is not specified\n");
return -EINVAL;
return;
}
ar8xxx_phy_dbg_read(priv, phyaddr,
AR8327_PHY_SYS_CTRL, &phy_val);
@ -161,7 +161,7 @@ ar8327_phy_rgmii_set(struct ar8xxx_priv *priv, struct phy_device *phydev)
/* set rgmii rx clock delay if needed */
if (!of_property_read_bool(np, "qca,rxclk-delay-en")) {
pr_err("ar8327: qca,rxclk-delay-en is not specified\n");
return -EINVAL;
return;
}
ar8xxx_phy_dbg_read(priv, phyaddr,
AR8327_PHY_TEST_CTRL, &phy_val);
@ -662,8 +662,8 @@ ar8327_hw_init(struct ar8xxx_priv *priv)
if (!priv->chip_data)
return -ENOMEM;
if (priv->phy->mdio.dev.of_node)
ret = ar8327_hw_config_of(priv, priv->phy->mdio.dev.of_node);
if (priv->pdev->of_node)
ret = ar8327_hw_config_of(priv, priv->pdev->of_node);
else
ret = ar8327_hw_config_pdata(priv,
priv->phy->mdio.dev.platform_data);
@ -1321,6 +1321,20 @@ static const struct switch_attr ar8327_sw_attr_globals[] = {
.description = "Reset all MIB counters",
.set = ar8xxx_sw_set_reset_mibs,
},
{
.type = SWITCH_TYPE_INT,
.name = "ar8xxx_mib_poll_interval",
.description = "MIB polling interval in msecs (0 to disable)",
.set = ar8xxx_sw_set_mib_poll_interval,
.get = ar8xxx_sw_get_mib_poll_interval
},
{
.type = SWITCH_TYPE_INT,
.name = "ar8xxx_mib_type",
.description = "MIB type (0=basic 1=extended)",
.set = ar8xxx_sw_set_mib_type,
.get = ar8xxx_sw_get_mib_type
},
{
.type = SWITCH_TYPE_INT,
.name = "enable_mirror_rx",
@ -1457,16 +1471,7 @@ static const struct switch_dev_ops ar8327_sw_ops = {
.apply_config = ar8327_sw_hw_apply,
.reset_switch = ar8xxx_sw_reset_switch,
.get_port_link = ar8xxx_sw_get_port_link,
/* The following op is disabled as it hogs the CPU and degrades performance.
An implementation has been attempted in 4d8a66d but reading MIB data is slow
on ar8xxx switches.
The high CPU load has been traced down to the ar8xxx_reg_wait() call in
ar8xxx_mib_op(), which has to usleep_range() till the MIB busy flag set by
the request to update the MIB counter is cleared. */
#if 0
.get_port_stats = ar8xxx_sw_get_port_stats,
#endif
};
const struct ar8xxx_chip ar8327_chip = {
@ -1501,7 +1506,9 @@ const struct ar8xxx_chip ar8327_chip = {
.num_mibs = ARRAY_SIZE(ar8236_mibs),
.mib_decs = ar8236_mibs,
.mib_func = AR8327_REG_MIB_FUNC
.mib_func = AR8327_REG_MIB_FUNC,
.mib_rxb_id = AR8236_MIB_RXB_ID,
.mib_txb_id = AR8236_MIB_TXB_ID,
};
const struct ar8xxx_chip ar8337_chip = {
@ -1537,5 +1544,7 @@ const struct ar8xxx_chip ar8337_chip = {
.num_mibs = ARRAY_SIZE(ar8236_mibs),
.mib_decs = ar8236_mibs,
.mib_func = AR8327_REG_MIB_FUNC
.mib_func = AR8327_REG_MIB_FUNC,
.mib_rxb_id = AR8236_MIB_RXB_ID,
.mib_txb_id = AR8236_MIB_TXB_ID,
};

View File

@ -294,12 +294,22 @@ static int b53_phy_probe(struct phy_device *phydev)
if (ret)
return ret;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
linkmode_zero(phydev->supported);
if (is5325(dev) || is5365(dev))
linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, phydev->supported);
else
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, phydev->supported);
linkmode_copy(phydev->advertising, phydev->supported);
#else
if (is5325(dev) || is5365(dev))
phydev->supported = SUPPORTED_100baseT_Full;
else
phydev->supported = SUPPORTED_1000baseT_Full;
phydev->advertising = phydev->supported;
#endif
ret = b53_switch_register(dev);
if (ret) {
@ -360,6 +370,26 @@ static int b53_phy_read_status(struct phy_device *phydev)
return 0;
}
static const struct of_device_id b53_of_match_1[] = {
{ .compatible = "brcm,bcm5325" },
{ .compatible = "brcm,bcm5395" },
{ .compatible = "brcm,bcm5397" },
{ .compatible = "brcm,bcm5398" },
{ /* sentinel */ },
};
static const struct of_device_id b53_of_match_2[] = {
{ .compatible = "brcm,bcm53115" },
{ .compatible = "brcm,bcm53125" },
{ .compatible = "brcm,bcm53128" },
{ /* sentinel */ },
};
static const struct of_device_id b53_of_match_3[] = {
{ .compatible = "brcm,bcm5365" },
{ /* sentinel */ },
};
/* BCM5325, BCM539x */
static struct phy_driver b53_phy_driver_id1 = {
.phy_id = 0x0143bc00,
@ -371,6 +401,10 @@ static struct phy_driver b53_phy_driver_id1 = {
.config_aneg = b53_phy_config_aneg,
.config_init = b53_phy_config_init,
.read_status = b53_phy_read_status,
.mdiodrv.driver = {
.name = "bcm539x",
.of_match_table = b53_of_match_1,
},
};
/* BCM53125, BCM53128 */
@ -384,6 +418,10 @@ static struct phy_driver b53_phy_driver_id2 = {
.config_aneg = b53_phy_config_aneg,
.config_init = b53_phy_config_init,
.read_status = b53_phy_read_status,
.mdiodrv.driver = {
.name = "bcm531xx",
.of_match_table = b53_of_match_2,
},
};
/* BCM5365 */
@ -397,6 +435,10 @@ static struct phy_driver b53_phy_driver_id3 = {
.config_aneg = b53_phy_config_aneg,
.config_init = b53_phy_config_init,
.read_status = b53_phy_read_status,
.mdiodrv.driver = {
.name = "bcm5365",
.of_match_table = b53_of_match_3,
},
};
int __init b53_phy_driver_register(void)

View File

@ -133,23 +133,51 @@
#define RTL8367B_CHIP_MODE_MASK 0x7
#define RTL8367B_CHIP_DEBUG0_REG 0x1303
#define RTL8367B_CHIP_DEBUG0_DUMMY0(_x) BIT(8 + (_x))
#define RTL8367B_DEBUG0_SEL33(_x) BIT(8 + (_x))
#define RTL8367B_DEBUG0_DRI_OTHER BIT(7)
#define RTL8367B_DEBUG0_DRI_RG(_x) BIT(5 + (_x))
#define RTL8367B_DEBUG0_DRI(_x) BIT(3 + (_x))
#define RTL8367B_DEBUG0_SLR_OTHER BIT(2)
#define RTL8367B_DEBUG0_SLR(_x) BIT(_x)
#define RTL8367B_CHIP_DEBUG1_REG 0x1304
#define RTL8367B_DEBUG1_DN_MASK(_x) \
GENMASK(6 + (_x)*8, 4 + (_x)*8)
#define RTL8367B_DEBUG1_DN_SHIFT(_x) (4 + (_x) * 8)
#define RTL8367B_DEBUG1_DP_MASK(_x) \
GENMASK(2 + (_x) * 8, (_x) * 8)
#define RTL8367B_DEBUG1_DP_SHIFT(_x) ((_x) * 8)
#define RTL8367B_CHIP_DEBUG2_REG 0x13e2
#define RTL8367B_DEBUG2_RG2_DN_MASK GENMASK(8, 6)
#define RTL8367B_DEBUG2_RG2_DN_SHIFT 6
#define RTL8367B_DEBUG2_RG2_DP_MASK GENMASK(5, 3)
#define RTL8367B_DEBUG2_RG2_DP_SHIFT 3
#define RTL8367B_DEBUG2_DRI_EXT2_RG BIT(2)
#define RTL8367B_DEBUG2_DRI_EXT2 BIT(1)
#define RTL8367B_DEBUG2_SLR_EXT2 BIT(0)
#define RTL8367B_DIS_REG 0x1305
#define RTL8367B_DIS_SKIP_MII_RXER(_x) BIT(12 + (_x))
#define RTL8367B_DIS_RGMII_SHIFT(_x) (4 * (_x))
#define RTL8367B_DIS_RGMII_MASK 0x7
#define RTL8367B_EXT_RGMXF_REG(_x) (0x1306 + (_x))
#define RTL8367B_DIS2_REG 0x13c3
#define RTL8367B_DIS2_SKIP_MII_RXER_SHIFT 4
#define RTL8367B_DIS2_SKIP_MII_RXER 0x10
#define RTL8367B_DIS2_RGMII_SHIFT 0
#define RTL8367B_DIS2_RGMII_MASK 0xf
#define RTL8367B_EXT_RGMXF_REG(_x) \
((_x) == 2 ? 0x13c5 : 0x1306 + (_x))
#define RTL8367B_EXT_RGMXF_DUMMY0_SHIFT 5
#define RTL8367B_EXT_RGMXF_DUMMY0_MASK 0x7ff
#define RTL8367B_EXT_RGMXF_TXDELAY_SHIFT 3
#define RTL8367B_EXT_RGMXF_TXDELAY_MASK 1
#define RTL8367B_EXT_RGMXF_RXDELAY_MASK 0x7
#define RTL8367B_DI_FORCE_REG(_x) (0x1310 + (_x))
#define RTL8367B_DI_FORCE_REG(_x) \
((_x) == 2 ? 0x13c4 : 0x1310 + (_x))
#define RTL8367B_DI_FORCE_MODE BIT(12)
#define RTL8367B_DI_FORCE_NWAY BIT(7)
#define RTL8367B_DI_FORCE_TXPAUSE BIT(6)
@ -754,28 +782,51 @@ static int rtl8367b_extif_set_mode(struct rtl8366_smi *smi, int id,
switch (mode) {
case RTL8367_EXTIF_MODE_RGMII:
case RTL8367_EXTIF_MODE_RGMII_33V:
REG_WR(smi, RTL8367B_CHIP_DEBUG0_REG, 0x0367);
REG_WR(smi, RTL8367B_CHIP_DEBUG1_REG, 0x7777);
REG_RMW(smi, RTL8367B_CHIP_DEBUG0_REG,
RTL8367B_DEBUG0_SEL33(id),
RTL8367B_DEBUG0_SEL33(id));
if (id <= 1) {
REG_RMW(smi, RTL8367B_CHIP_DEBUG0_REG,
RTL8367B_DEBUG0_DRI(id) |
RTL8367B_DEBUG0_DRI_RG(id) |
RTL8367B_DEBUG0_SLR(id),
RTL8367B_DEBUG0_DRI_RG(id) |
RTL8367B_DEBUG0_SLR(id));
REG_RMW(smi, RTL8367B_CHIP_DEBUG1_REG,
RTL8367B_DEBUG1_DN_MASK(id) |
RTL8367B_DEBUG1_DP_MASK(id),
(7 << RTL8367B_DEBUG1_DN_SHIFT(id)) |
(7 << RTL8367B_DEBUG1_DP_SHIFT(id)));
} else {
REG_RMW(smi, RTL8367B_CHIP_DEBUG2_REG,
RTL8367B_DEBUG2_DRI_EXT2 |
RTL8367B_DEBUG2_DRI_EXT2_RG |
RTL8367B_DEBUG2_SLR_EXT2 |
RTL8367B_DEBUG2_RG2_DN_MASK |
RTL8367B_DEBUG2_RG2_DP_MASK,
RTL8367B_DEBUG2_DRI_EXT2_RG |
RTL8367B_DEBUG2_SLR_EXT2 |
(7 << RTL8367B_DEBUG2_RG2_DN_SHIFT) |
(7 << RTL8367B_DEBUG2_RG2_DP_SHIFT));
}
break;
case RTL8367_EXTIF_MODE_TMII_MAC:
case RTL8367_EXTIF_MODE_TMII_PHY:
REG_RMW(smi, RTL8367B_BYPASS_LINE_RATE_REG,
BIT((id + 1) % 2), BIT((id + 1) % 2));
REG_RMW(smi, RTL8367B_BYPASS_LINE_RATE_REG, BIT(id), BIT(id));
break;
case RTL8367_EXTIF_MODE_GMII:
REG_RMW(smi, RTL8367B_CHIP_DEBUG0_REG,
RTL8367B_CHIP_DEBUG0_DUMMY0(id),
RTL8367B_CHIP_DEBUG0_DUMMY0(id));
RTL8367B_DEBUG0_SEL33(id),
RTL8367B_DEBUG0_SEL33(id));
REG_RMW(smi, RTL8367B_EXT_RGMXF_REG(id), BIT(6), BIT(6));
break;
case RTL8367_EXTIF_MODE_MII_MAC:
case RTL8367_EXTIF_MODE_MII_PHY:
case RTL8367_EXTIF_MODE_DISABLED:
REG_RMW(smi, RTL8367B_BYPASS_LINE_RATE_REG,
BIT((id + 1) % 2), 0);
REG_RMW(smi, RTL8367B_BYPASS_LINE_RATE_REG, BIT(id), 0);
REG_RMW(smi, RTL8367B_EXT_RGMXF_REG(id), BIT(6), 0);
break;
@ -785,9 +836,14 @@ static int rtl8367b_extif_set_mode(struct rtl8366_smi *smi, int id,
return -EINVAL;
}
REG_RMW(smi, RTL8367B_DIS_REG,
RTL8367B_DIS_RGMII_MASK << RTL8367B_DIS_RGMII_SHIFT(id),
mode << RTL8367B_DIS_RGMII_SHIFT(id));
if (id <= 1)
REG_RMW(smi, RTL8367B_DIS_REG,
RTL8367B_DIS_RGMII_MASK << RTL8367B_DIS_RGMII_SHIFT(id),
mode << RTL8367B_DIS_RGMII_SHIFT(id));
else
REG_RMW(smi, RTL8367B_DIS2_REG,
RTL8367B_DIS2_RGMII_MASK << RTL8367B_DIS2_RGMII_SHIFT,
mode << RTL8367B_DIS2_RGMII_SHIFT);
return 0;
}
@ -931,6 +987,10 @@ static int rtl8367b_setup(struct rtl8366_smi *smi)
err = rtl8367b_extif_init_of(smi, 1, "realtek,extif1");
if (err)
return err;
err = rtl8367b_extif_init_of(smi, 2, "realtek,extif2");
if (err)
return err;
} else {
err = rtl8367b_extif_init(smi, 0, pdata->extif0_cfg);
if (err)

View File

@ -1291,6 +1291,7 @@ switch_generic_set_link(struct switch_dev *dev, int port,
return 0;
}
EXPORT_SYMBOL_GPL(switch_generic_set_link);
static int __init
swconfig_init(void)