Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Marvell 10G 88x3310 PHY driver
0004  *
0005  * Based upon the ID registers, this PHY appears to be a mixture of IPs
0006  * from two different companies.
0007  *
0008  * There appears to be several different data paths through the PHY which
0009  * are automatically managed by the PHY.  The following has been determined
0010  * via observation and experimentation for a setup using single-lane Serdes:
0011  *
0012  *       SGMII PHYXS -- BASE-T PCS -- 10G PMA -- AN -- Copper (for <= 1G)
0013  *  10GBASE-KR PHYXS -- BASE-T PCS -- 10G PMA -- AN -- Copper (for 10G)
0014  *  10GBASE-KR PHYXS -- BASE-R PCS -- Fiber
0015  *
0016  * With XAUI, observation shows:
0017  *
0018  *        XAUI PHYXS -- <appropriate PCS as above>
0019  *
0020  * and no switching of the host interface mode occurs.
0021  *
0022  * If both the fiber and copper ports are connected, the first to gain
0023  * link takes priority and the other port is completely locked out.
0024  */
0025 #include <linux/bitfield.h>
0026 #include <linux/ctype.h>
0027 #include <linux/delay.h>
0028 #include <linux/hwmon.h>
0029 #include <linux/marvell_phy.h>
0030 #include <linux/phy.h>
0031 #include <linux/sfp.h>
0032 #include <linux/netdevice.h>
0033 
0034 #define MV_PHY_ALASKA_NBT_QUIRK_MASK    0xfffffffe
0035 #define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa)
0036 
0037 #define MV_VERSION(a,b,c,d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
0038 
0039 enum {
0040     MV_PMA_FW_VER0      = 0xc011,
0041     MV_PMA_FW_VER1      = 0xc012,
0042     MV_PMA_21X0_PORT_CTRL   = 0xc04a,
0043     MV_PMA_21X0_PORT_CTRL_SWRST             = BIT(15),
0044     MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK          = 0x7,
0045     MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII           = 0x0,
0046     MV_PMA_2180_PORT_CTRL_MACTYPE_DXGMII            = 0x1,
0047     MV_PMA_2180_PORT_CTRL_MACTYPE_QXGMII            = 0x2,
0048     MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER           = 0x4,
0049     MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN   = 0x5,
0050     MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH   = 0x6,
0051     MV_PMA_BOOT     = 0xc050,
0052     MV_PMA_BOOT_FATAL   = BIT(0),
0053 
0054     MV_PCS_BASE_T       = 0x0000,
0055     MV_PCS_BASE_R       = 0x1000,
0056     MV_PCS_1000BASEX    = 0x2000,
0057 
0058     MV_PCS_CSCR1        = 0x8000,
0059     MV_PCS_CSCR1_ED_MASK    = 0x0300,
0060     MV_PCS_CSCR1_ED_OFF = 0x0000,
0061     MV_PCS_CSCR1_ED_RX  = 0x0200,
0062     MV_PCS_CSCR1_ED_NLP = 0x0300,
0063     MV_PCS_CSCR1_MDIX_MASK  = 0x0060,
0064     MV_PCS_CSCR1_MDIX_MDI   = 0x0000,
0065     MV_PCS_CSCR1_MDIX_MDIX  = 0x0020,
0066     MV_PCS_CSCR1_MDIX_AUTO  = 0x0060,
0067 
0068     MV_PCS_DSC1     = 0x8003,
0069     MV_PCS_DSC1_ENABLE  = BIT(9),
0070     MV_PCS_DSC1_10GBT   = 0x01c0,
0071     MV_PCS_DSC1_1GBR    = 0x0038,
0072     MV_PCS_DSC1_100BTX  = 0x0007,
0073     MV_PCS_DSC2     = 0x8004,
0074     MV_PCS_DSC2_2P5G    = 0xf000,
0075     MV_PCS_DSC2_5G      = 0x0f00,
0076 
0077     MV_PCS_CSSR1        = 0x8008,
0078     MV_PCS_CSSR1_SPD1_MASK  = 0xc000,
0079     MV_PCS_CSSR1_SPD1_SPD2  = 0xc000,
0080     MV_PCS_CSSR1_SPD1_1000  = 0x8000,
0081     MV_PCS_CSSR1_SPD1_100   = 0x4000,
0082     MV_PCS_CSSR1_SPD1_10    = 0x0000,
0083     MV_PCS_CSSR1_DUPLEX_FULL= BIT(13),
0084     MV_PCS_CSSR1_RESOLVED   = BIT(11),
0085     MV_PCS_CSSR1_MDIX   = BIT(6),
0086     MV_PCS_CSSR1_SPD2_MASK  = 0x000c,
0087     MV_PCS_CSSR1_SPD2_5000  = 0x0008,
0088     MV_PCS_CSSR1_SPD2_2500  = 0x0004,
0089     MV_PCS_CSSR1_SPD2_10000 = 0x0000,
0090 
0091     /* Temperature read register (88E2110 only) */
0092     MV_PCS_TEMP     = 0x8042,
0093 
0094     /* Number of ports on the device */
0095     MV_PCS_PORT_INFO    = 0xd00d,
0096     MV_PCS_PORT_INFO_NPORTS_MASK    = 0x0380,
0097     MV_PCS_PORT_INFO_NPORTS_SHIFT   = 7,
0098 
0099     /* These registers appear at 0x800X and 0xa00X - the 0xa00X control
0100      * registers appear to set themselves to the 0x800X when AN is
0101      * restarted, but status registers appear readable from either.
0102      */
0103     MV_AN_CTRL1000      = 0x8000, /* 1000base-T control register */
0104     MV_AN_STAT1000      = 0x8001, /* 1000base-T status register */
0105 
0106     /* Vendor2 MMD registers */
0107     MV_V2_PORT_CTRL     = 0xf001,
0108     MV_V2_PORT_CTRL_PWRDOWN                 = BIT(11),
0109     MV_V2_33X0_PORT_CTRL_SWRST              = BIT(15),
0110     MV_V2_33X0_PORT_CTRL_MACTYPE_MASK           = 0x7,
0111     MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI          = 0x0,
0112     MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH        = 0x1,
0113     MV_V2_3340_PORT_CTRL_MACTYPE_RXAUI_NO_SGMII_AN      = 0x1,
0114     MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH       = 0x2,
0115     MV_V2_3310_PORT_CTRL_MACTYPE_XAUI           = 0x3,
0116     MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER           = 0x4,
0117     MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN   = 0x5,
0118     MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH    = 0x6,
0119     MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII            = 0x7,
0120     MV_V2_PORT_INTR_STS     = 0xf040,
0121     MV_V2_PORT_INTR_MASK    = 0xf043,
0122     MV_V2_PORT_INTR_STS_WOL_EN      = BIT(8),
0123     MV_V2_MAGIC_PKT_WORD0   = 0xf06b,
0124     MV_V2_MAGIC_PKT_WORD1   = 0xf06c,
0125     MV_V2_MAGIC_PKT_WORD2   = 0xf06d,
0126     /* Wake on LAN registers */
0127     MV_V2_WOL_CTRL          = 0xf06e,
0128     MV_V2_WOL_CTRL_CLEAR_STS        = BIT(15),
0129     MV_V2_WOL_CTRL_MAGIC_PKT_EN     = BIT(0),
0130     /* Temperature control/read registers (88X3310 only) */
0131     MV_V2_TEMP_CTRL     = 0xf08a,
0132     MV_V2_TEMP_CTRL_MASK    = 0xc000,
0133     MV_V2_TEMP_CTRL_SAMPLE  = 0x0000,
0134     MV_V2_TEMP_CTRL_DISABLE = 0xc000,
0135     MV_V2_TEMP      = 0xf08c,
0136     MV_V2_TEMP_UNKNOWN  = 0x9600, /* unknown function */
0137 };
0138 
0139 struct mv3310_chip {
0140     bool (*has_downshift)(struct phy_device *phydev);
0141     void (*init_supported_interfaces)(unsigned long *mask);
0142     int (*get_mactype)(struct phy_device *phydev);
0143     int (*init_interface)(struct phy_device *phydev, int mactype);
0144 
0145 #ifdef CONFIG_HWMON
0146     int (*hwmon_read_temp_reg)(struct phy_device *phydev);
0147 #endif
0148 };
0149 
0150 struct mv3310_priv {
0151     DECLARE_BITMAP(supported_interfaces, PHY_INTERFACE_MODE_MAX);
0152 
0153     u32 firmware_ver;
0154     bool has_downshift;
0155     bool rate_match;
0156     phy_interface_t const_interface;
0157 
0158     struct device *hwmon_dev;
0159     char *hwmon_name;
0160 };
0161 
0162 static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev)
0163 {
0164     return phydev->drv->driver_data;
0165 }
0166 
0167 #ifdef CONFIG_HWMON
0168 static umode_t mv3310_hwmon_is_visible(const void *data,
0169                        enum hwmon_sensor_types type,
0170                        u32 attr, int channel)
0171 {
0172     if (type == hwmon_chip && attr == hwmon_chip_update_interval)
0173         return 0444;
0174     if (type == hwmon_temp && attr == hwmon_temp_input)
0175         return 0444;
0176     return 0;
0177 }
0178 
0179 static int mv3310_hwmon_read_temp_reg(struct phy_device *phydev)
0180 {
0181     return phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP);
0182 }
0183 
0184 static int mv2110_hwmon_read_temp_reg(struct phy_device *phydev)
0185 {
0186     return phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_TEMP);
0187 }
0188 
0189 static int mv3310_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
0190                  u32 attr, int channel, long *value)
0191 {
0192     struct phy_device *phydev = dev_get_drvdata(dev);
0193     const struct mv3310_chip *chip = to_mv3310_chip(phydev);
0194     int temp;
0195 
0196     if (type == hwmon_chip && attr == hwmon_chip_update_interval) {
0197         *value = MSEC_PER_SEC;
0198         return 0;
0199     }
0200 
0201     if (type == hwmon_temp && attr == hwmon_temp_input) {
0202         temp = chip->hwmon_read_temp_reg(phydev);
0203         if (temp < 0)
0204             return temp;
0205 
0206         *value = ((temp & 0xff) - 75) * 1000;
0207 
0208         return 0;
0209     }
0210 
0211     return -EOPNOTSUPP;
0212 }
0213 
0214 static const struct hwmon_ops mv3310_hwmon_ops = {
0215     .is_visible = mv3310_hwmon_is_visible,
0216     .read = mv3310_hwmon_read,
0217 };
0218 
0219 static u32 mv3310_hwmon_chip_config[] = {
0220     HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL,
0221     0,
0222 };
0223 
0224 static const struct hwmon_channel_info mv3310_hwmon_chip = {
0225     .type = hwmon_chip,
0226     .config = mv3310_hwmon_chip_config,
0227 };
0228 
0229 static u32 mv3310_hwmon_temp_config[] = {
0230     HWMON_T_INPUT,
0231     0,
0232 };
0233 
0234 static const struct hwmon_channel_info mv3310_hwmon_temp = {
0235     .type = hwmon_temp,
0236     .config = mv3310_hwmon_temp_config,
0237 };
0238 
0239 static const struct hwmon_channel_info *mv3310_hwmon_info[] = {
0240     &mv3310_hwmon_chip,
0241     &mv3310_hwmon_temp,
0242     NULL,
0243 };
0244 
0245 static const struct hwmon_chip_info mv3310_hwmon_chip_info = {
0246     .ops = &mv3310_hwmon_ops,
0247     .info = mv3310_hwmon_info,
0248 };
0249 
0250 static int mv3310_hwmon_config(struct phy_device *phydev, bool enable)
0251 {
0252     u16 val;
0253     int ret;
0254 
0255     if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310)
0256         return 0;
0257 
0258     ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP,
0259                 MV_V2_TEMP_UNKNOWN);
0260     if (ret < 0)
0261         return ret;
0262 
0263     val = enable ? MV_V2_TEMP_CTRL_SAMPLE : MV_V2_TEMP_CTRL_DISABLE;
0264 
0265     return phy_modify_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP_CTRL,
0266                   MV_V2_TEMP_CTRL_MASK, val);
0267 }
0268 
0269 static int mv3310_hwmon_probe(struct phy_device *phydev)
0270 {
0271     struct device *dev = &phydev->mdio.dev;
0272     struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
0273     int i, j, ret;
0274 
0275     priv->hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
0276     if (!priv->hwmon_name)
0277         return -ENODEV;
0278 
0279     for (i = j = 0; priv->hwmon_name[i]; i++) {
0280         if (isalnum(priv->hwmon_name[i])) {
0281             if (i != j)
0282                 priv->hwmon_name[j] = priv->hwmon_name[i];
0283             j++;
0284         }
0285     }
0286     priv->hwmon_name[j] = '\0';
0287 
0288     ret = mv3310_hwmon_config(phydev, true);
0289     if (ret)
0290         return ret;
0291 
0292     priv->hwmon_dev = devm_hwmon_device_register_with_info(dev,
0293                 priv->hwmon_name, phydev,
0294                 &mv3310_hwmon_chip_info, NULL);
0295 
0296     return PTR_ERR_OR_ZERO(priv->hwmon_dev);
0297 }
0298 #else
0299 static inline int mv3310_hwmon_config(struct phy_device *phydev, bool enable)
0300 {
0301     return 0;
0302 }
0303 
0304 static int mv3310_hwmon_probe(struct phy_device *phydev)
0305 {
0306     return 0;
0307 }
0308 #endif
0309 
0310 static int mv3310_power_down(struct phy_device *phydev)
0311 {
0312     return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
0313                 MV_V2_PORT_CTRL_PWRDOWN);
0314 }
0315 
0316 static int mv3310_power_up(struct phy_device *phydev)
0317 {
0318     struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
0319     int ret;
0320 
0321     ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
0322                  MV_V2_PORT_CTRL_PWRDOWN);
0323 
0324     if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310 ||
0325         priv->firmware_ver < 0x00030000)
0326         return ret;
0327 
0328     return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
0329                 MV_V2_33X0_PORT_CTRL_SWRST);
0330 }
0331 
0332 static int mv3310_reset(struct phy_device *phydev, u32 unit)
0333 {
0334     int val, err;
0335 
0336     err = phy_modify_mmd(phydev, MDIO_MMD_PCS, unit + MDIO_CTRL1,
0337                  MDIO_CTRL1_RESET, MDIO_CTRL1_RESET);
0338     if (err < 0)
0339         return err;
0340 
0341     return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PCS,
0342                      unit + MDIO_CTRL1, val,
0343                      !(val & MDIO_CTRL1_RESET),
0344                      5000, 100000, true);
0345 }
0346 
0347 static int mv3310_get_downshift(struct phy_device *phydev, u8 *ds)
0348 {
0349     struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
0350     int val;
0351 
0352     if (!priv->has_downshift)
0353         return -EOPNOTSUPP;
0354 
0355     val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_DSC1);
0356     if (val < 0)
0357         return val;
0358 
0359     if (val & MV_PCS_DSC1_ENABLE)
0360         /* assume that all fields are the same */
0361         *ds = 1 + FIELD_GET(MV_PCS_DSC1_10GBT, (u16)val);
0362     else
0363         *ds = DOWNSHIFT_DEV_DISABLE;
0364 
0365     return 0;
0366 }
0367 
0368 static int mv3310_set_downshift(struct phy_device *phydev, u8 ds)
0369 {
0370     struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
0371     u16 val;
0372     int err;
0373 
0374     if (!priv->has_downshift)
0375         return -EOPNOTSUPP;
0376 
0377     if (ds == DOWNSHIFT_DEV_DISABLE)
0378         return phy_clear_bits_mmd(phydev, MDIO_MMD_PCS, MV_PCS_DSC1,
0379                       MV_PCS_DSC1_ENABLE);
0380 
0381     /* DOWNSHIFT_DEV_DEFAULT_COUNT is confusing. It looks like it should
0382      * set the default settings for the PHY. However, it is used for
0383      * "ethtool --set-phy-tunable ethN downshift on". The intention is
0384      * to enable downshift at a default number of retries. The default
0385      * settings for 88x3310 are for two retries with downshift disabled.
0386      * So let's use two retries with downshift enabled.
0387      */
0388     if (ds == DOWNSHIFT_DEV_DEFAULT_COUNT)
0389         ds = 2;
0390 
0391     if (ds > 8)
0392         return -E2BIG;
0393 
0394     ds -= 1;
0395     val = FIELD_PREP(MV_PCS_DSC2_2P5G, ds);
0396     val |= FIELD_PREP(MV_PCS_DSC2_5G, ds);
0397     err = phy_modify_mmd(phydev, MDIO_MMD_PCS, MV_PCS_DSC2,
0398                  MV_PCS_DSC2_2P5G | MV_PCS_DSC2_5G, val);
0399     if (err < 0)
0400         return err;
0401 
0402     val = MV_PCS_DSC1_ENABLE;
0403     val |= FIELD_PREP(MV_PCS_DSC1_10GBT, ds);
0404     val |= FIELD_PREP(MV_PCS_DSC1_1GBR, ds);
0405     val |= FIELD_PREP(MV_PCS_DSC1_100BTX, ds);
0406 
0407     return phy_modify_mmd(phydev, MDIO_MMD_PCS, MV_PCS_DSC1,
0408                   MV_PCS_DSC1_ENABLE | MV_PCS_DSC1_10GBT |
0409                   MV_PCS_DSC1_1GBR | MV_PCS_DSC1_100BTX, val);
0410 }
0411 
0412 static int mv3310_get_edpd(struct phy_device *phydev, u16 *edpd)
0413 {
0414     int val;
0415 
0416     val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1);
0417     if (val < 0)
0418         return val;
0419 
0420     switch (val & MV_PCS_CSCR1_ED_MASK) {
0421     case MV_PCS_CSCR1_ED_NLP:
0422         *edpd = 1000;
0423         break;
0424     case MV_PCS_CSCR1_ED_RX:
0425         *edpd = ETHTOOL_PHY_EDPD_NO_TX;
0426         break;
0427     default:
0428         *edpd = ETHTOOL_PHY_EDPD_DISABLE;
0429         break;
0430     }
0431     return 0;
0432 }
0433 
0434 static int mv3310_set_edpd(struct phy_device *phydev, u16 edpd)
0435 {
0436     u16 val;
0437     int err;
0438 
0439     switch (edpd) {
0440     case 1000:
0441     case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS:
0442         val = MV_PCS_CSCR1_ED_NLP;
0443         break;
0444 
0445     case ETHTOOL_PHY_EDPD_NO_TX:
0446         val = MV_PCS_CSCR1_ED_RX;
0447         break;
0448 
0449     case ETHTOOL_PHY_EDPD_DISABLE:
0450         val = MV_PCS_CSCR1_ED_OFF;
0451         break;
0452 
0453     default:
0454         return -EINVAL;
0455     }
0456 
0457     err = phy_modify_mmd_changed(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1,
0458                      MV_PCS_CSCR1_ED_MASK, val);
0459     if (err > 0)
0460         err = mv3310_reset(phydev, MV_PCS_BASE_T);
0461 
0462     return err;
0463 }
0464 
0465 static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
0466 {
0467     struct phy_device *phydev = upstream;
0468     __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
0469     phy_interface_t iface;
0470 
0471     sfp_parse_support(phydev->sfp_bus, id, support);
0472     iface = sfp_select_interface(phydev->sfp_bus, support);
0473 
0474     if (iface != PHY_INTERFACE_MODE_10GBASER) {
0475         dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
0476         return -EINVAL;
0477     }
0478     return 0;
0479 }
0480 
0481 static const struct sfp_upstream_ops mv3310_sfp_ops = {
0482     .attach = phy_sfp_attach,
0483     .detach = phy_sfp_detach,
0484     .module_insert = mv3310_sfp_insert,
0485 };
0486 
0487 static int mv3310_probe(struct phy_device *phydev)
0488 {
0489     const struct mv3310_chip *chip = to_mv3310_chip(phydev);
0490     struct mv3310_priv *priv;
0491     u32 mmd_mask = MDIO_DEVS_PMAPMD | MDIO_DEVS_AN;
0492     int ret;
0493 
0494     if (!phydev->is_c45 ||
0495         (phydev->c45_ids.devices_in_package & mmd_mask) != mmd_mask)
0496         return -ENODEV;
0497 
0498     ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_BOOT);
0499     if (ret < 0)
0500         return ret;
0501 
0502     if (ret & MV_PMA_BOOT_FATAL) {
0503         dev_warn(&phydev->mdio.dev,
0504              "PHY failed to boot firmware, status=%04x\n", ret);
0505         return -ENODEV;
0506     }
0507 
0508     priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
0509     if (!priv)
0510         return -ENOMEM;
0511 
0512     dev_set_drvdata(&phydev->mdio.dev, priv);
0513 
0514     ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_FW_VER0);
0515     if (ret < 0)
0516         return ret;
0517 
0518     priv->firmware_ver = ret << 16;
0519 
0520     ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_FW_VER1);
0521     if (ret < 0)
0522         return ret;
0523 
0524     priv->firmware_ver |= ret;
0525 
0526     phydev_info(phydev, "Firmware version %u.%u.%u.%u\n",
0527             priv->firmware_ver >> 24, (priv->firmware_ver >> 16) & 255,
0528             (priv->firmware_ver >> 8) & 255, priv->firmware_ver & 255);
0529 
0530     if (chip->has_downshift)
0531         priv->has_downshift = chip->has_downshift(phydev);
0532 
0533     /* Powering down the port when not in use saves about 600mW */
0534     ret = mv3310_power_down(phydev);
0535     if (ret)
0536         return ret;
0537 
0538     ret = mv3310_hwmon_probe(phydev);
0539     if (ret)
0540         return ret;
0541 
0542     chip->init_supported_interfaces(priv->supported_interfaces);
0543 
0544     return phy_sfp_probe(phydev, &mv3310_sfp_ops);
0545 }
0546 
0547 static void mv3310_remove(struct phy_device *phydev)
0548 {
0549     mv3310_hwmon_config(phydev, false);
0550 }
0551 
0552 static int mv3310_suspend(struct phy_device *phydev)
0553 {
0554     return mv3310_power_down(phydev);
0555 }
0556 
0557 static int mv3310_resume(struct phy_device *phydev)
0558 {
0559     int ret;
0560 
0561     ret = mv3310_power_up(phydev);
0562     if (ret)
0563         return ret;
0564 
0565     return mv3310_hwmon_config(phydev, true);
0566 }
0567 
0568 /* Some PHYs in the Alaska family such as the 88X3310 and the 88E2010
0569  * don't set bit 14 in PMA Extended Abilities (1.11), although they do
0570  * support 2.5GBASET and 5GBASET. For these models, we can still read their
0571  * 2.5G/5G extended abilities register (1.21). We detect these models based on
0572  * the PMA device identifier, with a mask matching models known to have this
0573  * issue
0574  */
0575 static bool mv3310_has_pma_ngbaset_quirk(struct phy_device *phydev)
0576 {
0577     if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_PMAPMD))
0578         return false;
0579 
0580     /* Only some revisions of the 88X3310 family PMA seem to be impacted */
0581     return (phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
0582         MV_PHY_ALASKA_NBT_QUIRK_MASK) == MV_PHY_ALASKA_NBT_QUIRK_REV;
0583 }
0584 
0585 static int mv2110_get_mactype(struct phy_device *phydev)
0586 {
0587     int mactype;
0588 
0589     mactype = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_21X0_PORT_CTRL);
0590     if (mactype < 0)
0591         return mactype;
0592 
0593     return mactype & MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK;
0594 }
0595 
0596 static int mv3310_get_mactype(struct phy_device *phydev)
0597 {
0598     int mactype;
0599 
0600     mactype = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL);
0601     if (mactype < 0)
0602         return mactype;
0603 
0604     return mactype & MV_V2_33X0_PORT_CTRL_MACTYPE_MASK;
0605 }
0606 
0607 static int mv2110_init_interface(struct phy_device *phydev, int mactype)
0608 {
0609     struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
0610 
0611     priv->rate_match = false;
0612 
0613     if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
0614         priv->rate_match = true;
0615 
0616     if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII)
0617         priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
0618     else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
0619         priv->const_interface = PHY_INTERFACE_MODE_10GBASER;
0620     else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER ||
0621          mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN)
0622         priv->const_interface = PHY_INTERFACE_MODE_NA;
0623     else
0624         return -EINVAL;
0625 
0626     return 0;
0627 }
0628 
0629 static int mv3310_init_interface(struct phy_device *phydev, int mactype)
0630 {
0631     struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
0632 
0633     priv->rate_match = false;
0634 
0635     if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
0636         mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
0637         mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH)
0638         priv->rate_match = true;
0639 
0640     if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII)
0641         priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
0642     else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
0643          mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN ||
0644          mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER)
0645         priv->const_interface = PHY_INTERFACE_MODE_10GBASER;
0646     else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
0647          mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI)
0648         priv->const_interface = PHY_INTERFACE_MODE_RXAUI;
0649     else if (mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH ||
0650          mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI)
0651         priv->const_interface = PHY_INTERFACE_MODE_XAUI;
0652     else
0653         return -EINVAL;
0654 
0655     return 0;
0656 }
0657 
0658 static int mv3340_init_interface(struct phy_device *phydev, int mactype)
0659 {
0660     struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
0661     int err = 0;
0662 
0663     priv->rate_match = false;
0664 
0665     if (mactype == MV_V2_3340_PORT_CTRL_MACTYPE_RXAUI_NO_SGMII_AN)
0666         priv->const_interface = PHY_INTERFACE_MODE_RXAUI;
0667     else
0668         err = mv3310_init_interface(phydev, mactype);
0669 
0670     return err;
0671 }
0672 
0673 static int mv3310_config_init(struct phy_device *phydev)
0674 {
0675     struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
0676     const struct mv3310_chip *chip = to_mv3310_chip(phydev);
0677     int err, mactype;
0678 
0679     /* Check that the PHY interface type is compatible */
0680     if (!test_bit(phydev->interface, priv->supported_interfaces))
0681         return -ENODEV;
0682 
0683     phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
0684 
0685     /* Power up so reset works */
0686     err = mv3310_power_up(phydev);
0687     if (err)
0688         return err;
0689 
0690     mactype = chip->get_mactype(phydev);
0691     if (mactype < 0)
0692         return mactype;
0693 
0694     err = chip->init_interface(phydev, mactype);
0695     if (err) {
0696         phydev_err(phydev, "MACTYPE configuration invalid\n");
0697         return err;
0698     }
0699 
0700     /* Enable EDPD mode - saving 600mW */
0701     err = mv3310_set_edpd(phydev, ETHTOOL_PHY_EDPD_DFLT_TX_MSECS);
0702     if (err)
0703         return err;
0704 
0705     /* Allow downshift */
0706     err = mv3310_set_downshift(phydev, DOWNSHIFT_DEV_DEFAULT_COUNT);
0707     if (err && err != -EOPNOTSUPP)
0708         return err;
0709 
0710     return 0;
0711 }
0712 
0713 static int mv3310_get_features(struct phy_device *phydev)
0714 {
0715     int ret, val;
0716 
0717     ret = genphy_c45_pma_read_abilities(phydev);
0718     if (ret)
0719         return ret;
0720 
0721     if (mv3310_has_pma_ngbaset_quirk(phydev)) {
0722         val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
0723                    MDIO_PMA_NG_EXTABLE);
0724         if (val < 0)
0725             return val;
0726 
0727         linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
0728                  phydev->supported,
0729                  val & MDIO_PMA_NG_EXTABLE_2_5GBT);
0730 
0731         linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
0732                  phydev->supported,
0733                  val & MDIO_PMA_NG_EXTABLE_5GBT);
0734     }
0735 
0736     return 0;
0737 }
0738 
0739 static int mv3310_config_mdix(struct phy_device *phydev)
0740 {
0741     u16 val;
0742     int err;
0743 
0744     switch (phydev->mdix_ctrl) {
0745     case ETH_TP_MDI_AUTO:
0746         val = MV_PCS_CSCR1_MDIX_AUTO;
0747         break;
0748     case ETH_TP_MDI_X:
0749         val = MV_PCS_CSCR1_MDIX_MDIX;
0750         break;
0751     case ETH_TP_MDI:
0752         val = MV_PCS_CSCR1_MDIX_MDI;
0753         break;
0754     default:
0755         return -EINVAL;
0756     }
0757 
0758     err = phy_modify_mmd_changed(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1,
0759                      MV_PCS_CSCR1_MDIX_MASK, val);
0760     if (err > 0)
0761         err = mv3310_reset(phydev, MV_PCS_BASE_T);
0762 
0763     return err;
0764 }
0765 
0766 static int mv3310_config_aneg(struct phy_device *phydev)
0767 {
0768     bool changed = false;
0769     u16 reg;
0770     int ret;
0771 
0772     ret = mv3310_config_mdix(phydev);
0773     if (ret < 0)
0774         return ret;
0775 
0776     if (phydev->autoneg == AUTONEG_DISABLE)
0777         return genphy_c45_pma_setup_forced(phydev);
0778 
0779     ret = genphy_c45_an_config_aneg(phydev);
0780     if (ret < 0)
0781         return ret;
0782     if (ret > 0)
0783         changed = true;
0784 
0785     /* Clause 45 has no standardized support for 1000BaseT, therefore
0786      * use vendor registers for this mode.
0787      */
0788     reg = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
0789     ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MV_AN_CTRL1000,
0790                  ADVERTISE_1000FULL | ADVERTISE_1000HALF, reg);
0791     if (ret < 0)
0792         return ret;
0793     if (ret > 0)
0794         changed = true;
0795 
0796     return genphy_c45_check_and_restart_aneg(phydev, changed);
0797 }
0798 
0799 static int mv3310_aneg_done(struct phy_device *phydev)
0800 {
0801     int val;
0802 
0803     val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_BASE_R + MDIO_STAT1);
0804     if (val < 0)
0805         return val;
0806 
0807     if (val & MDIO_STAT1_LSTATUS)
0808         return 1;
0809 
0810     return genphy_c45_aneg_done(phydev);
0811 }
0812 
0813 static void mv3310_update_interface(struct phy_device *phydev)
0814 {
0815     struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
0816 
0817     if (!phydev->link)
0818         return;
0819 
0820     /* In all of the "* with Rate Matching" modes the PHY interface is fixed
0821      * at 10Gb. The PHY adapts the rate to actual wire speed with help of
0822      * internal 16KB buffer.
0823      *
0824      * In USXGMII mode the PHY interface mode is also fixed.
0825      */
0826     if (priv->rate_match ||
0827         priv->const_interface == PHY_INTERFACE_MODE_USXGMII) {
0828         phydev->interface = priv->const_interface;
0829         return;
0830     }
0831 
0832     /* The PHY automatically switches its serdes interface (and active PHYXS
0833      * instance) between Cisco SGMII, 2500BaseX, 5GBase-R and 10GBase-R /
0834      * xaui / rxaui modes according to the speed.
0835      * Florian suggests setting phydev->interface to communicate this to the
0836      * MAC. Only do this if we are already in one of the above modes.
0837      */
0838     switch (phydev->speed) {
0839     case SPEED_10000:
0840         phydev->interface = priv->const_interface;
0841         break;
0842     case SPEED_5000:
0843         phydev->interface = PHY_INTERFACE_MODE_5GBASER;
0844         break;
0845     case SPEED_2500:
0846         phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
0847         break;
0848     case SPEED_1000:
0849     case SPEED_100:
0850     case SPEED_10:
0851         phydev->interface = PHY_INTERFACE_MODE_SGMII;
0852         break;
0853     default:
0854         break;
0855     }
0856 }
0857 
0858 /* 10GBASE-ER,LR,LRM,SR do not support autonegotiation. */
0859 static int mv3310_read_status_10gbaser(struct phy_device *phydev)
0860 {
0861     phydev->link = 1;
0862     phydev->speed = SPEED_10000;
0863     phydev->duplex = DUPLEX_FULL;
0864     phydev->port = PORT_FIBRE;
0865 
0866     return 0;
0867 }
0868 
0869 static int mv3310_read_status_copper(struct phy_device *phydev)
0870 {
0871     int cssr1, speed, val;
0872 
0873     val = genphy_c45_read_link(phydev);
0874     if (val < 0)
0875         return val;
0876 
0877     val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
0878     if (val < 0)
0879         return val;
0880 
0881     cssr1 = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSSR1);
0882     if (cssr1 < 0)
0883         return cssr1;
0884 
0885     /* If the link settings are not resolved, mark the link down */
0886     if (!(cssr1 & MV_PCS_CSSR1_RESOLVED)) {
0887         phydev->link = 0;
0888         return 0;
0889     }
0890 
0891     /* Read the copper link settings */
0892     speed = cssr1 & MV_PCS_CSSR1_SPD1_MASK;
0893     if (speed == MV_PCS_CSSR1_SPD1_SPD2)
0894         speed |= cssr1 & MV_PCS_CSSR1_SPD2_MASK;
0895 
0896     switch (speed) {
0897     case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_10000:
0898         phydev->speed = SPEED_10000;
0899         break;
0900 
0901     case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_5000:
0902         phydev->speed = SPEED_5000;
0903         break;
0904 
0905     case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_2500:
0906         phydev->speed = SPEED_2500;
0907         break;
0908 
0909     case MV_PCS_CSSR1_SPD1_1000:
0910         phydev->speed = SPEED_1000;
0911         break;
0912 
0913     case MV_PCS_CSSR1_SPD1_100:
0914         phydev->speed = SPEED_100;
0915         break;
0916 
0917     case MV_PCS_CSSR1_SPD1_10:
0918         phydev->speed = SPEED_10;
0919         break;
0920     }
0921 
0922     phydev->duplex = cssr1 & MV_PCS_CSSR1_DUPLEX_FULL ?
0923              DUPLEX_FULL : DUPLEX_HALF;
0924     phydev->port = PORT_TP;
0925     phydev->mdix = cssr1 & MV_PCS_CSSR1_MDIX ?
0926                ETH_TP_MDI_X : ETH_TP_MDI;
0927 
0928     if (val & MDIO_AN_STAT1_COMPLETE) {
0929         val = genphy_c45_read_lpa(phydev);
0930         if (val < 0)
0931             return val;
0932 
0933         /* Read the link partner's 1G advertisement */
0934         val = phy_read_mmd(phydev, MDIO_MMD_AN, MV_AN_STAT1000);
0935         if (val < 0)
0936             return val;
0937 
0938         mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
0939 
0940         /* Update the pause status */
0941         phy_resolve_aneg_pause(phydev);
0942     }
0943 
0944     return 0;
0945 }
0946 
0947 static int mv3310_read_status(struct phy_device *phydev)
0948 {
0949     int err, val;
0950 
0951     phydev->speed = SPEED_UNKNOWN;
0952     phydev->duplex = DUPLEX_UNKNOWN;
0953     linkmode_zero(phydev->lp_advertising);
0954     phydev->link = 0;
0955     phydev->pause = 0;
0956     phydev->asym_pause = 0;
0957     phydev->mdix = ETH_TP_MDI_INVALID;
0958 
0959     val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_BASE_R + MDIO_STAT1);
0960     if (val < 0)
0961         return val;
0962 
0963     if (val & MDIO_STAT1_LSTATUS)
0964         err = mv3310_read_status_10gbaser(phydev);
0965     else
0966         err = mv3310_read_status_copper(phydev);
0967     if (err < 0)
0968         return err;
0969 
0970     if (phydev->link)
0971         mv3310_update_interface(phydev);
0972 
0973     return 0;
0974 }
0975 
0976 static int mv3310_get_tunable(struct phy_device *phydev,
0977                   struct ethtool_tunable *tuna, void *data)
0978 {
0979     switch (tuna->id) {
0980     case ETHTOOL_PHY_DOWNSHIFT:
0981         return mv3310_get_downshift(phydev, data);
0982     case ETHTOOL_PHY_EDPD:
0983         return mv3310_get_edpd(phydev, data);
0984     default:
0985         return -EOPNOTSUPP;
0986     }
0987 }
0988 
0989 static int mv3310_set_tunable(struct phy_device *phydev,
0990                   struct ethtool_tunable *tuna, const void *data)
0991 {
0992     switch (tuna->id) {
0993     case ETHTOOL_PHY_DOWNSHIFT:
0994         return mv3310_set_downshift(phydev, *(u8 *)data);
0995     case ETHTOOL_PHY_EDPD:
0996         return mv3310_set_edpd(phydev, *(u16 *)data);
0997     default:
0998         return -EOPNOTSUPP;
0999     }
1000 }
1001 
1002 static 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 
1010 static 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 
1021 static 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 
1031 static 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 
1040 static 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 
1048 static 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 
1059 static 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 
1070 static 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 
1080 static 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 
1090 static 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 
1104 static 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 
1113 static 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 
1122 static 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 
1137 static int mv2110_match_phy_device(struct phy_device *phydev)
1138 {
1139     return mv211x_match_phy_device(phydev, true);
1140 }
1141 
1142 static int mv2111_match_phy_device(struct phy_device *phydev)
1143 {
1144     return mv211x_match_phy_device(phydev, false);
1145 }
1146 
1147 static 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 
1163 static 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 
1221 static 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 
1302 module_phy_driver(mv3310_drivers);
1303 
1304 static 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 };
1309 MODULE_DEVICE_TABLE(mdio, mv3310_tbl);
1310 MODULE_DESCRIPTION("Marvell Alaska X/M multi-gigabit Ethernet PHY driver");
1311 MODULE_LICENSE("GPL");