cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

marvell10g.c (34485B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Marvell 10G 88x3310 PHY driver
      4 *
      5 * Based upon the ID registers, this PHY appears to be a mixture of IPs
      6 * from two different companies.
      7 *
      8 * There appears to be several different data paths through the PHY which
      9 * are automatically managed by the PHY.  The following has been determined
     10 * via observation and experimentation for a setup using single-lane Serdes:
     11 *
     12 *       SGMII PHYXS -- BASE-T PCS -- 10G PMA -- AN -- Copper (for <= 1G)
     13 *  10GBASE-KR PHYXS -- BASE-T PCS -- 10G PMA -- AN -- Copper (for 10G)
     14 *  10GBASE-KR PHYXS -- BASE-R PCS -- Fiber
     15 *
     16 * With XAUI, observation shows:
     17 *
     18 *        XAUI PHYXS -- <appropriate PCS as above>
     19 *
     20 * and no switching of the host interface mode occurs.
     21 *
     22 * If both the fiber and copper ports are connected, the first to gain
     23 * link takes priority and the other port is completely locked out.
     24 */
     25#include <linux/bitfield.h>
     26#include <linux/ctype.h>
     27#include <linux/delay.h>
     28#include <linux/hwmon.h>
     29#include <linux/marvell_phy.h>
     30#include <linux/phy.h>
     31#include <linux/sfp.h>
     32#include <linux/netdevice.h>
     33
     34#define MV_PHY_ALASKA_NBT_QUIRK_MASK	0xfffffffe
     35#define MV_PHY_ALASKA_NBT_QUIRK_REV	(MARVELL_PHY_ID_88X3310 | 0xa)
     36
     37#define MV_VERSION(a,b,c,d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
     38
     39enum {
     40	MV_PMA_FW_VER0		= 0xc011,
     41	MV_PMA_FW_VER1		= 0xc012,
     42	MV_PMA_21X0_PORT_CTRL	= 0xc04a,
     43	MV_PMA_21X0_PORT_CTRL_SWRST				= BIT(15),
     44	MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK			= 0x7,
     45	MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII			= 0x0,
     46	MV_PMA_2180_PORT_CTRL_MACTYPE_DXGMII			= 0x1,
     47	MV_PMA_2180_PORT_CTRL_MACTYPE_QXGMII			= 0x2,
     48	MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER			= 0x4,
     49	MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN	= 0x5,
     50	MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH	= 0x6,
     51	MV_PMA_BOOT		= 0xc050,
     52	MV_PMA_BOOT_FATAL	= BIT(0),
     53
     54	MV_PCS_BASE_T		= 0x0000,
     55	MV_PCS_BASE_R		= 0x1000,
     56	MV_PCS_1000BASEX	= 0x2000,
     57
     58	MV_PCS_CSCR1		= 0x8000,
     59	MV_PCS_CSCR1_ED_MASK	= 0x0300,
     60	MV_PCS_CSCR1_ED_OFF	= 0x0000,
     61	MV_PCS_CSCR1_ED_RX	= 0x0200,
     62	MV_PCS_CSCR1_ED_NLP	= 0x0300,
     63	MV_PCS_CSCR1_MDIX_MASK	= 0x0060,
     64	MV_PCS_CSCR1_MDIX_MDI	= 0x0000,
     65	MV_PCS_CSCR1_MDIX_MDIX	= 0x0020,
     66	MV_PCS_CSCR1_MDIX_AUTO	= 0x0060,
     67
     68	MV_PCS_DSC1		= 0x8003,
     69	MV_PCS_DSC1_ENABLE	= BIT(9),
     70	MV_PCS_DSC1_10GBT	= 0x01c0,
     71	MV_PCS_DSC1_1GBR	= 0x0038,
     72	MV_PCS_DSC1_100BTX	= 0x0007,
     73	MV_PCS_DSC2		= 0x8004,
     74	MV_PCS_DSC2_2P5G	= 0xf000,
     75	MV_PCS_DSC2_5G		= 0x0f00,
     76
     77	MV_PCS_CSSR1		= 0x8008,
     78	MV_PCS_CSSR1_SPD1_MASK	= 0xc000,
     79	MV_PCS_CSSR1_SPD1_SPD2	= 0xc000,
     80	MV_PCS_CSSR1_SPD1_1000	= 0x8000,
     81	MV_PCS_CSSR1_SPD1_100	= 0x4000,
     82	MV_PCS_CSSR1_SPD1_10	= 0x0000,
     83	MV_PCS_CSSR1_DUPLEX_FULL= BIT(13),
     84	MV_PCS_CSSR1_RESOLVED	= BIT(11),
     85	MV_PCS_CSSR1_MDIX	= BIT(6),
     86	MV_PCS_CSSR1_SPD2_MASK	= 0x000c,
     87	MV_PCS_CSSR1_SPD2_5000	= 0x0008,
     88	MV_PCS_CSSR1_SPD2_2500	= 0x0004,
     89	MV_PCS_CSSR1_SPD2_10000	= 0x0000,
     90
     91	/* Temperature read register (88E2110 only) */
     92	MV_PCS_TEMP		= 0x8042,
     93
     94	/* Number of ports on the device */
     95	MV_PCS_PORT_INFO	= 0xd00d,
     96	MV_PCS_PORT_INFO_NPORTS_MASK	= 0x0380,
     97	MV_PCS_PORT_INFO_NPORTS_SHIFT	= 7,
     98
     99	/* These registers appear at 0x800X and 0xa00X - the 0xa00X control
    100	 * registers appear to set themselves to the 0x800X when AN is
    101	 * restarted, but status registers appear readable from either.
    102	 */
    103	MV_AN_CTRL1000		= 0x8000, /* 1000base-T control register */
    104	MV_AN_STAT1000		= 0x8001, /* 1000base-T status register */
    105
    106	/* Vendor2 MMD registers */
    107	MV_V2_PORT_CTRL		= 0xf001,
    108	MV_V2_PORT_CTRL_PWRDOWN					= BIT(11),
    109	MV_V2_33X0_PORT_CTRL_SWRST				= BIT(15),
    110	MV_V2_33X0_PORT_CTRL_MACTYPE_MASK			= 0x7,
    111	MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI			= 0x0,
    112	MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH		= 0x1,
    113	MV_V2_3340_PORT_CTRL_MACTYPE_RXAUI_NO_SGMII_AN		= 0x1,
    114	MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH		= 0x2,
    115	MV_V2_3310_PORT_CTRL_MACTYPE_XAUI			= 0x3,
    116	MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER			= 0x4,
    117	MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN	= 0x5,
    118	MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH	= 0x6,
    119	MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII			= 0x7,
    120	MV_V2_PORT_INTR_STS     = 0xf040,
    121	MV_V2_PORT_INTR_MASK    = 0xf043,
    122	MV_V2_PORT_INTR_STS_WOL_EN      = BIT(8),
    123	MV_V2_MAGIC_PKT_WORD0   = 0xf06b,
    124	MV_V2_MAGIC_PKT_WORD1   = 0xf06c,
    125	MV_V2_MAGIC_PKT_WORD2   = 0xf06d,
    126	/* Wake on LAN registers */
    127	MV_V2_WOL_CTRL          = 0xf06e,
    128	MV_V2_WOL_CTRL_CLEAR_STS        = BIT(15),
    129	MV_V2_WOL_CTRL_MAGIC_PKT_EN     = BIT(0),
    130	/* Temperature control/read registers (88X3310 only) */
    131	MV_V2_TEMP_CTRL		= 0xf08a,
    132	MV_V2_TEMP_CTRL_MASK	= 0xc000,
    133	MV_V2_TEMP_CTRL_SAMPLE	= 0x0000,
    134	MV_V2_TEMP_CTRL_DISABLE	= 0xc000,
    135	MV_V2_TEMP		= 0xf08c,
    136	MV_V2_TEMP_UNKNOWN	= 0x9600, /* unknown function */
    137};
    138
    139struct mv3310_chip {
    140	bool (*has_downshift)(struct phy_device *phydev);
    141	void (*init_supported_interfaces)(unsigned long *mask);
    142	int (*get_mactype)(struct phy_device *phydev);
    143	int (*init_interface)(struct phy_device *phydev, int mactype);
    144
    145#ifdef CONFIG_HWMON
    146	int (*hwmon_read_temp_reg)(struct phy_device *phydev);
    147#endif
    148};
    149
    150struct mv3310_priv {
    151	DECLARE_BITMAP(supported_interfaces, PHY_INTERFACE_MODE_MAX);
    152
    153	u32 firmware_ver;
    154	bool has_downshift;
    155	bool rate_match;
    156	phy_interface_t const_interface;
    157
    158	struct device *hwmon_dev;
    159	char *hwmon_name;
    160};
    161
    162static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev)
    163{
    164	return phydev->drv->driver_data;
    165}
    166
    167#ifdef CONFIG_HWMON
    168static umode_t mv3310_hwmon_is_visible(const void *data,
    169				       enum hwmon_sensor_types type,
    170				       u32 attr, int channel)
    171{
    172	if (type == hwmon_chip && attr == hwmon_chip_update_interval)
    173		return 0444;
    174	if (type == hwmon_temp && attr == hwmon_temp_input)
    175		return 0444;
    176	return 0;
    177}
    178
    179static int mv3310_hwmon_read_temp_reg(struct phy_device *phydev)
    180{
    181	return phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP);
    182}
    183
    184static int mv2110_hwmon_read_temp_reg(struct phy_device *phydev)
    185{
    186	return phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_TEMP);
    187}
    188
    189static int mv3310_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
    190			     u32 attr, int channel, long *value)
    191{
    192	struct phy_device *phydev = dev_get_drvdata(dev);
    193	const struct mv3310_chip *chip = to_mv3310_chip(phydev);
    194	int temp;
    195
    196	if (type == hwmon_chip && attr == hwmon_chip_update_interval) {
    197		*value = MSEC_PER_SEC;
    198		return 0;
    199	}
    200
    201	if (type == hwmon_temp && attr == hwmon_temp_input) {
    202		temp = chip->hwmon_read_temp_reg(phydev);
    203		if (temp < 0)
    204			return temp;
    205
    206		*value = ((temp & 0xff) - 75) * 1000;
    207
    208		return 0;
    209	}
    210
    211	return -EOPNOTSUPP;
    212}
    213
    214static const struct hwmon_ops mv3310_hwmon_ops = {
    215	.is_visible = mv3310_hwmon_is_visible,
    216	.read = mv3310_hwmon_read,
    217};
    218
    219static u32 mv3310_hwmon_chip_config[] = {
    220	HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL,
    221	0,
    222};
    223
    224static const struct hwmon_channel_info mv3310_hwmon_chip = {
    225	.type = hwmon_chip,
    226	.config = mv3310_hwmon_chip_config,
    227};
    228
    229static u32 mv3310_hwmon_temp_config[] = {
    230	HWMON_T_INPUT,
    231	0,
    232};
    233
    234static const struct hwmon_channel_info mv3310_hwmon_temp = {
    235	.type = hwmon_temp,
    236	.config = mv3310_hwmon_temp_config,
    237};
    238
    239static const struct hwmon_channel_info *mv3310_hwmon_info[] = {
    240	&mv3310_hwmon_chip,
    241	&mv3310_hwmon_temp,
    242	NULL,
    243};
    244
    245static const struct hwmon_chip_info mv3310_hwmon_chip_info = {
    246	.ops = &mv3310_hwmon_ops,
    247	.info = mv3310_hwmon_info,
    248};
    249
    250static int mv3310_hwmon_config(struct phy_device *phydev, bool enable)
    251{
    252	u16 val;
    253	int ret;
    254
    255	if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310)
    256		return 0;
    257
    258	ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP,
    259			    MV_V2_TEMP_UNKNOWN);
    260	if (ret < 0)
    261		return ret;
    262
    263	val = enable ? MV_V2_TEMP_CTRL_SAMPLE : MV_V2_TEMP_CTRL_DISABLE;
    264
    265	return phy_modify_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP_CTRL,
    266			      MV_V2_TEMP_CTRL_MASK, val);
    267}
    268
    269static int mv3310_hwmon_probe(struct phy_device *phydev)
    270{
    271	struct device *dev = &phydev->mdio.dev;
    272	struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
    273	int i, j, ret;
    274
    275	priv->hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
    276	if (!priv->hwmon_name)
    277		return -ENODEV;
    278
    279	for (i = j = 0; priv->hwmon_name[i]; i++) {
    280		if (isalnum(priv->hwmon_name[i])) {
    281			if (i != j)
    282				priv->hwmon_name[j] = priv->hwmon_name[i];
    283			j++;
    284		}
    285	}
    286	priv->hwmon_name[j] = '\0';
    287
    288	ret = mv3310_hwmon_config(phydev, true);
    289	if (ret)
    290		return ret;
    291
    292	priv->hwmon_dev = devm_hwmon_device_register_with_info(dev,
    293				priv->hwmon_name, phydev,
    294				&mv3310_hwmon_chip_info, NULL);
    295
    296	return PTR_ERR_OR_ZERO(priv->hwmon_dev);
    297}
    298#else
    299static inline int mv3310_hwmon_config(struct phy_device *phydev, bool enable)
    300{
    301	return 0;
    302}
    303
    304static int mv3310_hwmon_probe(struct phy_device *phydev)
    305{
    306	return 0;
    307}
    308#endif
    309
    310static int mv3310_power_down(struct phy_device *phydev)
    311{
    312	return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
    313				MV_V2_PORT_CTRL_PWRDOWN);
    314}
    315
    316static int mv3310_power_up(struct phy_device *phydev)
    317{
    318	struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
    319	int ret;
    320
    321	ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
    322				 MV_V2_PORT_CTRL_PWRDOWN);
    323
    324	if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310 ||
    325	    priv->firmware_ver < 0x00030000)
    326		return ret;
    327
    328	return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
    329				MV_V2_33X0_PORT_CTRL_SWRST);
    330}
    331
    332static int mv3310_reset(struct phy_device *phydev, u32 unit)
    333{
    334	int val, err;
    335
    336	err = phy_modify_mmd(phydev, MDIO_MMD_PCS, unit + MDIO_CTRL1,
    337			     MDIO_CTRL1_RESET, MDIO_CTRL1_RESET);
    338	if (err < 0)
    339		return err;
    340
    341	return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PCS,
    342					 unit + MDIO_CTRL1, val,
    343					 !(val & MDIO_CTRL1_RESET),
    344					 5000, 100000, true);
    345}
    346
    347static int mv3310_get_downshift(struct phy_device *phydev, u8 *ds)
    348{
    349	struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
    350	int val;
    351
    352	if (!priv->has_downshift)
    353		return -EOPNOTSUPP;
    354
    355	val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_DSC1);
    356	if (val < 0)
    357		return val;
    358
    359	if (val & MV_PCS_DSC1_ENABLE)
    360		/* assume that all fields are the same */
    361		*ds = 1 + FIELD_GET(MV_PCS_DSC1_10GBT, (u16)val);
    362	else
    363		*ds = DOWNSHIFT_DEV_DISABLE;
    364
    365	return 0;
    366}
    367
    368static int mv3310_set_downshift(struct phy_device *phydev, u8 ds)
    369{
    370	struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
    371	u16 val;
    372	int err;
    373
    374	if (!priv->has_downshift)
    375		return -EOPNOTSUPP;
    376
    377	if (ds == DOWNSHIFT_DEV_DISABLE)
    378		return phy_clear_bits_mmd(phydev, MDIO_MMD_PCS, MV_PCS_DSC1,
    379					  MV_PCS_DSC1_ENABLE);
    380
    381	/* DOWNSHIFT_DEV_DEFAULT_COUNT is confusing. It looks like it should
    382	 * set the default settings for the PHY. However, it is used for
    383	 * "ethtool --set-phy-tunable ethN downshift on". The intention is
    384	 * to enable downshift at a default number of retries. The default
    385	 * settings for 88x3310 are for two retries with downshift disabled.
    386	 * So let's use two retries with downshift enabled.
    387	 */
    388	if (ds == DOWNSHIFT_DEV_DEFAULT_COUNT)
    389		ds = 2;
    390
    391	if (ds > 8)
    392		return -E2BIG;
    393
    394	ds -= 1;
    395	val = FIELD_PREP(MV_PCS_DSC2_2P5G, ds);
    396	val |= FIELD_PREP(MV_PCS_DSC2_5G, ds);
    397	err = phy_modify_mmd(phydev, MDIO_MMD_PCS, MV_PCS_DSC2,
    398			     MV_PCS_DSC2_2P5G | MV_PCS_DSC2_5G, val);
    399	if (err < 0)
    400		return err;
    401
    402	val = MV_PCS_DSC1_ENABLE;
    403	val |= FIELD_PREP(MV_PCS_DSC1_10GBT, ds);
    404	val |= FIELD_PREP(MV_PCS_DSC1_1GBR, ds);
    405	val |= FIELD_PREP(MV_PCS_DSC1_100BTX, ds);
    406
    407	return phy_modify_mmd(phydev, MDIO_MMD_PCS, MV_PCS_DSC1,
    408			      MV_PCS_DSC1_ENABLE | MV_PCS_DSC1_10GBT |
    409			      MV_PCS_DSC1_1GBR | MV_PCS_DSC1_100BTX, val);
    410}
    411
    412static int mv3310_get_edpd(struct phy_device *phydev, u16 *edpd)
    413{
    414	int val;
    415
    416	val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1);
    417	if (val < 0)
    418		return val;
    419
    420	switch (val & MV_PCS_CSCR1_ED_MASK) {
    421	case MV_PCS_CSCR1_ED_NLP:
    422		*edpd = 1000;
    423		break;
    424	case MV_PCS_CSCR1_ED_RX:
    425		*edpd = ETHTOOL_PHY_EDPD_NO_TX;
    426		break;
    427	default:
    428		*edpd = ETHTOOL_PHY_EDPD_DISABLE;
    429		break;
    430	}
    431	return 0;
    432}
    433
    434static int mv3310_set_edpd(struct phy_device *phydev, u16 edpd)
    435{
    436	u16 val;
    437	int err;
    438
    439	switch (edpd) {
    440	case 1000:
    441	case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS:
    442		val = MV_PCS_CSCR1_ED_NLP;
    443		break;
    444
    445	case ETHTOOL_PHY_EDPD_NO_TX:
    446		val = MV_PCS_CSCR1_ED_RX;
    447		break;
    448
    449	case ETHTOOL_PHY_EDPD_DISABLE:
    450		val = MV_PCS_CSCR1_ED_OFF;
    451		break;
    452
    453	default:
    454		return -EINVAL;
    455	}
    456
    457	err = phy_modify_mmd_changed(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1,
    458				     MV_PCS_CSCR1_ED_MASK, val);
    459	if (err > 0)
    460		err = mv3310_reset(phydev, MV_PCS_BASE_T);
    461
    462	return err;
    463}
    464
    465static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
    466{
    467	struct phy_device *phydev = upstream;
    468	__ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
    469	phy_interface_t iface;
    470
    471	sfp_parse_support(phydev->sfp_bus, id, support);
    472	iface = sfp_select_interface(phydev->sfp_bus, support);
    473
    474	if (iface != PHY_INTERFACE_MODE_10GBASER) {
    475		dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
    476		return -EINVAL;
    477	}
    478	return 0;
    479}
    480
    481static const struct sfp_upstream_ops mv3310_sfp_ops = {
    482	.attach = phy_sfp_attach,
    483	.detach = phy_sfp_detach,
    484	.module_insert = mv3310_sfp_insert,
    485};
    486
    487static int mv3310_probe(struct phy_device *phydev)
    488{
    489	const struct mv3310_chip *chip = to_mv3310_chip(phydev);
    490	struct mv3310_priv *priv;
    491	u32 mmd_mask = MDIO_DEVS_PMAPMD | MDIO_DEVS_AN;
    492	int ret;
    493
    494	if (!phydev->is_c45 ||
    495	    (phydev->c45_ids.devices_in_package & mmd_mask) != mmd_mask)
    496		return -ENODEV;
    497
    498	ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_BOOT);
    499	if (ret < 0)
    500		return ret;
    501
    502	if (ret & MV_PMA_BOOT_FATAL) {
    503		dev_warn(&phydev->mdio.dev,
    504			 "PHY failed to boot firmware, status=%04x\n", ret);
    505		return -ENODEV;
    506	}
    507
    508	priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
    509	if (!priv)
    510		return -ENOMEM;
    511
    512	dev_set_drvdata(&phydev->mdio.dev, priv);
    513
    514	ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_FW_VER0);
    515	if (ret < 0)
    516		return ret;
    517
    518	priv->firmware_ver = ret << 16;
    519
    520	ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_FW_VER1);
    521	if (ret < 0)
    522		return ret;
    523
    524	priv->firmware_ver |= ret;
    525
    526	phydev_info(phydev, "Firmware version %u.%u.%u.%u\n",
    527		    priv->firmware_ver >> 24, (priv->firmware_ver >> 16) & 255,
    528		    (priv->firmware_ver >> 8) & 255, priv->firmware_ver & 255);
    529
    530	if (chip->has_downshift)
    531		priv->has_downshift = chip->has_downshift(phydev);
    532
    533	/* Powering down the port when not in use saves about 600mW */
    534	ret = mv3310_power_down(phydev);
    535	if (ret)
    536		return ret;
    537
    538	ret = mv3310_hwmon_probe(phydev);
    539	if (ret)
    540		return ret;
    541
    542	chip->init_supported_interfaces(priv->supported_interfaces);
    543
    544	return phy_sfp_probe(phydev, &mv3310_sfp_ops);
    545}
    546
    547static void mv3310_remove(struct phy_device *phydev)
    548{
    549	mv3310_hwmon_config(phydev, false);
    550}
    551
    552static int mv3310_suspend(struct phy_device *phydev)
    553{
    554	return mv3310_power_down(phydev);
    555}
    556
    557static int mv3310_resume(struct phy_device *phydev)
    558{
    559	int ret;
    560
    561	ret = mv3310_power_up(phydev);
    562	if (ret)
    563		return ret;
    564
    565	return mv3310_hwmon_config(phydev, true);
    566}
    567
    568/* Some PHYs in the Alaska family such as the 88X3310 and the 88E2010
    569 * don't set bit 14 in PMA Extended Abilities (1.11), although they do
    570 * support 2.5GBASET and 5GBASET. For these models, we can still read their
    571 * 2.5G/5G extended abilities register (1.21). We detect these models based on
    572 * the PMA device identifier, with a mask matching models known to have this
    573 * issue
    574 */
    575static bool mv3310_has_pma_ngbaset_quirk(struct phy_device *phydev)
    576{
    577	if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_PMAPMD))
    578		return false;
    579
    580	/* Only some revisions of the 88X3310 family PMA seem to be impacted */
    581	return (phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
    582		MV_PHY_ALASKA_NBT_QUIRK_MASK) == MV_PHY_ALASKA_NBT_QUIRK_REV;
    583}
    584
    585static int mv2110_get_mactype(struct phy_device *phydev)
    586{
    587	int mactype;
    588
    589	mactype = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_21X0_PORT_CTRL);
    590	if (mactype < 0)
    591		return mactype;
    592
    593	return mactype & MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK;
    594}
    595
    596static int mv3310_get_mactype(struct phy_device *phydev)
    597{
    598	int mactype;
    599
    600	mactype = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL);
    601	if (mactype < 0)
    602		return mactype;
    603
    604	return mactype & MV_V2_33X0_PORT_CTRL_MACTYPE_MASK;
    605}
    606
    607static int mv2110_init_interface(struct phy_device *phydev, int mactype)
    608{
    609	struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
    610
    611	priv->rate_match = false;
    612
    613	if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
    614		priv->rate_match = true;
    615
    616	if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII)
    617		priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
    618	else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
    619		priv->const_interface = PHY_INTERFACE_MODE_10GBASER;
    620	else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER ||
    621		 mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN)
    622		priv->const_interface = PHY_INTERFACE_MODE_NA;
    623	else
    624		return -EINVAL;
    625
    626	return 0;
    627}
    628
    629static int mv3310_init_interface(struct phy_device *phydev, int mactype)
    630{
    631	struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
    632
    633	priv->rate_match = false;
    634
    635	if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
    636	    mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
    637	    mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH)
    638		priv->rate_match = true;
    639
    640	if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII)
    641		priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
    642	else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
    643		 mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN ||
    644		 mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER)
    645		priv->const_interface = PHY_INTERFACE_MODE_10GBASER;
    646	else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
    647		 mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI)
    648		priv->const_interface = PHY_INTERFACE_MODE_RXAUI;
    649	else if (mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH ||
    650		 mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI)
    651		priv->const_interface = PHY_INTERFACE_MODE_XAUI;
    652	else
    653		return -EINVAL;
    654
    655	return 0;
    656}
    657
    658static int mv3340_init_interface(struct phy_device *phydev, int mactype)
    659{
    660	struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
    661	int err = 0;
    662
    663	priv->rate_match = false;
    664
    665	if (mactype == MV_V2_3340_PORT_CTRL_MACTYPE_RXAUI_NO_SGMII_AN)
    666		priv->const_interface = PHY_INTERFACE_MODE_RXAUI;
    667	else
    668		err = mv3310_init_interface(phydev, mactype);
    669
    670	return err;
    671}
    672
    673static int mv3310_config_init(struct phy_device *phydev)
    674{
    675	struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
    676	const struct mv3310_chip *chip = to_mv3310_chip(phydev);
    677	int err, mactype;
    678
    679	/* Check that the PHY interface type is compatible */
    680	if (!test_bit(phydev->interface, priv->supported_interfaces))
    681		return -ENODEV;
    682
    683	phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
    684
    685	/* Power up so reset works */
    686	err = mv3310_power_up(phydev);
    687	if (err)
    688		return err;
    689
    690	mactype = chip->get_mactype(phydev);
    691	if (mactype < 0)
    692		return mactype;
    693
    694	err = chip->init_interface(phydev, mactype);
    695	if (err) {
    696		phydev_err(phydev, "MACTYPE configuration invalid\n");
    697		return err;
    698	}
    699
    700	/* Enable EDPD mode - saving 600mW */
    701	err = mv3310_set_edpd(phydev, ETHTOOL_PHY_EDPD_DFLT_TX_MSECS);
    702	if (err)
    703		return err;
    704
    705	/* Allow downshift */
    706	err = mv3310_set_downshift(phydev, DOWNSHIFT_DEV_DEFAULT_COUNT);
    707	if (err && err != -EOPNOTSUPP)
    708		return err;
    709
    710	return 0;
    711}
    712
    713static int mv3310_get_features(struct phy_device *phydev)
    714{
    715	int ret, val;
    716
    717	ret = genphy_c45_pma_read_abilities(phydev);
    718	if (ret)
    719		return ret;
    720
    721	if (mv3310_has_pma_ngbaset_quirk(phydev)) {
    722		val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
    723				   MDIO_PMA_NG_EXTABLE);
    724		if (val < 0)
    725			return val;
    726
    727		linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
    728				 phydev->supported,
    729				 val & MDIO_PMA_NG_EXTABLE_2_5GBT);
    730
    731		linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
    732				 phydev->supported,
    733				 val & MDIO_PMA_NG_EXTABLE_5GBT);
    734	}
    735
    736	return 0;
    737}
    738
    739static int mv3310_config_mdix(struct phy_device *phydev)
    740{
    741	u16 val;
    742	int err;
    743
    744	switch (phydev->mdix_ctrl) {
    745	case ETH_TP_MDI_AUTO:
    746		val = MV_PCS_CSCR1_MDIX_AUTO;
    747		break;
    748	case ETH_TP_MDI_X:
    749		val = MV_PCS_CSCR1_MDIX_MDIX;
    750		break;
    751	case ETH_TP_MDI:
    752		val = MV_PCS_CSCR1_MDIX_MDI;
    753		break;
    754	default:
    755		return -EINVAL;
    756	}
    757
    758	err = phy_modify_mmd_changed(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1,
    759				     MV_PCS_CSCR1_MDIX_MASK, val);
    760	if (err > 0)
    761		err = mv3310_reset(phydev, MV_PCS_BASE_T);
    762
    763	return err;
    764}
    765
    766static int mv3310_config_aneg(struct phy_device *phydev)
    767{
    768	bool changed = false;
    769	u16 reg;
    770	int ret;
    771
    772	ret = mv3310_config_mdix(phydev);
    773	if (ret < 0)
    774		return ret;
    775
    776	if (phydev->autoneg == AUTONEG_DISABLE)
    777		return genphy_c45_pma_setup_forced(phydev);
    778
    779	ret = genphy_c45_an_config_aneg(phydev);
    780	if (ret < 0)
    781		return ret;
    782	if (ret > 0)
    783		changed = true;
    784
    785	/* Clause 45 has no standardized support for 1000BaseT, therefore
    786	 * use vendor registers for this mode.
    787	 */
    788	reg = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
    789	ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MV_AN_CTRL1000,
    790			     ADVERTISE_1000FULL | ADVERTISE_1000HALF, reg);
    791	if (ret < 0)
    792		return ret;
    793	if (ret > 0)
    794		changed = true;
    795
    796	return genphy_c45_check_and_restart_aneg(phydev, changed);
    797}
    798
    799static int mv3310_aneg_done(struct phy_device *phydev)
    800{
    801	int val;
    802
    803	val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_BASE_R + MDIO_STAT1);
    804	if (val < 0)
    805		return val;
    806
    807	if (val & MDIO_STAT1_LSTATUS)
    808		return 1;
    809
    810	return genphy_c45_aneg_done(phydev);
    811}
    812
    813static void mv3310_update_interface(struct phy_device *phydev)
    814{
    815	struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
    816
    817	if (!phydev->link)
    818		return;
    819
    820	/* In all of the "* with Rate Matching" modes the PHY interface is fixed
    821	 * at 10Gb. The PHY adapts the rate to actual wire speed with help of
    822	 * internal 16KB buffer.
    823	 *
    824	 * In USXGMII mode the PHY interface mode is also fixed.
    825	 */
    826	if (priv->rate_match ||
    827	    priv->const_interface == PHY_INTERFACE_MODE_USXGMII) {
    828		phydev->interface = priv->const_interface;
    829		return;
    830	}
    831
    832	/* The PHY automatically switches its serdes interface (and active PHYXS
    833	 * instance) between Cisco SGMII, 2500BaseX, 5GBase-R and 10GBase-R /
    834	 * xaui / rxaui modes according to the speed.
    835	 * Florian suggests setting phydev->interface to communicate this to the
    836	 * MAC. Only do this if we are already in one of the above modes.
    837	 */
    838	switch (phydev->speed) {
    839	case SPEED_10000:
    840		phydev->interface = priv->const_interface;
    841		break;
    842	case SPEED_5000:
    843		phydev->interface = PHY_INTERFACE_MODE_5GBASER;
    844		break;
    845	case SPEED_2500:
    846		phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
    847		break;
    848	case SPEED_1000:
    849	case SPEED_100:
    850	case SPEED_10:
    851		phydev->interface = PHY_INTERFACE_MODE_SGMII;
    852		break;
    853	default:
    854		break;
    855	}
    856}
    857
    858/* 10GBASE-ER,LR,LRM,SR do not support autonegotiation. */
    859static int mv3310_read_status_10gbaser(struct phy_device *phydev)
    860{
    861	phydev->link = 1;
    862	phydev->speed = SPEED_10000;
    863	phydev->duplex = DUPLEX_FULL;
    864	phydev->port = PORT_FIBRE;
    865
    866	return 0;
    867}
    868
    869static int mv3310_read_status_copper(struct phy_device *phydev)
    870{
    871	int cssr1, speed, val;
    872
    873	val = genphy_c45_read_link(phydev);
    874	if (val < 0)
    875		return val;
    876
    877	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
    878	if (val < 0)
    879		return val;
    880
    881	cssr1 = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSSR1);
    882	if (cssr1 < 0)
    883		return cssr1;
    884
    885	/* If the link settings are not resolved, mark the link down */
    886	if (!(cssr1 & MV_PCS_CSSR1_RESOLVED)) {
    887		phydev->link = 0;
    888		return 0;
    889	}
    890
    891	/* Read the copper link settings */
    892	speed = cssr1 & MV_PCS_CSSR1_SPD1_MASK;
    893	if (speed == MV_PCS_CSSR1_SPD1_SPD2)
    894		speed |= cssr1 & MV_PCS_CSSR1_SPD2_MASK;
    895
    896	switch (speed) {
    897	case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_10000:
    898		phydev->speed = SPEED_10000;
    899		break;
    900
    901	case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_5000:
    902		phydev->speed = SPEED_5000;
    903		break;
    904
    905	case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_2500:
    906		phydev->speed = SPEED_2500;
    907		break;
    908
    909	case MV_PCS_CSSR1_SPD1_1000:
    910		phydev->speed = SPEED_1000;
    911		break;
    912
    913	case MV_PCS_CSSR1_SPD1_100:
    914		phydev->speed = SPEED_100;
    915		break;
    916
    917	case MV_PCS_CSSR1_SPD1_10:
    918		phydev->speed = SPEED_10;
    919		break;
    920	}
    921
    922	phydev->duplex = cssr1 & MV_PCS_CSSR1_DUPLEX_FULL ?
    923			 DUPLEX_FULL : DUPLEX_HALF;
    924	phydev->port = PORT_TP;
    925	phydev->mdix = cssr1 & MV_PCS_CSSR1_MDIX ?
    926		       ETH_TP_MDI_X : ETH_TP_MDI;
    927
    928	if (val & MDIO_AN_STAT1_COMPLETE) {
    929		val = genphy_c45_read_lpa(phydev);
    930		if (val < 0)
    931			return val;
    932
    933		/* Read the link partner's 1G advertisement */
    934		val = phy_read_mmd(phydev, MDIO_MMD_AN, MV_AN_STAT1000);
    935		if (val < 0)
    936			return val;
    937
    938		mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
    939
    940		/* Update the pause status */
    941		phy_resolve_aneg_pause(phydev);
    942	}
    943
    944	return 0;
    945}
    946
    947static int mv3310_read_status(struct phy_device *phydev)
    948{
    949	int err, val;
    950
    951	phydev->speed = SPEED_UNKNOWN;
    952	phydev->duplex = DUPLEX_UNKNOWN;
    953	linkmode_zero(phydev->lp_advertising);
    954	phydev->link = 0;
    955	phydev->pause = 0;
    956	phydev->asym_pause = 0;
    957	phydev->mdix = ETH_TP_MDI_INVALID;
    958
    959	val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_BASE_R + MDIO_STAT1);
    960	if (val < 0)
    961		return val;
    962
    963	if (val & MDIO_STAT1_LSTATUS)
    964		err = mv3310_read_status_10gbaser(phydev);
    965	else
    966		err = mv3310_read_status_copper(phydev);
    967	if (err < 0)
    968		return err;
    969
    970	if (phydev->link)
    971		mv3310_update_interface(phydev);
    972
    973	return 0;
    974}
    975
    976static int mv3310_get_tunable(struct phy_device *phydev,
    977			      struct ethtool_tunable *tuna, void *data)
    978{
    979	switch (tuna->id) {
    980	case ETHTOOL_PHY_DOWNSHIFT:
    981		return mv3310_get_downshift(phydev, data);
    982	case ETHTOOL_PHY_EDPD:
    983		return mv3310_get_edpd(phydev, data);
    984	default:
    985		return -EOPNOTSUPP;
    986	}
    987}
    988
    989static int mv3310_set_tunable(struct phy_device *phydev,
    990			      struct ethtool_tunable *tuna, const void *data)
    991{
    992	switch (tuna->id) {
    993	case ETHTOOL_PHY_DOWNSHIFT:
    994		return mv3310_set_downshift(phydev, *(u8 *)data);
    995	case ETHTOOL_PHY_EDPD:
    996		return mv3310_set_edpd(phydev, *(u16 *)data);
    997	default:
    998		return -EOPNOTSUPP;
    999	}
   1000}
   1001
   1002static bool mv3310_has_downshift(struct phy_device *phydev)
   1003{
   1004	struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
   1005
   1006	/* Fails to downshift with firmware older than v0.3.5.0 */
   1007	return priv->firmware_ver >= MV_VERSION(0,3,5,0);
   1008}
   1009
   1010static void mv3310_init_supported_interfaces(unsigned long *mask)
   1011{
   1012	__set_bit(PHY_INTERFACE_MODE_SGMII, mask);
   1013	__set_bit(PHY_INTERFACE_MODE_2500BASEX, mask);
   1014	__set_bit(PHY_INTERFACE_MODE_5GBASER, mask);
   1015	__set_bit(PHY_INTERFACE_MODE_XAUI, mask);
   1016	__set_bit(PHY_INTERFACE_MODE_RXAUI, mask);
   1017	__set_bit(PHY_INTERFACE_MODE_10GBASER, mask);
   1018	__set_bit(PHY_INTERFACE_MODE_USXGMII, mask);
   1019}
   1020
   1021static void mv3340_init_supported_interfaces(unsigned long *mask)
   1022{
   1023	__set_bit(PHY_INTERFACE_MODE_SGMII, mask);
   1024	__set_bit(PHY_INTERFACE_MODE_2500BASEX, mask);
   1025	__set_bit(PHY_INTERFACE_MODE_5GBASER, mask);
   1026	__set_bit(PHY_INTERFACE_MODE_RXAUI, mask);
   1027	__set_bit(PHY_INTERFACE_MODE_10GBASER, mask);
   1028	__set_bit(PHY_INTERFACE_MODE_USXGMII, mask);
   1029}
   1030
   1031static void mv2110_init_supported_interfaces(unsigned long *mask)
   1032{
   1033	__set_bit(PHY_INTERFACE_MODE_SGMII, mask);
   1034	__set_bit(PHY_INTERFACE_MODE_2500BASEX, mask);
   1035	__set_bit(PHY_INTERFACE_MODE_5GBASER, mask);
   1036	__set_bit(PHY_INTERFACE_MODE_10GBASER, mask);
   1037	__set_bit(PHY_INTERFACE_MODE_USXGMII, mask);
   1038}
   1039
   1040static void mv2111_init_supported_interfaces(unsigned long *mask)
   1041{
   1042	__set_bit(PHY_INTERFACE_MODE_SGMII, mask);
   1043	__set_bit(PHY_INTERFACE_MODE_2500BASEX, mask);
   1044	__set_bit(PHY_INTERFACE_MODE_10GBASER, mask);
   1045	__set_bit(PHY_INTERFACE_MODE_USXGMII, mask);
   1046}
   1047
   1048static const struct mv3310_chip mv3310_type = {
   1049	.has_downshift = mv3310_has_downshift,
   1050	.init_supported_interfaces = mv3310_init_supported_interfaces,
   1051	.get_mactype = mv3310_get_mactype,
   1052	.init_interface = mv3310_init_interface,
   1053
   1054#ifdef CONFIG_HWMON
   1055	.hwmon_read_temp_reg = mv3310_hwmon_read_temp_reg,
   1056#endif
   1057};
   1058
   1059static const struct mv3310_chip mv3340_type = {
   1060	.has_downshift = mv3310_has_downshift,
   1061	.init_supported_interfaces = mv3340_init_supported_interfaces,
   1062	.get_mactype = mv3310_get_mactype,
   1063	.init_interface = mv3340_init_interface,
   1064
   1065#ifdef CONFIG_HWMON
   1066	.hwmon_read_temp_reg = mv3310_hwmon_read_temp_reg,
   1067#endif
   1068};
   1069
   1070static const struct mv3310_chip mv2110_type = {
   1071	.init_supported_interfaces = mv2110_init_supported_interfaces,
   1072	.get_mactype = mv2110_get_mactype,
   1073	.init_interface = mv2110_init_interface,
   1074
   1075#ifdef CONFIG_HWMON
   1076	.hwmon_read_temp_reg = mv2110_hwmon_read_temp_reg,
   1077#endif
   1078};
   1079
   1080static const struct mv3310_chip mv2111_type = {
   1081	.init_supported_interfaces = mv2111_init_supported_interfaces,
   1082	.get_mactype = mv2110_get_mactype,
   1083	.init_interface = mv2110_init_interface,
   1084
   1085#ifdef CONFIG_HWMON
   1086	.hwmon_read_temp_reg = mv2110_hwmon_read_temp_reg,
   1087#endif
   1088};
   1089
   1090static int mv3310_get_number_of_ports(struct phy_device *phydev)
   1091{
   1092	int ret;
   1093
   1094	ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_PORT_INFO);
   1095	if (ret < 0)
   1096		return ret;
   1097
   1098	ret &= MV_PCS_PORT_INFO_NPORTS_MASK;
   1099	ret >>= MV_PCS_PORT_INFO_NPORTS_SHIFT;
   1100
   1101	return ret + 1;
   1102}
   1103
   1104static int mv3310_match_phy_device(struct phy_device *phydev)
   1105{
   1106	if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
   1107	     MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310)
   1108		return 0;
   1109
   1110	return mv3310_get_number_of_ports(phydev) == 1;
   1111}
   1112
   1113static int mv3340_match_phy_device(struct phy_device *phydev)
   1114{
   1115	if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
   1116	     MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310)
   1117		return 0;
   1118
   1119	return mv3310_get_number_of_ports(phydev) == 4;
   1120}
   1121
   1122static int mv211x_match_phy_device(struct phy_device *phydev, bool has_5g)
   1123{
   1124	int val;
   1125
   1126	if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
   1127	     MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88E2110)
   1128		return 0;
   1129
   1130	val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_SPEED);
   1131	if (val < 0)
   1132		return val;
   1133
   1134	return !!(val & MDIO_PCS_SPEED_5G) == has_5g;
   1135}
   1136
   1137static int mv2110_match_phy_device(struct phy_device *phydev)
   1138{
   1139	return mv211x_match_phy_device(phydev, true);
   1140}
   1141
   1142static int mv2111_match_phy_device(struct phy_device *phydev)
   1143{
   1144	return mv211x_match_phy_device(phydev, false);
   1145}
   1146
   1147static void mv3110_get_wol(struct phy_device *phydev,
   1148			   struct ethtool_wolinfo *wol)
   1149{
   1150	int ret;
   1151
   1152	wol->supported = WAKE_MAGIC;
   1153	wol->wolopts = 0;
   1154
   1155	ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_WOL_CTRL);
   1156	if (ret < 0)
   1157		return;
   1158
   1159	if (ret & MV_V2_WOL_CTRL_MAGIC_PKT_EN)
   1160		wol->wolopts |= WAKE_MAGIC;
   1161}
   1162
   1163static int mv3110_set_wol(struct phy_device *phydev,
   1164			  struct ethtool_wolinfo *wol)
   1165{
   1166	int ret;
   1167
   1168	if (wol->wolopts & WAKE_MAGIC) {
   1169		/* Enable the WOL interrupt */
   1170		ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
   1171				       MV_V2_PORT_INTR_MASK,
   1172				       MV_V2_PORT_INTR_STS_WOL_EN);
   1173		if (ret < 0)
   1174			return ret;
   1175
   1176		/* Store the device address for the magic packet */
   1177		ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
   1178				    MV_V2_MAGIC_PKT_WORD2,
   1179				    ((phydev->attached_dev->dev_addr[5] << 8) |
   1180				    phydev->attached_dev->dev_addr[4]));
   1181		if (ret < 0)
   1182			return ret;
   1183
   1184		ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
   1185				    MV_V2_MAGIC_PKT_WORD1,
   1186				    ((phydev->attached_dev->dev_addr[3] << 8) |
   1187				    phydev->attached_dev->dev_addr[2]));
   1188		if (ret < 0)
   1189			return ret;
   1190
   1191		ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
   1192				    MV_V2_MAGIC_PKT_WORD0,
   1193				    ((phydev->attached_dev->dev_addr[1] << 8) |
   1194				    phydev->attached_dev->dev_addr[0]));
   1195		if (ret < 0)
   1196			return ret;
   1197
   1198		/* Clear WOL status and enable magic packet matching */
   1199		ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
   1200				       MV_V2_WOL_CTRL,
   1201				       MV_V2_WOL_CTRL_MAGIC_PKT_EN |
   1202				       MV_V2_WOL_CTRL_CLEAR_STS);
   1203		if (ret < 0)
   1204			return ret;
   1205	} else {
   1206		/* Disable magic packet matching & reset WOL status bit */
   1207		ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2,
   1208				     MV_V2_WOL_CTRL,
   1209				     MV_V2_WOL_CTRL_MAGIC_PKT_EN,
   1210				     MV_V2_WOL_CTRL_CLEAR_STS);
   1211		if (ret < 0)
   1212			return ret;
   1213	}
   1214
   1215	/* Reset the clear WOL status bit as it does not self-clear */
   1216	return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2,
   1217				  MV_V2_WOL_CTRL,
   1218				  MV_V2_WOL_CTRL_CLEAR_STS);
   1219}
   1220
   1221static struct phy_driver mv3310_drivers[] = {
   1222	{
   1223		.phy_id		= MARVELL_PHY_ID_88X3310,
   1224		.phy_id_mask	= MARVELL_PHY_ID_MASK,
   1225		.match_phy_device = mv3310_match_phy_device,
   1226		.name		= "mv88x3310",
   1227		.driver_data	= &mv3310_type,
   1228		.get_features	= mv3310_get_features,
   1229		.config_init	= mv3310_config_init,
   1230		.probe		= mv3310_probe,
   1231		.suspend	= mv3310_suspend,
   1232		.resume		= mv3310_resume,
   1233		.config_aneg	= mv3310_config_aneg,
   1234		.aneg_done	= mv3310_aneg_done,
   1235		.read_status	= mv3310_read_status,
   1236		.get_tunable	= mv3310_get_tunable,
   1237		.set_tunable	= mv3310_set_tunable,
   1238		.remove		= mv3310_remove,
   1239		.set_loopback	= genphy_c45_loopback,
   1240		.get_wol	= mv3110_get_wol,
   1241		.set_wol	= mv3110_set_wol,
   1242	},
   1243	{
   1244		.phy_id		= MARVELL_PHY_ID_88X3310,
   1245		.phy_id_mask	= MARVELL_PHY_ID_MASK,
   1246		.match_phy_device = mv3340_match_phy_device,
   1247		.name		= "mv88x3340",
   1248		.driver_data	= &mv3340_type,
   1249		.get_features	= mv3310_get_features,
   1250		.config_init	= mv3310_config_init,
   1251		.probe		= mv3310_probe,
   1252		.suspend	= mv3310_suspend,
   1253		.resume		= mv3310_resume,
   1254		.config_aneg	= mv3310_config_aneg,
   1255		.aneg_done	= mv3310_aneg_done,
   1256		.read_status	= mv3310_read_status,
   1257		.get_tunable	= mv3310_get_tunable,
   1258		.set_tunable	= mv3310_set_tunable,
   1259		.remove		= mv3310_remove,
   1260		.set_loopback	= genphy_c45_loopback,
   1261	},
   1262	{
   1263		.phy_id		= MARVELL_PHY_ID_88E2110,
   1264		.phy_id_mask	= MARVELL_PHY_ID_MASK,
   1265		.match_phy_device = mv2110_match_phy_device,
   1266		.name		= "mv88e2110",
   1267		.driver_data	= &mv2110_type,
   1268		.probe		= mv3310_probe,
   1269		.suspend	= mv3310_suspend,
   1270		.resume		= mv3310_resume,
   1271		.config_init	= mv3310_config_init,
   1272		.config_aneg	= mv3310_config_aneg,
   1273		.aneg_done	= mv3310_aneg_done,
   1274		.read_status	= mv3310_read_status,
   1275		.get_tunable	= mv3310_get_tunable,
   1276		.set_tunable	= mv3310_set_tunable,
   1277		.remove		= mv3310_remove,
   1278		.set_loopback	= genphy_c45_loopback,
   1279		.get_wol	= mv3110_get_wol,
   1280		.set_wol	= mv3110_set_wol,
   1281	},
   1282	{
   1283		.phy_id		= MARVELL_PHY_ID_88E2110,
   1284		.phy_id_mask	= MARVELL_PHY_ID_MASK,
   1285		.match_phy_device = mv2111_match_phy_device,
   1286		.name		= "mv88e2111",
   1287		.driver_data	= &mv2111_type,
   1288		.probe		= mv3310_probe,
   1289		.suspend	= mv3310_suspend,
   1290		.resume		= mv3310_resume,
   1291		.config_init	= mv3310_config_init,
   1292		.config_aneg	= mv3310_config_aneg,
   1293		.aneg_done	= mv3310_aneg_done,
   1294		.read_status	= mv3310_read_status,
   1295		.get_tunable	= mv3310_get_tunable,
   1296		.set_tunable	= mv3310_set_tunable,
   1297		.remove		= mv3310_remove,
   1298		.set_loopback	= genphy_c45_loopback,
   1299	},
   1300};
   1301
   1302module_phy_driver(mv3310_drivers);
   1303
   1304static struct mdio_device_id __maybe_unused mv3310_tbl[] = {
   1305	{ MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK },
   1306	{ MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK },
   1307	{ },
   1308};
   1309MODULE_DEVICE_TABLE(mdio, mv3310_tbl);
   1310MODULE_DESCRIPTION("Marvell Alaska X/M multi-gigabit Ethernet PHY driver");
   1311MODULE_LICENSE("GPL");