amd-xgbe: Update the BelFuse quirk to support SGMII
[linux-2.6-microblaze.git] / drivers / net / ethernet / amd / xgbe / xgbe-phy-v2.c
index aac8843..194a569 100644 (file)
 #include <linux/kmod.h>
 #include <linux/mdio.h>
 #include <linux/phy.h>
+#include <linux/ethtool.h>
 
 #include "xgbe.h"
 #include "xgbe-common.h"
@@ -270,6 +271,15 @@ struct xgbe_sfp_eeprom {
        u8 vendor[32];
 };
 
+#define XGBE_SFP_DIAGS_SUPPORTED(_x)                   \
+       ((_x)->extd[XGBE_SFP_EXTD_SFF_8472] &&          \
+        !((_x)->extd[XGBE_SFP_EXTD_DIAG] & XGBE_SFP_EXTD_DIAG_ADDR_CHANGE))
+
+#define XGBE_SFP_EEPROM_BASE_LEN       256
+#define XGBE_SFP_EEPROM_DIAG_LEN       256
+#define XGBE_SFP_EEPROM_MAX            (XGBE_SFP_EEPROM_BASE_LEN +     \
+                                        XGBE_SFP_EEPROM_DIAG_LEN)
+
 #define XGBE_BEL_FUSE_VENDOR   "BEL-FUSE        "
 #define XGBE_BEL_FUSE_PARTNO   "1GBT-SFP06      "
 
@@ -327,8 +337,6 @@ struct xgbe_phy_data {
 
        unsigned int mdio_addr;
 
-       unsigned int comm_owned;
-
        /* SFP Support */
        enum xgbe_sfp_comm sfp_comm;
        unsigned int sfp_mux_address;
@@ -345,7 +353,6 @@ struct xgbe_phy_data {
        unsigned int sfp_rx_los;
        unsigned int sfp_tx_fault;
        unsigned int sfp_mod_absent;
-       unsigned int sfp_diags;
        unsigned int sfp_changed;
        unsigned int sfp_phy_avail;
        unsigned int sfp_cable_len;
@@ -382,12 +389,6 @@ static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata);
 static int xgbe_phy_i2c_xfer(struct xgbe_prv_data *pdata,
                             struct xgbe_i2c_op *i2c_op)
 {
-       struct xgbe_phy_data *phy_data = pdata->phy_data;
-
-       /* Be sure we own the bus */
-       if (WARN_ON(!phy_data->comm_owned))
-               return -EIO;
-
        return pdata->i2c_if.i2c_xfer(pdata, i2c_op);
 }
 
@@ -549,10 +550,6 @@ static int xgbe_phy_sfp_get_mux(struct xgbe_prv_data *pdata)
 
 static void xgbe_phy_put_comm_ownership(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_phy_data *phy_data = pdata->phy_data;
-
-       phy_data->comm_owned = 0;
-
        mutex_unlock(&xgbe_phy_comm_lock);
 }
 
@@ -562,9 +559,6 @@ static int xgbe_phy_get_comm_ownership(struct xgbe_prv_data *pdata)
        unsigned long timeout;
        unsigned int mutex_id;
 
-       if (phy_data->comm_owned)
-               return 0;
-
        /* The I2C and MDIO/GPIO bus is multiplexed between multiple devices,
         * the driver needs to take the software mutex and then the hardware
         * mutexes before being able to use the busses.
@@ -593,7 +587,6 @@ static int xgbe_phy_get_comm_ownership(struct xgbe_prv_data *pdata)
                XP_IOWRITE(pdata, XP_I2C_MUTEX, mutex_id);
                XP_IOWRITE(pdata, XP_MDIO_MUTEX, mutex_id);
 
-               phy_data->comm_owned = 1;
                return 0;
        }
 
@@ -867,6 +860,9 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
        struct xgbe_phy_data *phy_data = pdata->phy_data;
        unsigned int phy_id = phy_data->phydev->phy_id;
 
+       if (phy_data->port_mode != XGBE_PORT_MODE_SFP)
+               return false;
+
        if ((phy_id & 0xfffffff0) != 0x01ff0cc0)
                return false;
 
@@ -892,8 +888,80 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
        return true;
 }
 
+static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
+{
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
+       struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
+       unsigned int phy_id = phy_data->phydev->phy_id;
+       int reg;
+
+       if (phy_data->port_mode != XGBE_PORT_MODE_SFP)
+               return false;
+
+       if (memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME],
+                  XGBE_BEL_FUSE_VENDOR, XGBE_SFP_BASE_VENDOR_NAME_LEN))
+               return false;
+
+       if (memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_PN],
+                  XGBE_BEL_FUSE_PARTNO, XGBE_SFP_BASE_VENDOR_PN_LEN))
+               return false;
+
+       if ((phy_id & 0xfffffff0) != 0x03625d10)
+               return false;
+
+       /* Disable RGMII mode */
+       phy_write(phy_data->phydev, 0x18, 0x7007);
+       reg = phy_read(phy_data->phydev, 0x18);
+       phy_write(phy_data->phydev, 0x18, reg & ~0x0080);
+
+       /* Enable fiber register bank */
+       phy_write(phy_data->phydev, 0x1c, 0x7c00);
+       reg = phy_read(phy_data->phydev, 0x1c);
+       reg &= 0x03ff;
+       reg &= ~0x0001;
+       phy_write(phy_data->phydev, 0x1c, 0x8000 | 0x7c00 | reg | 0x0001);
+
+       /* Power down SerDes */
+       reg = phy_read(phy_data->phydev, 0x00);
+       phy_write(phy_data->phydev, 0x00, reg | 0x00800);
+
+       /* Configure SGMII-to-Copper mode */
+       phy_write(phy_data->phydev, 0x1c, 0x7c00);
+       reg = phy_read(phy_data->phydev, 0x1c);
+       reg &= 0x03ff;
+       reg &= ~0x0006;
+       phy_write(phy_data->phydev, 0x1c, 0x8000 | 0x7c00 | reg | 0x0004);
+
+       /* Power up SerDes */
+       reg = phy_read(phy_data->phydev, 0x00);
+       phy_write(phy_data->phydev, 0x00, reg & ~0x00800);
+
+       /* Enable copper register bank */
+       phy_write(phy_data->phydev, 0x1c, 0x7c00);
+       reg = phy_read(phy_data->phydev, 0x1c);
+       reg &= 0x03ff;
+       reg &= ~0x0001;
+       phy_write(phy_data->phydev, 0x1c, 0x8000 | 0x7c00 | reg);
+
+       /* Power up SerDes */
+       reg = phy_read(phy_data->phydev, 0x00);
+       phy_write(phy_data->phydev, 0x00, reg & ~0x00800);
+
+       phy_data->phydev->supported = PHY_GBIT_FEATURES;
+       phy_data->phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+       phy_data->phydev->advertising = phy_data->phydev->supported;
+
+       netif_dbg(pdata, drv, pdata->netdev,
+                 "BelFuse PHY quirk in place\n");
+
+       return true;
+}
+
 static void xgbe_phy_external_phy_quirks(struct xgbe_prv_data *pdata)
 {
+       if (xgbe_phy_belfuse_phy_quirks(pdata))
+               return;
+
        if (xgbe_phy_finisar_phy_quirks(pdata))
                return;
 }
