1*4ac7516bSRavi Kumar /* SPDX-License-Identifier: BSD-3-Clause 2*4ac7516bSRavi Kumar * Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved. 3*4ac7516bSRavi Kumar * Copyright(c) 2018 Synopsys, Inc. All rights reserved. 4*4ac7516bSRavi Kumar */ 5*4ac7516bSRavi Kumar 6*4ac7516bSRavi Kumar #include "axgbe_ethdev.h" 7*4ac7516bSRavi Kumar #include "axgbe_common.h" 8*4ac7516bSRavi Kumar #include "axgbe_phy.h" 9*4ac7516bSRavi Kumar 10*4ac7516bSRavi Kumar #define AXGBE_PHY_PORT_SPEED_100 BIT(0) 11*4ac7516bSRavi Kumar #define AXGBE_PHY_PORT_SPEED_1000 BIT(1) 12*4ac7516bSRavi Kumar #define AXGBE_PHY_PORT_SPEED_2500 BIT(2) 13*4ac7516bSRavi Kumar #define AXGBE_PHY_PORT_SPEED_10000 BIT(3) 14*4ac7516bSRavi Kumar 15*4ac7516bSRavi Kumar #define AXGBE_MUTEX_RELEASE 0x80000000 16*4ac7516bSRavi Kumar 17*4ac7516bSRavi Kumar #define AXGBE_SFP_DIRECT 7 18*4ac7516bSRavi Kumar 19*4ac7516bSRavi Kumar /* I2C target addresses */ 20*4ac7516bSRavi Kumar #define AXGBE_SFP_SERIAL_ID_ADDRESS 0x50 21*4ac7516bSRavi Kumar #define AXGBE_SFP_DIAG_INFO_ADDRESS 0x51 22*4ac7516bSRavi Kumar #define AXGBE_SFP_PHY_ADDRESS 0x56 23*4ac7516bSRavi Kumar #define AXGBE_GPIO_ADDRESS_PCA9555 0x20 24*4ac7516bSRavi Kumar 25*4ac7516bSRavi Kumar /* SFP sideband signal indicators */ 26*4ac7516bSRavi Kumar #define AXGBE_GPIO_NO_TX_FAULT BIT(0) 27*4ac7516bSRavi Kumar #define AXGBE_GPIO_NO_RATE_SELECT BIT(1) 28*4ac7516bSRavi Kumar #define AXGBE_GPIO_NO_MOD_ABSENT BIT(2) 29*4ac7516bSRavi Kumar #define AXGBE_GPIO_NO_RX_LOS BIT(3) 30*4ac7516bSRavi Kumar 31*4ac7516bSRavi Kumar /* Rate-change complete wait/retry count */ 32*4ac7516bSRavi Kumar #define AXGBE_RATECHANGE_COUNT 500 33*4ac7516bSRavi Kumar 34*4ac7516bSRavi Kumar enum axgbe_port_mode { 35*4ac7516bSRavi Kumar AXGBE_PORT_MODE_RSVD = 0, 36*4ac7516bSRavi Kumar AXGBE_PORT_MODE_BACKPLANE, 37*4ac7516bSRavi Kumar AXGBE_PORT_MODE_BACKPLANE_2500, 38*4ac7516bSRavi Kumar AXGBE_PORT_MODE_1000BASE_T, 39*4ac7516bSRavi Kumar AXGBE_PORT_MODE_1000BASE_X, 40*4ac7516bSRavi Kumar AXGBE_PORT_MODE_NBASE_T, 41*4ac7516bSRavi Kumar AXGBE_PORT_MODE_10GBASE_T, 42*4ac7516bSRavi Kumar AXGBE_PORT_MODE_10GBASE_R, 43*4ac7516bSRavi Kumar AXGBE_PORT_MODE_SFP, 44*4ac7516bSRavi Kumar AXGBE_PORT_MODE_MAX, 45*4ac7516bSRavi Kumar }; 46*4ac7516bSRavi Kumar 47*4ac7516bSRavi Kumar enum axgbe_conn_type { 48*4ac7516bSRavi Kumar AXGBE_CONN_TYPE_NONE = 0, 49*4ac7516bSRavi Kumar AXGBE_CONN_TYPE_SFP, 50*4ac7516bSRavi Kumar AXGBE_CONN_TYPE_MDIO, 51*4ac7516bSRavi Kumar AXGBE_CONN_TYPE_RSVD1, 52*4ac7516bSRavi Kumar AXGBE_CONN_TYPE_BACKPLANE, 53*4ac7516bSRavi Kumar AXGBE_CONN_TYPE_MAX, 54*4ac7516bSRavi Kumar }; 55*4ac7516bSRavi Kumar 56*4ac7516bSRavi Kumar /* SFP/SFP+ related definitions */ 57*4ac7516bSRavi Kumar enum axgbe_sfp_comm { 58*4ac7516bSRavi Kumar AXGBE_SFP_COMM_DIRECT = 0, 59*4ac7516bSRavi Kumar AXGBE_SFP_COMM_PCA9545, 60*4ac7516bSRavi Kumar }; 61*4ac7516bSRavi Kumar 62*4ac7516bSRavi Kumar enum axgbe_sfp_cable { 63*4ac7516bSRavi Kumar AXGBE_SFP_CABLE_UNKNOWN = 0, 64*4ac7516bSRavi Kumar AXGBE_SFP_CABLE_ACTIVE, 65*4ac7516bSRavi Kumar AXGBE_SFP_CABLE_PASSIVE, 66*4ac7516bSRavi Kumar }; 67*4ac7516bSRavi Kumar 68*4ac7516bSRavi Kumar enum axgbe_sfp_base { 69*4ac7516bSRavi Kumar AXGBE_SFP_BASE_UNKNOWN = 0, 70*4ac7516bSRavi Kumar AXGBE_SFP_BASE_1000_T, 71*4ac7516bSRavi Kumar AXGBE_SFP_BASE_1000_SX, 72*4ac7516bSRavi Kumar AXGBE_SFP_BASE_1000_LX, 73*4ac7516bSRavi Kumar AXGBE_SFP_BASE_1000_CX, 74*4ac7516bSRavi Kumar AXGBE_SFP_BASE_10000_SR, 75*4ac7516bSRavi Kumar AXGBE_SFP_BASE_10000_LR, 76*4ac7516bSRavi Kumar AXGBE_SFP_BASE_10000_LRM, 77*4ac7516bSRavi Kumar AXGBE_SFP_BASE_10000_ER, 78*4ac7516bSRavi Kumar AXGBE_SFP_BASE_10000_CR, 79*4ac7516bSRavi Kumar }; 80*4ac7516bSRavi Kumar 81*4ac7516bSRavi Kumar enum axgbe_sfp_speed { 82*4ac7516bSRavi Kumar AXGBE_SFP_SPEED_UNKNOWN = 0, 83*4ac7516bSRavi Kumar AXGBE_SFP_SPEED_100_1000, 84*4ac7516bSRavi Kumar AXGBE_SFP_SPEED_1000, 85*4ac7516bSRavi Kumar AXGBE_SFP_SPEED_10000, 86*4ac7516bSRavi Kumar }; 87*4ac7516bSRavi Kumar 88*4ac7516bSRavi Kumar /* SFP Serial ID Base ID values relative to an offset of 0 */ 89*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_ID 0 90*4ac7516bSRavi Kumar #define AXGBE_SFP_ID_SFP 0x03 91*4ac7516bSRavi Kumar 92*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_EXT_ID 1 93*4ac7516bSRavi Kumar #define AXGBE_SFP_EXT_ID_SFP 0x04 94*4ac7516bSRavi Kumar 95*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_10GBE_CC 3 96*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_10GBE_CC_SR BIT(4) 97*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_10GBE_CC_LR BIT(5) 98*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_10GBE_CC_LRM BIT(6) 99*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_10GBE_CC_ER BIT(7) 100*4ac7516bSRavi Kumar 101*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_1GBE_CC 6 102*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_1GBE_CC_SX BIT(0) 103*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_1GBE_CC_LX BIT(1) 104*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_1GBE_CC_CX BIT(2) 105*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_1GBE_CC_T BIT(3) 106*4ac7516bSRavi Kumar 107*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_CABLE 8 108*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_CABLE_PASSIVE BIT(2) 109*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_CABLE_ACTIVE BIT(3) 110*4ac7516bSRavi Kumar 111*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_BR 12 112*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_BR_1GBE_MIN 0x0a 113*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_BR_1GBE_MAX 0x0d 114*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_BR_10GBE_MIN 0x64 115*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_BR_10GBE_MAX 0x68 116*4ac7516bSRavi Kumar 117*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_CU_CABLE_LEN 18 118*4ac7516bSRavi Kumar 119*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_NAME 20 120*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_NAME_LEN 16 121*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_PN 40 122*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_PN_LEN 16 123*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_REV 56 124*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_REV_LEN 4 125*4ac7516bSRavi Kumar 126*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_CC 63 127*4ac7516bSRavi Kumar 128*4ac7516bSRavi Kumar /* SFP Serial ID Extended ID values relative to an offset of 64 */ 129*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_SN 4 130*4ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_SN_LEN 16 131*4ac7516bSRavi Kumar 132*4ac7516bSRavi Kumar #define AXGBE_SFP_EXTD_DIAG 28 133*4ac7516bSRavi Kumar #define AXGBE_SFP_EXTD_DIAG_ADDR_CHANGE BIT(2) 134*4ac7516bSRavi Kumar 135*4ac7516bSRavi Kumar #define AXGBE_SFP_EXTD_SFF_8472 30 136*4ac7516bSRavi Kumar 137*4ac7516bSRavi Kumar #define AXGBE_SFP_EXTD_CC 31 138*4ac7516bSRavi Kumar 139*4ac7516bSRavi Kumar struct axgbe_sfp_eeprom { 140*4ac7516bSRavi Kumar u8 base[64]; 141*4ac7516bSRavi Kumar u8 extd[32]; 142*4ac7516bSRavi Kumar u8 vendor[32]; 143*4ac7516bSRavi Kumar }; 144*4ac7516bSRavi Kumar 145*4ac7516bSRavi Kumar #define AXGBE_BEL_FUSE_VENDOR "BEL-FUSE" 146*4ac7516bSRavi Kumar #define AXGBE_BEL_FUSE_PARTNO "1GBT-SFP06" 147*4ac7516bSRavi Kumar 148*4ac7516bSRavi Kumar struct axgbe_sfp_ascii { 149*4ac7516bSRavi Kumar union { 150*4ac7516bSRavi Kumar char vendor[AXGBE_SFP_BASE_VENDOR_NAME_LEN + 1]; 151*4ac7516bSRavi Kumar char partno[AXGBE_SFP_BASE_VENDOR_PN_LEN + 1]; 152*4ac7516bSRavi Kumar char rev[AXGBE_SFP_BASE_VENDOR_REV_LEN + 1]; 153*4ac7516bSRavi Kumar char serno[AXGBE_SFP_BASE_VENDOR_SN_LEN + 1]; 154*4ac7516bSRavi Kumar } u; 155*4ac7516bSRavi Kumar }; 156*4ac7516bSRavi Kumar 157*4ac7516bSRavi Kumar /* MDIO PHY reset types */ 158*4ac7516bSRavi Kumar enum axgbe_mdio_reset { 159*4ac7516bSRavi Kumar AXGBE_MDIO_RESET_NONE = 0, 160*4ac7516bSRavi Kumar AXGBE_MDIO_RESET_I2C_GPIO, 161*4ac7516bSRavi Kumar AXGBE_MDIO_RESET_INT_GPIO, 162*4ac7516bSRavi Kumar AXGBE_MDIO_RESET_MAX, 163*4ac7516bSRavi Kumar }; 164*4ac7516bSRavi Kumar 165*4ac7516bSRavi Kumar /* Re-driver related definitions */ 166*4ac7516bSRavi Kumar enum axgbe_phy_redrv_if { 167*4ac7516bSRavi Kumar AXGBE_PHY_REDRV_IF_MDIO = 0, 168*4ac7516bSRavi Kumar AXGBE_PHY_REDRV_IF_I2C, 169*4ac7516bSRavi Kumar AXGBE_PHY_REDRV_IF_MAX, 170*4ac7516bSRavi Kumar }; 171*4ac7516bSRavi Kumar 172*4ac7516bSRavi Kumar enum axgbe_phy_redrv_model { 173*4ac7516bSRavi Kumar AXGBE_PHY_REDRV_MODEL_4223 = 0, 174*4ac7516bSRavi Kumar AXGBE_PHY_REDRV_MODEL_4227, 175*4ac7516bSRavi Kumar AXGBE_PHY_REDRV_MODEL_MAX, 176*4ac7516bSRavi Kumar }; 177*4ac7516bSRavi Kumar 178*4ac7516bSRavi Kumar enum axgbe_phy_redrv_mode { 179*4ac7516bSRavi Kumar AXGBE_PHY_REDRV_MODE_CX = 5, 180*4ac7516bSRavi Kumar AXGBE_PHY_REDRV_MODE_SR = 9, 181*4ac7516bSRavi Kumar }; 182*4ac7516bSRavi Kumar 183*4ac7516bSRavi Kumar #define AXGBE_PHY_REDRV_MODE_REG 0x12b0 184*4ac7516bSRavi Kumar 185*4ac7516bSRavi Kumar /* PHY related configuration information */ 186*4ac7516bSRavi Kumar struct axgbe_phy_data { 187*4ac7516bSRavi Kumar enum axgbe_port_mode port_mode; 188*4ac7516bSRavi Kumar 189*4ac7516bSRavi Kumar unsigned int port_id; 190*4ac7516bSRavi Kumar 191*4ac7516bSRavi Kumar unsigned int port_speeds; 192*4ac7516bSRavi Kumar 193*4ac7516bSRavi Kumar enum axgbe_conn_type conn_type; 194*4ac7516bSRavi Kumar 195*4ac7516bSRavi Kumar enum axgbe_mode cur_mode; 196*4ac7516bSRavi Kumar enum axgbe_mode start_mode; 197*4ac7516bSRavi Kumar 198*4ac7516bSRavi Kumar unsigned int rrc_count; 199*4ac7516bSRavi Kumar 200*4ac7516bSRavi Kumar unsigned int mdio_addr; 201*4ac7516bSRavi Kumar 202*4ac7516bSRavi Kumar unsigned int comm_owned; 203*4ac7516bSRavi Kumar 204*4ac7516bSRavi Kumar /* SFP Support */ 205*4ac7516bSRavi Kumar enum axgbe_sfp_comm sfp_comm; 206*4ac7516bSRavi Kumar unsigned int sfp_mux_address; 207*4ac7516bSRavi Kumar unsigned int sfp_mux_channel; 208*4ac7516bSRavi Kumar 209*4ac7516bSRavi Kumar unsigned int sfp_gpio_address; 210*4ac7516bSRavi Kumar unsigned int sfp_gpio_mask; 211*4ac7516bSRavi Kumar unsigned int sfp_gpio_rx_los; 212*4ac7516bSRavi Kumar unsigned int sfp_gpio_tx_fault; 213*4ac7516bSRavi Kumar unsigned int sfp_gpio_mod_absent; 214*4ac7516bSRavi Kumar unsigned int sfp_gpio_rate_select; 215*4ac7516bSRavi Kumar 216*4ac7516bSRavi Kumar unsigned int sfp_rx_los; 217*4ac7516bSRavi Kumar unsigned int sfp_tx_fault; 218*4ac7516bSRavi Kumar unsigned int sfp_mod_absent; 219*4ac7516bSRavi Kumar unsigned int sfp_diags; 220*4ac7516bSRavi Kumar unsigned int sfp_changed; 221*4ac7516bSRavi Kumar unsigned int sfp_phy_avail; 222*4ac7516bSRavi Kumar unsigned int sfp_cable_len; 223*4ac7516bSRavi Kumar enum axgbe_sfp_base sfp_base; 224*4ac7516bSRavi Kumar enum axgbe_sfp_cable sfp_cable; 225*4ac7516bSRavi Kumar enum axgbe_sfp_speed sfp_speed; 226*4ac7516bSRavi Kumar struct axgbe_sfp_eeprom sfp_eeprom; 227*4ac7516bSRavi Kumar 228*4ac7516bSRavi Kumar /* External PHY support */ 229*4ac7516bSRavi Kumar enum axgbe_mdio_mode phydev_mode; 230*4ac7516bSRavi Kumar enum axgbe_mdio_reset mdio_reset; 231*4ac7516bSRavi Kumar unsigned int mdio_reset_addr; 232*4ac7516bSRavi Kumar unsigned int mdio_reset_gpio; 233*4ac7516bSRavi Kumar 234*4ac7516bSRavi Kumar /* Re-driver support */ 235*4ac7516bSRavi Kumar unsigned int redrv; 236*4ac7516bSRavi Kumar unsigned int redrv_if; 237*4ac7516bSRavi Kumar unsigned int redrv_addr; 238*4ac7516bSRavi Kumar unsigned int redrv_lane; 239*4ac7516bSRavi Kumar unsigned int redrv_model; 240*4ac7516bSRavi Kumar }; 241*4ac7516bSRavi Kumar 242*4ac7516bSRavi Kumar static void axgbe_phy_sfp_gpio_setup(struct axgbe_port *pdata) 243*4ac7516bSRavi Kumar { 244*4ac7516bSRavi Kumar struct axgbe_phy_data *phy_data = pdata->phy_data; 245*4ac7516bSRavi Kumar unsigned int reg; 246*4ac7516bSRavi Kumar 247*4ac7516bSRavi Kumar reg = XP_IOREAD(pdata, XP_PROP_3); 248*4ac7516bSRavi Kumar 249*4ac7516bSRavi Kumar phy_data->sfp_gpio_address = AXGBE_GPIO_ADDRESS_PCA9555 + 250*4ac7516bSRavi Kumar XP_GET_BITS(reg, XP_PROP_3, GPIO_ADDR); 251*4ac7516bSRavi Kumar 252*4ac7516bSRavi Kumar phy_data->sfp_gpio_mask = XP_GET_BITS(reg, XP_PROP_3, GPIO_MASK); 253*4ac7516bSRavi Kumar 254*4ac7516bSRavi Kumar phy_data->sfp_gpio_rx_los = XP_GET_BITS(reg, XP_PROP_3, 255*4ac7516bSRavi Kumar GPIO_RX_LOS); 256*4ac7516bSRavi Kumar phy_data->sfp_gpio_tx_fault = XP_GET_BITS(reg, XP_PROP_3, 257*4ac7516bSRavi Kumar GPIO_TX_FAULT); 258*4ac7516bSRavi Kumar phy_data->sfp_gpio_mod_absent = XP_GET_BITS(reg, XP_PROP_3, 259*4ac7516bSRavi Kumar GPIO_MOD_ABS); 260*4ac7516bSRavi Kumar phy_data->sfp_gpio_rate_select = XP_GET_BITS(reg, XP_PROP_3, 261*4ac7516bSRavi Kumar GPIO_RATE_SELECT); 262*4ac7516bSRavi Kumar } 263*4ac7516bSRavi Kumar 264*4ac7516bSRavi Kumar static void axgbe_phy_sfp_comm_setup(struct axgbe_port *pdata) 265*4ac7516bSRavi Kumar { 266*4ac7516bSRavi Kumar struct axgbe_phy_data *phy_data = pdata->phy_data; 267*4ac7516bSRavi Kumar unsigned int reg, mux_addr_hi, mux_addr_lo; 268*4ac7516bSRavi Kumar 269*4ac7516bSRavi Kumar reg = XP_IOREAD(pdata, XP_PROP_4); 270*4ac7516bSRavi Kumar 271*4ac7516bSRavi Kumar mux_addr_hi = XP_GET_BITS(reg, XP_PROP_4, MUX_ADDR_HI); 272*4ac7516bSRavi Kumar mux_addr_lo = XP_GET_BITS(reg, XP_PROP_4, MUX_ADDR_LO); 273*4ac7516bSRavi Kumar if (mux_addr_lo == AXGBE_SFP_DIRECT) 274*4ac7516bSRavi Kumar return; 275*4ac7516bSRavi Kumar 276*4ac7516bSRavi Kumar phy_data->sfp_comm = AXGBE_SFP_COMM_PCA9545; 277*4ac7516bSRavi Kumar phy_data->sfp_mux_address = (mux_addr_hi << 2) + mux_addr_lo; 278*4ac7516bSRavi Kumar phy_data->sfp_mux_channel = XP_GET_BITS(reg, XP_PROP_4, MUX_CHAN); 279*4ac7516bSRavi Kumar } 280*4ac7516bSRavi Kumar 281*4ac7516bSRavi Kumar static void axgbe_phy_sfp_setup(struct axgbe_port *pdata) 282*4ac7516bSRavi Kumar { 283*4ac7516bSRavi Kumar axgbe_phy_sfp_comm_setup(pdata); 284*4ac7516bSRavi Kumar axgbe_phy_sfp_gpio_setup(pdata); 285*4ac7516bSRavi Kumar } 286*4ac7516bSRavi Kumar 287*4ac7516bSRavi Kumar static bool axgbe_phy_redrv_error(struct axgbe_phy_data *phy_data) 288*4ac7516bSRavi Kumar { 289*4ac7516bSRavi Kumar if (!phy_data->redrv) 290*4ac7516bSRavi Kumar return false; 291*4ac7516bSRavi Kumar 292*4ac7516bSRavi Kumar if (phy_data->redrv_if >= AXGBE_PHY_REDRV_IF_MAX) 293*4ac7516bSRavi Kumar return true; 294*4ac7516bSRavi Kumar 295*4ac7516bSRavi Kumar switch (phy_data->redrv_model) { 296*4ac7516bSRavi Kumar case AXGBE_PHY_REDRV_MODEL_4223: 297*4ac7516bSRavi Kumar if (phy_data->redrv_lane > 3) 298*4ac7516bSRavi Kumar return true; 299*4ac7516bSRavi Kumar break; 300*4ac7516bSRavi Kumar case AXGBE_PHY_REDRV_MODEL_4227: 301*4ac7516bSRavi Kumar if (phy_data->redrv_lane > 1) 302*4ac7516bSRavi Kumar return true; 303*4ac7516bSRavi Kumar break; 304*4ac7516bSRavi Kumar default: 305*4ac7516bSRavi Kumar return true; 306*4ac7516bSRavi Kumar } 307*4ac7516bSRavi Kumar 308*4ac7516bSRavi Kumar return false; 309*4ac7516bSRavi Kumar } 310*4ac7516bSRavi Kumar 311*4ac7516bSRavi Kumar static int axgbe_phy_mdio_reset_setup(struct axgbe_port *pdata) 312*4ac7516bSRavi Kumar { 313*4ac7516bSRavi Kumar struct axgbe_phy_data *phy_data = pdata->phy_data; 314*4ac7516bSRavi Kumar unsigned int reg; 315*4ac7516bSRavi Kumar 316*4ac7516bSRavi Kumar if (phy_data->conn_type != AXGBE_CONN_TYPE_MDIO) 317*4ac7516bSRavi Kumar return 0; 318*4ac7516bSRavi Kumar reg = XP_IOREAD(pdata, XP_PROP_3); 319*4ac7516bSRavi Kumar phy_data->mdio_reset = XP_GET_BITS(reg, XP_PROP_3, MDIO_RESET); 320*4ac7516bSRavi Kumar switch (phy_data->mdio_reset) { 321*4ac7516bSRavi Kumar case AXGBE_MDIO_RESET_NONE: 322*4ac7516bSRavi Kumar case AXGBE_MDIO_RESET_I2C_GPIO: 323*4ac7516bSRavi Kumar case AXGBE_MDIO_RESET_INT_GPIO: 324*4ac7516bSRavi Kumar break; 325*4ac7516bSRavi Kumar default: 326*4ac7516bSRavi Kumar PMD_DRV_LOG(ERR, "unsupported MDIO reset (%#x)\n", 327*4ac7516bSRavi Kumar phy_data->mdio_reset); 328*4ac7516bSRavi Kumar return -EINVAL; 329*4ac7516bSRavi Kumar } 330*4ac7516bSRavi Kumar if (phy_data->mdio_reset == AXGBE_MDIO_RESET_I2C_GPIO) { 331*4ac7516bSRavi Kumar phy_data->mdio_reset_addr = AXGBE_GPIO_ADDRESS_PCA9555 + 332*4ac7516bSRavi Kumar XP_GET_BITS(reg, XP_PROP_3, 333*4ac7516bSRavi Kumar MDIO_RESET_I2C_ADDR); 334*4ac7516bSRavi Kumar phy_data->mdio_reset_gpio = XP_GET_BITS(reg, XP_PROP_3, 335*4ac7516bSRavi Kumar MDIO_RESET_I2C_GPIO); 336*4ac7516bSRavi Kumar } else if (phy_data->mdio_reset == AXGBE_MDIO_RESET_INT_GPIO) { 337*4ac7516bSRavi Kumar phy_data->mdio_reset_gpio = XP_GET_BITS(reg, XP_PROP_3, 338*4ac7516bSRavi Kumar MDIO_RESET_INT_GPIO); 339*4ac7516bSRavi Kumar } 340*4ac7516bSRavi Kumar 341*4ac7516bSRavi Kumar return 0; 342*4ac7516bSRavi Kumar } 343*4ac7516bSRavi Kumar 344*4ac7516bSRavi Kumar static bool axgbe_phy_port_mode_mismatch(struct axgbe_port *pdata) 345*4ac7516bSRavi Kumar { 346*4ac7516bSRavi Kumar struct axgbe_phy_data *phy_data = pdata->phy_data; 347*4ac7516bSRavi Kumar 348*4ac7516bSRavi Kumar switch (phy_data->port_mode) { 349*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_BACKPLANE: 350*4ac7516bSRavi Kumar if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) || 351*4ac7516bSRavi Kumar (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000)) 352*4ac7516bSRavi Kumar return false; 353*4ac7516bSRavi Kumar break; 354*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_BACKPLANE_2500: 355*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500) 356*4ac7516bSRavi Kumar return false; 357*4ac7516bSRavi Kumar break; 358*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_1000BASE_T: 359*4ac7516bSRavi Kumar if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) || 360*4ac7516bSRavi Kumar (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000)) 361*4ac7516bSRavi Kumar return false; 362*4ac7516bSRavi Kumar break; 363*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_1000BASE_X: 364*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) 365*4ac7516bSRavi Kumar return false; 366*4ac7516bSRavi Kumar break; 367*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_NBASE_T: 368*4ac7516bSRavi Kumar if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) || 369*4ac7516bSRavi Kumar (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) || 370*4ac7516bSRavi Kumar (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500)) 371*4ac7516bSRavi Kumar return false; 372*4ac7516bSRavi Kumar break; 373*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_10GBASE_T: 374*4ac7516bSRavi Kumar if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) || 375*4ac7516bSRavi Kumar (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) || 376*4ac7516bSRavi Kumar (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000)) 377*4ac7516bSRavi Kumar return false; 378*4ac7516bSRavi Kumar break; 379*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_10GBASE_R: 380*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000) 381*4ac7516bSRavi Kumar return false; 382*4ac7516bSRavi Kumar break; 383*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_SFP: 384*4ac7516bSRavi Kumar if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) || 385*4ac7516bSRavi Kumar (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) || 386*4ac7516bSRavi Kumar (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000)) 387*4ac7516bSRavi Kumar return false; 388*4ac7516bSRavi Kumar break; 389*4ac7516bSRavi Kumar default: 390*4ac7516bSRavi Kumar break; 391*4ac7516bSRavi Kumar } 392*4ac7516bSRavi Kumar 393*4ac7516bSRavi Kumar return true; 394*4ac7516bSRavi Kumar } 395*4ac7516bSRavi Kumar 396*4ac7516bSRavi Kumar static bool axgbe_phy_conn_type_mismatch(struct axgbe_port *pdata) 397*4ac7516bSRavi Kumar { 398*4ac7516bSRavi Kumar struct axgbe_phy_data *phy_data = pdata->phy_data; 399*4ac7516bSRavi Kumar 400*4ac7516bSRavi Kumar switch (phy_data->port_mode) { 401*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_BACKPLANE: 402*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_BACKPLANE_2500: 403*4ac7516bSRavi Kumar if (phy_data->conn_type == AXGBE_CONN_TYPE_BACKPLANE) 404*4ac7516bSRavi Kumar return false; 405*4ac7516bSRavi Kumar break; 406*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_1000BASE_T: 407*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_1000BASE_X: 408*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_NBASE_T: 409*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_10GBASE_T: 410*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_10GBASE_R: 411*4ac7516bSRavi Kumar if (phy_data->conn_type == AXGBE_CONN_TYPE_MDIO) 412*4ac7516bSRavi Kumar return false; 413*4ac7516bSRavi Kumar break; 414*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_SFP: 415*4ac7516bSRavi Kumar if (phy_data->conn_type == AXGBE_CONN_TYPE_SFP) 416*4ac7516bSRavi Kumar return false; 417*4ac7516bSRavi Kumar break; 418*4ac7516bSRavi Kumar default: 419*4ac7516bSRavi Kumar break; 420*4ac7516bSRavi Kumar } 421*4ac7516bSRavi Kumar 422*4ac7516bSRavi Kumar return true; 423*4ac7516bSRavi Kumar } 424*4ac7516bSRavi Kumar 425*4ac7516bSRavi Kumar static bool axgbe_phy_port_enabled(struct axgbe_port *pdata) 426*4ac7516bSRavi Kumar { 427*4ac7516bSRavi Kumar unsigned int reg; 428*4ac7516bSRavi Kumar 429*4ac7516bSRavi Kumar reg = XP_IOREAD(pdata, XP_PROP_0); 430*4ac7516bSRavi Kumar if (!XP_GET_BITS(reg, XP_PROP_0, PORT_SPEEDS)) 431*4ac7516bSRavi Kumar return false; 432*4ac7516bSRavi Kumar if (!XP_GET_BITS(reg, XP_PROP_0, CONN_TYPE)) 433*4ac7516bSRavi Kumar return false; 434*4ac7516bSRavi Kumar 435*4ac7516bSRavi Kumar return true; 436*4ac7516bSRavi Kumar } 437*4ac7516bSRavi Kumar 438*4ac7516bSRavi Kumar static int axgbe_phy_init(struct axgbe_port *pdata) 439*4ac7516bSRavi Kumar { 440*4ac7516bSRavi Kumar struct axgbe_phy_data *phy_data; 441*4ac7516bSRavi Kumar unsigned int reg; 442*4ac7516bSRavi Kumar int ret; 443*4ac7516bSRavi Kumar 444*4ac7516bSRavi Kumar /* Check if enabled */ 445*4ac7516bSRavi Kumar if (!axgbe_phy_port_enabled(pdata)) { 446*4ac7516bSRavi Kumar PMD_DRV_LOG(ERR, "device is not enabled\n"); 447*4ac7516bSRavi Kumar return -ENODEV; 448*4ac7516bSRavi Kumar } 449*4ac7516bSRavi Kumar 450*4ac7516bSRavi Kumar /* Initialize the I2C controller */ 451*4ac7516bSRavi Kumar ret = pdata->i2c_if.i2c_init(pdata); 452*4ac7516bSRavi Kumar if (ret) 453*4ac7516bSRavi Kumar return ret; 454*4ac7516bSRavi Kumar 455*4ac7516bSRavi Kumar phy_data = rte_zmalloc("phy_data memory", sizeof(*phy_data), 0); 456*4ac7516bSRavi Kumar if (!phy_data) { 457*4ac7516bSRavi Kumar PMD_DRV_LOG(ERR, "phy_data allocation failed\n"); 458*4ac7516bSRavi Kumar return -ENOMEM; 459*4ac7516bSRavi Kumar } 460*4ac7516bSRavi Kumar pdata->phy_data = phy_data; 461*4ac7516bSRavi Kumar 462*4ac7516bSRavi Kumar reg = XP_IOREAD(pdata, XP_PROP_0); 463*4ac7516bSRavi Kumar phy_data->port_mode = XP_GET_BITS(reg, XP_PROP_0, PORT_MODE); 464*4ac7516bSRavi Kumar phy_data->port_id = XP_GET_BITS(reg, XP_PROP_0, PORT_ID); 465*4ac7516bSRavi Kumar phy_data->port_speeds = XP_GET_BITS(reg, XP_PROP_0, PORT_SPEEDS); 466*4ac7516bSRavi Kumar phy_data->conn_type = XP_GET_BITS(reg, XP_PROP_0, CONN_TYPE); 467*4ac7516bSRavi Kumar phy_data->mdio_addr = XP_GET_BITS(reg, XP_PROP_0, MDIO_ADDR); 468*4ac7516bSRavi Kumar 469*4ac7516bSRavi Kumar reg = XP_IOREAD(pdata, XP_PROP_4); 470*4ac7516bSRavi Kumar phy_data->redrv = XP_GET_BITS(reg, XP_PROP_4, REDRV_PRESENT); 471*4ac7516bSRavi Kumar phy_data->redrv_if = XP_GET_BITS(reg, XP_PROP_4, REDRV_IF); 472*4ac7516bSRavi Kumar phy_data->redrv_addr = XP_GET_BITS(reg, XP_PROP_4, REDRV_ADDR); 473*4ac7516bSRavi Kumar phy_data->redrv_lane = XP_GET_BITS(reg, XP_PROP_4, REDRV_LANE); 474*4ac7516bSRavi Kumar phy_data->redrv_model = XP_GET_BITS(reg, XP_PROP_4, REDRV_MODEL); 475*4ac7516bSRavi Kumar 476*4ac7516bSRavi Kumar /* Validate the connection requested */ 477*4ac7516bSRavi Kumar if (axgbe_phy_conn_type_mismatch(pdata)) { 478*4ac7516bSRavi Kumar PMD_DRV_LOG(ERR, "phy mode/connection mismatch (%#x/%#x)\n", 479*4ac7516bSRavi Kumar phy_data->port_mode, phy_data->conn_type); 480*4ac7516bSRavi Kumar return -EINVAL; 481*4ac7516bSRavi Kumar } 482*4ac7516bSRavi Kumar 483*4ac7516bSRavi Kumar /* Validate the mode requested */ 484*4ac7516bSRavi Kumar if (axgbe_phy_port_mode_mismatch(pdata)) { 485*4ac7516bSRavi Kumar PMD_DRV_LOG(ERR, "phy mode/speed mismatch (%#x/%#x)\n", 486*4ac7516bSRavi Kumar phy_data->port_mode, phy_data->port_speeds); 487*4ac7516bSRavi Kumar return -EINVAL; 488*4ac7516bSRavi Kumar } 489*4ac7516bSRavi Kumar 490*4ac7516bSRavi Kumar /* Check for and validate MDIO reset support */ 491*4ac7516bSRavi Kumar ret = axgbe_phy_mdio_reset_setup(pdata); 492*4ac7516bSRavi Kumar if (ret) 493*4ac7516bSRavi Kumar return ret; 494*4ac7516bSRavi Kumar 495*4ac7516bSRavi Kumar /* Validate the re-driver information */ 496*4ac7516bSRavi Kumar if (axgbe_phy_redrv_error(phy_data)) { 497*4ac7516bSRavi Kumar PMD_DRV_LOG(ERR, "phy re-driver settings error\n"); 498*4ac7516bSRavi Kumar return -EINVAL; 499*4ac7516bSRavi Kumar } 500*4ac7516bSRavi Kumar pdata->kr_redrv = phy_data->redrv; 501*4ac7516bSRavi Kumar 502*4ac7516bSRavi Kumar /* Indicate current mode is unknown */ 503*4ac7516bSRavi Kumar phy_data->cur_mode = AXGBE_MODE_UNKNOWN; 504*4ac7516bSRavi Kumar 505*4ac7516bSRavi Kumar /* Initialize supported features */ 506*4ac7516bSRavi Kumar pdata->phy.supported = 0; 507*4ac7516bSRavi Kumar 508*4ac7516bSRavi Kumar switch (phy_data->port_mode) { 509*4ac7516bSRavi Kumar /* Backplane support */ 510*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_BACKPLANE: 511*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Autoneg; 512*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; 513*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Backplane; 514*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) { 515*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_1000baseKX_Full; 516*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_KX_1000; 517*4ac7516bSRavi Kumar } 518*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000) { 519*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_10000baseKR_Full; 520*4ac7516bSRavi Kumar if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE) 521*4ac7516bSRavi Kumar pdata->phy.supported |= 522*4ac7516bSRavi Kumar SUPPORTED_10000baseR_FEC; 523*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_KR; 524*4ac7516bSRavi Kumar } 525*4ac7516bSRavi Kumar 526*4ac7516bSRavi Kumar phy_data->phydev_mode = AXGBE_MDIO_MODE_NONE; 527*4ac7516bSRavi Kumar break; 528*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_BACKPLANE_2500: 529*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; 530*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Backplane; 531*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_2500baseX_Full; 532*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_KX_2500; 533*4ac7516bSRavi Kumar 534*4ac7516bSRavi Kumar phy_data->phydev_mode = AXGBE_MDIO_MODE_NONE; 535*4ac7516bSRavi Kumar break; 536*4ac7516bSRavi Kumar 537*4ac7516bSRavi Kumar /* MDIO 1GBase-T support */ 538*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_1000BASE_T: 539*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Autoneg; 540*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; 541*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_TP; 542*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) { 543*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_100baseT_Full; 544*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_SGMII_100; 545*4ac7516bSRavi Kumar } 546*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) { 547*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_1000baseT_Full; 548*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_SGMII_1000; 549*4ac7516bSRavi Kumar } 550*4ac7516bSRavi Kumar 551*4ac7516bSRavi Kumar phy_data->phydev_mode = AXGBE_MDIO_MODE_CL22; 552*4ac7516bSRavi Kumar break; 553*4ac7516bSRavi Kumar 554*4ac7516bSRavi Kumar /* MDIO Base-X support */ 555*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_1000BASE_X: 556*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Autoneg; 557*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; 558*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_FIBRE; 559*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_1000baseT_Full; 560*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_X; 561*4ac7516bSRavi Kumar 562*4ac7516bSRavi Kumar phy_data->phydev_mode = AXGBE_MDIO_MODE_CL22; 563*4ac7516bSRavi Kumar break; 564*4ac7516bSRavi Kumar 565*4ac7516bSRavi Kumar /* MDIO NBase-T support */ 566*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_NBASE_T: 567*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Autoneg; 568*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; 569*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_TP; 570*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) { 571*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_100baseT_Full; 572*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_SGMII_100; 573*4ac7516bSRavi Kumar } 574*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) { 575*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_1000baseT_Full; 576*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_SGMII_1000; 577*4ac7516bSRavi Kumar } 578*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500) { 579*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_2500baseX_Full; 580*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_KX_2500; 581*4ac7516bSRavi Kumar } 582*4ac7516bSRavi Kumar 583*4ac7516bSRavi Kumar phy_data->phydev_mode = AXGBE_MDIO_MODE_CL45; 584*4ac7516bSRavi Kumar break; 585*4ac7516bSRavi Kumar 586*4ac7516bSRavi Kumar /* 10GBase-T support */ 587*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_10GBASE_T: 588*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Autoneg; 589*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; 590*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_TP; 591*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) { 592*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_100baseT_Full; 593*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_SGMII_100; 594*4ac7516bSRavi Kumar } 595*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) { 596*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_1000baseT_Full; 597*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_SGMII_1000; 598*4ac7516bSRavi Kumar } 599*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000) { 600*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_10000baseT_Full; 601*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_KR; 602*4ac7516bSRavi Kumar } 603*4ac7516bSRavi Kumar 604*4ac7516bSRavi Kumar phy_data->phydev_mode = AXGBE_MDIO_MODE_NONE; 605*4ac7516bSRavi Kumar break; 606*4ac7516bSRavi Kumar 607*4ac7516bSRavi Kumar /* 10GBase-R support */ 608*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_10GBASE_R: 609*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Autoneg; 610*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; 611*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_TP; 612*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_10000baseT_Full; 613*4ac7516bSRavi Kumar if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE) 614*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_10000baseR_FEC; 615*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_SFI; 616*4ac7516bSRavi Kumar 617*4ac7516bSRavi Kumar phy_data->phydev_mode = AXGBE_MDIO_MODE_NONE; 618*4ac7516bSRavi Kumar break; 619*4ac7516bSRavi Kumar 620*4ac7516bSRavi Kumar /* SFP support */ 621*4ac7516bSRavi Kumar case AXGBE_PORT_MODE_SFP: 622*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Autoneg; 623*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; 624*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_TP; 625*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_FIBRE; 626*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) { 627*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_100baseT_Full; 628*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_SGMII_100; 629*4ac7516bSRavi Kumar } 630*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) { 631*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_1000baseT_Full; 632*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_SGMII_1000; 633*4ac7516bSRavi Kumar } 634*4ac7516bSRavi Kumar if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000) { 635*4ac7516bSRavi Kumar pdata->phy.supported |= SUPPORTED_10000baseT_Full; 636*4ac7516bSRavi Kumar phy_data->start_mode = AXGBE_MODE_SFI; 637*4ac7516bSRavi Kumar if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE) 638*4ac7516bSRavi Kumar pdata->phy.supported |= 639*4ac7516bSRavi Kumar SUPPORTED_10000baseR_FEC; 640*4ac7516bSRavi Kumar } 641*4ac7516bSRavi Kumar 642*4ac7516bSRavi Kumar phy_data->phydev_mode = AXGBE_MDIO_MODE_CL22; 643*4ac7516bSRavi Kumar 644*4ac7516bSRavi Kumar axgbe_phy_sfp_setup(pdata); 645*4ac7516bSRavi Kumar break; 646*4ac7516bSRavi Kumar default: 647*4ac7516bSRavi Kumar return -EINVAL; 648*4ac7516bSRavi Kumar } 649*4ac7516bSRavi Kumar 650*4ac7516bSRavi Kumar if ((phy_data->conn_type & AXGBE_CONN_TYPE_MDIO) && 651*4ac7516bSRavi Kumar (phy_data->phydev_mode != AXGBE_MDIO_MODE_NONE)) { 652*4ac7516bSRavi Kumar ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->mdio_addr, 653*4ac7516bSRavi Kumar phy_data->phydev_mode); 654*4ac7516bSRavi Kumar if (ret) { 655*4ac7516bSRavi Kumar PMD_DRV_LOG(ERR, "mdio port/clause not compatible (%d/%u)\n", 656*4ac7516bSRavi Kumar phy_data->mdio_addr, phy_data->phydev_mode); 657*4ac7516bSRavi Kumar return -EINVAL; 658*4ac7516bSRavi Kumar } 659*4ac7516bSRavi Kumar } 660*4ac7516bSRavi Kumar 661*4ac7516bSRavi Kumar if (phy_data->redrv && !phy_data->redrv_if) { 662*4ac7516bSRavi Kumar ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->redrv_addr, 663*4ac7516bSRavi Kumar AXGBE_MDIO_MODE_CL22); 664*4ac7516bSRavi Kumar if (ret) { 665*4ac7516bSRavi Kumar PMD_DRV_LOG(ERR, "redriver mdio port not compatible (%u)\n", 666*4ac7516bSRavi Kumar phy_data->redrv_addr); 667*4ac7516bSRavi Kumar return -EINVAL; 668*4ac7516bSRavi Kumar } 669*4ac7516bSRavi Kumar } 670*4ac7516bSRavi Kumar return 0; 671*4ac7516bSRavi Kumar } 672*4ac7516bSRavi Kumar void axgbe_init_function_ptrs_phy_v2(struct axgbe_phy_if *phy_if) 673*4ac7516bSRavi Kumar { 674*4ac7516bSRavi Kumar struct axgbe_phy_impl_if *phy_impl = &phy_if->phy_impl; 675*4ac7516bSRavi Kumar 676*4ac7516bSRavi Kumar phy_impl->init = axgbe_phy_init; 677*4ac7516bSRavi Kumar } 678