@@ -1034,37 +1102,6 @@ static bool xgbe_phy_check_sfp_mod_absent(struct xgbe_phy_data *phy_data)
        return false;
 }
 
-static bool xgbe_phy_belfuse_parse_quirks(struct xgbe_prv_data *pdata)
-{
-       struct xgbe_phy_data *phy_data = pdata->phy_data;
-       struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
-
-       if (memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME],
-                  XGBE_BEL_FUSE_VENDOR, XGBE_SFP_BASE_VENDOR_NAME_LEN))
-               return false;
-
-       if (!memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_PN],
-                   XGBE_BEL_FUSE_PARTNO, XGBE_SFP_BASE_VENDOR_PN_LEN)) {
-               phy_data->sfp_base = XGBE_SFP_BASE_1000_SX;
-               phy_data->sfp_cable = XGBE_SFP_CABLE_ACTIVE;
-               phy_data->sfp_speed = XGBE_SFP_SPEED_1000;
-               if (phy_data->sfp_changed)
-                       netif_dbg(pdata, drv, pdata->netdev,
-                                 "Bel-Fuse SFP quirk in place\n");
-               return true;
-       }
-
-       return false;
-}
-
-static bool xgbe_phy_sfp_parse_quirks(struct xgbe_prv_data *pdata)
-{
-       if (xgbe_phy_belfuse_parse_quirks(pdata))
-               return true;
-
-       return false;
-}
-
 static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
 {
        struct xgbe_phy_data *phy_data = pdata->phy_data;
@@ -1083,9 +1120,6 @@ static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
        phy_data->sfp_tx_fault = xgbe_phy_check_sfp_tx_fault(phy_data);
        phy_data->sfp_rx_los = xgbe_phy_check_sfp_rx_los(phy_data);
 
-       if (xgbe_phy_sfp_parse_quirks(pdata))
-               return;
-
        /* Assume ACTIVE cable unless told it is PASSIVE */
        if (sfp_base[XGBE_SFP_BASE_CABLE] & XGBE_SFP_BASE_CABLE_PASSIVE) {
                phy_data->sfp_cable = XGBE_SFP_CABLE_PASSIVE;
@@ -1227,13 +1261,6 @@ static int xgbe_phy_sfp_read_eeprom(struct xgbe_prv_data *pdata)
 
                memcpy(&phy_data->sfp_eeprom, &sfp_eeprom, sizeof(sfp_eeprom));
 
-               if (sfp_eeprom.extd[XGBE_SFP_EXTD_SFF_8472]) {
-                       u8 diag_type = sfp_eeprom.extd[XGBE_SFP_EXTD_DIAG];
-
-                       if (!(diag_type & XGBE_SFP_EXTD_DIAG_ADDR_CHANGE))
-                               phy_data->sfp_diags = 1;
-               }
-
                xgbe_phy_free_phy_device(pdata);
        } else {
                phy_data->sfp_changed = 0;
@@ -1283,7 +1310,6 @@ static void xgbe_phy_sfp_reset(struct xgbe_phy_data *phy_data)
        phy_data->sfp_rx_los = 0;
        phy_data->sfp_tx_fault = 0;
        phy_data->sfp_mod_absent = 1;
-       phy_data->sfp_diags = 0;
        phy_data->sfp_base = XGBE_SFP_BASE_UNKNOWN;
        phy_data->sfp_cable = XGBE_SFP_CABLE_UNKNOWN;
        phy_data->sfp_speed = XGBE_SFP_SPEED_UNKNOWN;
@@ -1326,6 +1352,130 @@ put:
        xgbe_phy_put_comm_ownership(pdata);
 }
 
+static int xgbe_phy_module_eeprom(struct xgbe_prv_data *pdata,
+                                 struct ethtool_eeprom *eeprom, u8 *data)
+{
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
+       u8 eeprom_addr, eeprom_data[XGBE_SFP_EEPROM_MAX];
+       struct xgbe_sfp_eeprom *sfp_eeprom;
+       unsigned int i, j, rem;
+       int ret;
+
+       rem = eeprom->len;
+
+       if (!eeprom->len) {
+               ret = -EINVAL;
+               goto done;
+       }
+
+       if ((eeprom->offset + eeprom->len) > XGBE_SFP_EEPROM_MAX) {
+               ret = -EINVAL;
+               goto done;
+       }
+
+       if (phy_data->port_mode != XGBE_PORT_MODE_SFP) {
+               ret = -ENXIO;
+               goto done;
+       }
+
+       if (!netif_running(pdata->netdev)) {
+               ret = -EIO;
+               goto done;
+       }
+
+       if (phy_data->sfp_mod_absent) {
+               ret = -EIO;
+               goto done;
+       }
+
+       ret = xgbe_phy_get_comm_ownership(pdata);
+       if (ret) {
+               ret = -EIO;
+               goto done;
+       }
+
+       ret = xgbe_phy_sfp_get_mux(pdata);
+       if (ret) {
+               netdev_err(pdata->netdev, "I2C error setting SFP MUX\n");
+               ret = -EIO;
+               goto put_own;
+       }
+
+       /* Read the SFP serial ID eeprom */
+       eeprom_addr = 0;
+       ret = xgbe_phy_i2c_read(pdata, XGBE_SFP_SERIAL_ID_ADDRESS,
+                               &eeprom_addr, sizeof(eeprom_addr),
+                               eeprom_data, XGBE_SFP_EEPROM_BASE_LEN);
+       if (ret) {
+               netdev_err(pdata->netdev,
+                          "I2C error reading SFP EEPROM\n");
+               ret = -EIO;
+               goto put_mux;
+       }
+
+       sfp_eeprom = (struct xgbe_sfp_eeprom *)eeprom_data;
+
+       if (XGBE_SFP_DIAGS_SUPPORTED(sfp_eeprom)) {
+               /* Read the SFP diagnostic eeprom */
+               eeprom_addr = 0;
+               ret = xgbe_phy_i2c_read(pdata, XGBE_SFP_DIAG_INFO_ADDRESS,
+                                       &eeprom_addr, sizeof(eeprom_addr),
+                                       eeprom_data + XGBE_SFP_EEPROM_BASE_LEN,
+                                       XGBE_SFP_EEPROM_DIAG_LEN);
+               if (ret) {
+                       netdev_err(pdata->netdev,
+                                  "I2C error reading SFP DIAGS\n");
+                       ret = -EIO;
+                       goto put_mux;
+               }
+       }
+
+       for (i = 0, j = eeprom->offset; i < eeprom->len; i++, j++) {
+               if ((j >= XGBE_SFP_EEPROM_BASE_LEN) &&
+                   !XGBE_SFP_DIAGS_SUPPORTED(sfp_eeprom))
+                       break;
+
+               data[i] = eeprom_data[j];
+               rem--;
+       }
+
+put_mux:
+       xgbe_phy_sfp_put_mux(pdata);
+
+put_own:
+       xgbe_phy_put_comm_ownership(pdata);
+
+done:
+       eeprom->len -= rem;
+
+       return ret;
+}
+
+static int xgbe_phy_module_info(struct xgbe_prv_data *pdata,
+                               struct ethtool_modinfo *modinfo)
+{
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
+
+       if (phy_data->port_mode != XGBE_PORT_MODE_SFP)
+               return -ENXIO;
+
+       if (!netif_running(pdata->netdev))
+               return -EIO;
+
+       if (phy_data->sfp_mod_absent)
+               return -EIO;
+
+       if (XGBE_SFP_DIAGS_SUPPORTED(&phy_data->sfp_eeprom)) {
+               modinfo->type = ETH_MODULE_SFF_8472;
+               modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
+       } else {
+               modinfo->type = ETH_MODULE_SFF_8079;
+               modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
+       }
+
+       return 0;
+}
+
 static void xgbe_phy_phydev_flowctrl(struct xgbe_prv_data *pdata)
 {
        struct ethtool_link_ksettings *lks = &pdata->phy.lks;
@@ -1611,6 +1761,10 @@ static void xgbe_phy_an_advertising(struct xgbe_prv_data *pdata,
        XGBE_CLR_ADV(dlks, 1000baseKX_Full);
        XGBE_CLR_ADV(dlks, 10000baseKR_Full);
 
+       /* Advertise FEC support is present */
+       if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
+               XGBE_SET_ADV(dlks, 10000baseR_FEC);
+
        switch (phy_data->port_mode) {
        case XGBE_PORT_MODE_BACKPLANE:
                XGBE_SET_ADV(dlks, 10000baseKR_Full);
@@ -2421,22 +2575,21 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
 static void xgbe_phy_sfp_gpio_setup(struct xgbe_prv_data *pdata)
 {
        struct xgbe_phy_data *phy_data = pdata->phy_data;
-       unsigned int reg;
-
-       reg = XP_IOREAD(pdata, XP_PROP_3);
 
        phy_data->sfp_gpio_address = XGBE_GPIO_ADDRESS_PCA9555 +
-                                    XP_GET_BITS(reg, XP_PROP_3, GPIO_ADDR);
+                                    XP_GET_BITS(pdata->pp3, XP_PROP_3,
+                                                GPIO_ADDR);
 
-       phy_data->sfp_gpio_mask = XP_GET_BITS(reg, XP_PROP_3, GPIO_MASK);
+       phy_data->sfp_gpio_mask = XP_GET_BITS(pdata->pp3, XP_PROP_3,
+                                             GPIO_MASK);
 
-       phy_data->sfp_gpio_rx_los = XP_GET_BITS(reg, XP_PROP_3,
+       phy_data->sfp_gpio_rx_los = XP_GET_BITS(pdata->pp3, XP_PROP_3,
                                                GPIO_RX_LOS);
-       phy_data->sfp_gpio_tx_fault = XP_GET_BITS(reg, XP_PROP_3,
+       phy_data->sfp_gpio_tx_fault = XP_GET_BITS(pdata->pp3, XP_PROP_3,
                                                  GPIO_TX_FAULT);
-       phy_data->sfp_gpio_mod_absent = XP_GET_BITS(reg, XP_PROP_3,
+       phy_data->sfp_gpio_mod_absent = XP_GET_BITS(pdata->pp3, XP_PROP_3,
                                                    GPIO_MOD_ABS);
-       phy_data->sfp_gpio_rate_select = XP_GET_BITS(reg, XP_PROP_3,
+       phy_data->sfp_gpio_rate_select = XP_GET_BITS(pdata->pp3, XP_PROP_3,
                                                     GPIO_RATE_SELECT);
 
        if (netif_msg_probe(pdata)) {
@@ -2458,18 +2611,17 @@ static void xgbe_phy_sfp_gpio_setup(struct xgbe_prv_data *pdata)
 static void xgbe_phy_sfp_comm_setup(struct xgbe_prv_data *pdata)
 {
        struct xgbe_phy_data *phy_data = pdata->phy_data;
-       unsigned int reg, mux_addr_hi, mux_addr_lo;
+       unsigned int mux_addr_hi, mux_addr_lo;
 
-       reg = XP_IOREAD(pdata, XP_PROP_4);
-
-       mux_addr_hi = XP_GET_BITS(reg, XP_PROP_4, MUX_ADDR_HI);
-       mux_addr_lo = XP_GET_BITS(reg, XP_PROP_4, MUX_ADDR_LO);
+       mux_addr_hi = XP_GET_BITS(pdata->pp4, XP_PROP_4, MUX_ADDR_HI);
+       mux_addr_lo = XP_GET_BITS(pdata->pp4, XP_PROP_4, MUX_ADDR_LO);
        if (mux_addr_lo == XGBE_SFP_DIRECT)
                return;
 
        phy_data->sfp_comm = XGBE_SFP_COMM_PCA9545;
        phy_data->sfp_mux_address = (mux_addr_hi << 2) + mux_addr_lo;
-       phy_data->sfp_mux_channel = XP_GET_BITS(reg, XP_PROP_4, MUX_CHAN);
+       phy_data->sfp_mux_channel = XP_GET_BITS(pdata->pp4, XP_PROP_4,
+                                               MUX_CHAN);
 
        if (netif_msg_probe(pdata)) {
                dev_dbg(pdata->dev, "SFP: mux_address=%#x\n",
@@ -2592,13 +2744,11 @@ static bool xgbe_phy_redrv_error(struct xgbe_phy_data *phy_data)
 static int xgbe_phy_mdio_reset_setup(struct xgbe_prv_data *pdata)
 {
        struct xgbe_phy_data *phy_data = pdata->phy_data;
-       unsigned int reg;
 
        if (phy_data->conn_type != XGBE_CONN_TYPE_MDIO)
                return 0;
 
-       reg = XP_IOREAD(pdata, XP_PROP_3);
-       phy_data->mdio_reset = XP_GET_BITS(reg, XP_PROP_3, MDIO_RESET);
+       phy_data->mdio_reset = XP_GET_BITS(pdata->pp3, XP_PROP_3, MDIO_RESET);
        switch (phy_data->mdio_reset) {
        case XGBE_MDIO_RESET_NONE:
        case XGBE_MDIO_RESET_I2C_GPIO:
@@ -2612,12 +2762,12 @@ static int xgbe_phy_mdio_reset_setup(struct xgbe_prv_data *pdata)
 
        if (phy_data->mdio_reset == XGBE_MDIO_RESET_I2C_GPIO) {
                phy_data->mdio_reset_addr = XGBE_GPIO_ADDRESS_PCA9555 +
-                                           XP_GET_BITS(reg, XP_PROP_3,
+                                           XP_GET_BITS(pdata->pp3, XP_PROP_3,
                                                        MDIO_RESET_I2C_ADDR);
-               phy_data->mdio_reset_gpio = XP_GET_BITS(reg, XP_PROP_3,
+               phy_data->mdio_reset_gpio = XP_GET_BITS(pdata->pp3, XP_PROP_3,
                                                        MDIO_RESET_I2C_GPIO);
        } else if (phy_data->mdio_reset == XGBE_MDIO_RESET_INT_GPIO) {
-               phy_data->mdio_reset_gpio = XP_GET_BITS(reg, XP_PROP_3,
+               phy_data->mdio_reset_gpio = XP_GET_BITS(pdata->pp3, XP_PROP_3,
                                                        MDIO_RESET_INT_GPIO);
        }
 
@@ -2707,12 +2857,9 @@ static bool xgbe_phy_conn_type_mismatch(struct xgbe_prv_data *pdata)
 
 static bool xgbe_phy_port_enabled(struct xgbe_prv_data *pdata)
 {
-       unsigned int reg;
-
-       reg = XP_IOREAD(pdata, XP_PROP_0);
-       if (!XP_GET_BITS(reg, XP_PROP_0, PORT_SPEEDS))
+       if (!XP_GET_BITS(pdata->pp0, XP_PROP_0, PORT_SPEEDS))
                return false;
-       if (!XP_GET_BITS(reg, XP_PROP_0, CONN_TYPE))
+       if (!XP_GET_BITS(pdata->pp0, XP_PROP_0, CONN_TYPE))
                return false;
 
        return true;
@@ -2921,7 +3068,6 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
        struct ethtool_link_ksettings *lks = &pdata->phy.lks;
        struct xgbe_phy_data *phy_data;
        struct mii_bus *mii;
-       unsigned int reg;
        int ret;
 
        /* Check if enabled */
@@ -2940,12 +3086,11 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
                return -ENOMEM;
        pdata->phy_data = phy_data;
 
-       reg = XP_IOREAD(pdata, XP_PROP_0);
-       phy_data->port_mode = XP_GET_BITS(reg, XP_PROP_0, PORT_MODE);
-       phy_data->port_id = XP_GET_BITS(reg, XP_PROP_0, PORT_ID);
-       phy_data->port_speeds = XP_GET_BITS(reg, XP_PROP_0, PORT_SPEEDS);
-       phy_data->conn_type = XP_GET_BITS(reg, XP_PROP_0, CONN_TYPE);
-       phy_data->mdio_addr = XP_GET_BITS(reg, XP_PROP_0, MDIO_ADDR);
+       phy_data->port_mode = XP_GET_BITS(pdata->pp0, XP_PROP_0, PORT_MODE);
+       phy_data->port_id = XP_GET_BITS(pdata->pp0, XP_PROP_0, PORT_ID);
+       phy_data->port_speeds = XP_GET_BITS(pdata->pp0, XP_PROP_0, PORT_SPEEDS);
+       phy_data->conn_type = XP_GET_BITS(pdata->pp0, XP_PROP_0, CONN_TYPE);
+       phy_data->mdio_addr = XP_GET_BITS(pdata->pp0, XP_PROP_0, MDIO_ADDR);
        if (netif_msg_probe(pdata)) {
                dev_dbg(pdata->dev, "port mode=%u\n", phy_data->port_mode);
                dev_dbg(pdata->dev, "port id=%u\n", phy_data->port_id);
@@ -2954,12 +3099,11 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
                dev_dbg(pdata->dev, "mdio addr=%u\n", phy_data->mdio_addr);
        }
 
-       reg = XP_IOREAD(pdata, XP_PROP_4);
-       phy_data->redrv = XP_GET_BITS(reg, XP_PROP_4, REDRV_PRESENT);
-       phy_data->redrv_if = XP_GET_BITS(reg, XP_PROP_4, REDRV_IF);
-       phy_data->redrv_addr = XP_GET_BITS(reg, XP_PROP_4, REDRV_ADDR);
-       phy_data->redrv_lane = XP_GET_BITS(reg, XP_PROP_4, REDRV_LANE);
-       phy_data->redrv_model = XP_GET_BITS(reg, XP_PROP_4, REDRV_MODEL);
+       phy_data->redrv = XP_GET_BITS(pdata->pp4, XP_PROP_4, REDRV_PRESENT);
+       phy_data->redrv_if = XP_GET_BITS(pdata->pp4, XP_PROP_4, REDRV_IF);
+       phy_data->redrv_addr = XP_GET_BITS(pdata->pp4, XP_PROP_4, REDRV_ADDR);
+       phy_data->redrv_lane = XP_GET_BITS(pdata->pp4, XP_PROP_4, REDRV_LANE);
+       phy_data->redrv_model = XP_GET_BITS(pdata->pp4, XP_PROP_4, REDRV_MODEL);
        if (phy_data->redrv && netif_msg_probe(pdata)) {
                dev_dbg(pdata->dev, "redrv present\n");
                dev_dbg(pdata->dev, "redrv i/f=%u\n", phy_data->redrv_if);
@@ -3231,4 +3375,7 @@ void xgbe_init_function_ptrs_phy_v2(struct xgbe_phy_if *phy_if)
 
        phy_impl->kr_training_pre       = xgbe_phy_kr_training_pre;
        phy_impl->kr_training_post      = xgbe_phy_kr_training_post;
+
+       phy_impl->module_info           = xgbe_phy_module_info;
+       phy_impl->module_eeprom         = xgbe_phy_module_eeprom;
 }