xref: /dpdk/drivers/net/axgbe/axgbe_phy_impl.c (revision 936e294c8eb025df7f070b62389ee8ce49d6463f)
14ac7516bSRavi Kumar /*   SPDX-License-Identifier: BSD-3-Clause
24ac7516bSRavi Kumar  *   Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved.
34ac7516bSRavi Kumar  *   Copyright(c) 2018 Synopsys, Inc. All rights reserved.
44ac7516bSRavi Kumar  */
54ac7516bSRavi Kumar 
64ac7516bSRavi Kumar #include "axgbe_ethdev.h"
74ac7516bSRavi Kumar #include "axgbe_common.h"
84ac7516bSRavi Kumar #include "axgbe_phy.h"
94ac7516bSRavi Kumar 
104ac7516bSRavi Kumar #define AXGBE_PHY_PORT_SPEED_100	BIT(0)
114ac7516bSRavi Kumar #define AXGBE_PHY_PORT_SPEED_1000	BIT(1)
124ac7516bSRavi Kumar #define AXGBE_PHY_PORT_SPEED_2500	BIT(2)
134ac7516bSRavi Kumar #define AXGBE_PHY_PORT_SPEED_10000	BIT(3)
144ac7516bSRavi Kumar 
154ac7516bSRavi Kumar #define AXGBE_MUTEX_RELEASE		0x80000000
164ac7516bSRavi Kumar 
174ac7516bSRavi Kumar #define AXGBE_SFP_DIRECT		7
184ac7516bSRavi Kumar 
194ac7516bSRavi Kumar /* I2C target addresses */
204ac7516bSRavi Kumar #define AXGBE_SFP_SERIAL_ID_ADDRESS	0x50
214ac7516bSRavi Kumar #define AXGBE_SFP_DIAG_INFO_ADDRESS	0x51
224ac7516bSRavi Kumar #define AXGBE_SFP_PHY_ADDRESS		0x56
234ac7516bSRavi Kumar #define AXGBE_GPIO_ADDRESS_PCA9555	0x20
244ac7516bSRavi Kumar 
254ac7516bSRavi Kumar /* SFP sideband signal indicators */
264ac7516bSRavi Kumar #define AXGBE_GPIO_NO_TX_FAULT		BIT(0)
274ac7516bSRavi Kumar #define AXGBE_GPIO_NO_RATE_SELECT	BIT(1)
284ac7516bSRavi Kumar #define AXGBE_GPIO_NO_MOD_ABSENT	BIT(2)
294ac7516bSRavi Kumar #define AXGBE_GPIO_NO_RX_LOS		BIT(3)
304ac7516bSRavi Kumar 
314ac7516bSRavi Kumar /* Rate-change complete wait/retry count */
324ac7516bSRavi Kumar #define AXGBE_RATECHANGE_COUNT		500
334ac7516bSRavi Kumar 
3400072056SRavi Kumar /* CDR delay values for KR support (in usec) */
3500072056SRavi Kumar #define AXGBE_CDR_DELAY_INIT		10000
3600072056SRavi Kumar #define AXGBE_CDR_DELAY_INC		10000
3700072056SRavi Kumar #define AXGBE_CDR_DELAY_MAX		100000
3800072056SRavi Kumar 
394ac7516bSRavi Kumar enum axgbe_port_mode {
404ac7516bSRavi Kumar 	AXGBE_PORT_MODE_RSVD = 0,
414ac7516bSRavi Kumar 	AXGBE_PORT_MODE_BACKPLANE,
424ac7516bSRavi Kumar 	AXGBE_PORT_MODE_BACKPLANE_2500,
434ac7516bSRavi Kumar 	AXGBE_PORT_MODE_1000BASE_T,
444ac7516bSRavi Kumar 	AXGBE_PORT_MODE_1000BASE_X,
454ac7516bSRavi Kumar 	AXGBE_PORT_MODE_NBASE_T,
464ac7516bSRavi Kumar 	AXGBE_PORT_MODE_10GBASE_T,
474ac7516bSRavi Kumar 	AXGBE_PORT_MODE_10GBASE_R,
484ac7516bSRavi Kumar 	AXGBE_PORT_MODE_SFP,
494ac7516bSRavi Kumar 	AXGBE_PORT_MODE_MAX,
504ac7516bSRavi Kumar };
514ac7516bSRavi Kumar 
524ac7516bSRavi Kumar enum axgbe_conn_type {
534ac7516bSRavi Kumar 	AXGBE_CONN_TYPE_NONE = 0,
544ac7516bSRavi Kumar 	AXGBE_CONN_TYPE_SFP,
554ac7516bSRavi Kumar 	AXGBE_CONN_TYPE_MDIO,
564ac7516bSRavi Kumar 	AXGBE_CONN_TYPE_RSVD1,
574ac7516bSRavi Kumar 	AXGBE_CONN_TYPE_BACKPLANE,
584ac7516bSRavi Kumar 	AXGBE_CONN_TYPE_MAX,
594ac7516bSRavi Kumar };
604ac7516bSRavi Kumar 
614ac7516bSRavi Kumar /* SFP/SFP+ related definitions */
624ac7516bSRavi Kumar enum axgbe_sfp_comm {
634ac7516bSRavi Kumar 	AXGBE_SFP_COMM_DIRECT = 0,
644ac7516bSRavi Kumar 	AXGBE_SFP_COMM_PCA9545,
654ac7516bSRavi Kumar };
664ac7516bSRavi Kumar 
674ac7516bSRavi Kumar enum axgbe_sfp_cable {
684ac7516bSRavi Kumar 	AXGBE_SFP_CABLE_UNKNOWN = 0,
694ac7516bSRavi Kumar 	AXGBE_SFP_CABLE_ACTIVE,
704ac7516bSRavi Kumar 	AXGBE_SFP_CABLE_PASSIVE,
714ac7516bSRavi Kumar };
724ac7516bSRavi Kumar 
734ac7516bSRavi Kumar enum axgbe_sfp_base {
744ac7516bSRavi Kumar 	AXGBE_SFP_BASE_UNKNOWN = 0,
754ac7516bSRavi Kumar 	AXGBE_SFP_BASE_1000_T,
764ac7516bSRavi Kumar 	AXGBE_SFP_BASE_1000_SX,
774ac7516bSRavi Kumar 	AXGBE_SFP_BASE_1000_LX,
784ac7516bSRavi Kumar 	AXGBE_SFP_BASE_1000_CX,
794ac7516bSRavi Kumar 	AXGBE_SFP_BASE_10000_SR,
804ac7516bSRavi Kumar 	AXGBE_SFP_BASE_10000_LR,
814ac7516bSRavi Kumar 	AXGBE_SFP_BASE_10000_LRM,
824ac7516bSRavi Kumar 	AXGBE_SFP_BASE_10000_ER,
834ac7516bSRavi Kumar 	AXGBE_SFP_BASE_10000_CR,
844ac7516bSRavi Kumar };
854ac7516bSRavi Kumar 
864ac7516bSRavi Kumar enum axgbe_sfp_speed {
874ac7516bSRavi Kumar 	AXGBE_SFP_SPEED_UNKNOWN = 0,
884ac7516bSRavi Kumar 	AXGBE_SFP_SPEED_100_1000,
894ac7516bSRavi Kumar 	AXGBE_SFP_SPEED_1000,
904ac7516bSRavi Kumar 	AXGBE_SFP_SPEED_10000,
914ac7516bSRavi Kumar };
924ac7516bSRavi Kumar 
934ac7516bSRavi Kumar /* SFP Serial ID Base ID values relative to an offset of 0 */
944ac7516bSRavi Kumar #define AXGBE_SFP_BASE_ID			0
954ac7516bSRavi Kumar #define AXGBE_SFP_ID_SFP			0x03
964ac7516bSRavi Kumar 
974ac7516bSRavi Kumar #define AXGBE_SFP_BASE_EXT_ID			1
984ac7516bSRavi Kumar #define AXGBE_SFP_EXT_ID_SFP			0x04
994ac7516bSRavi Kumar 
1004ac7516bSRavi Kumar #define AXGBE_SFP_BASE_10GBE_CC			3
1014ac7516bSRavi Kumar #define AXGBE_SFP_BASE_10GBE_CC_SR		BIT(4)
1024ac7516bSRavi Kumar #define AXGBE_SFP_BASE_10GBE_CC_LR		BIT(5)
1034ac7516bSRavi Kumar #define AXGBE_SFP_BASE_10GBE_CC_LRM		BIT(6)
1044ac7516bSRavi Kumar #define AXGBE_SFP_BASE_10GBE_CC_ER		BIT(7)
1054ac7516bSRavi Kumar 
1064ac7516bSRavi Kumar #define AXGBE_SFP_BASE_1GBE_CC			6
1074ac7516bSRavi Kumar #define AXGBE_SFP_BASE_1GBE_CC_SX		BIT(0)
1084ac7516bSRavi Kumar #define AXGBE_SFP_BASE_1GBE_CC_LX		BIT(1)
1094ac7516bSRavi Kumar #define AXGBE_SFP_BASE_1GBE_CC_CX		BIT(2)
1104ac7516bSRavi Kumar #define AXGBE_SFP_BASE_1GBE_CC_T		BIT(3)
1114ac7516bSRavi Kumar 
1124ac7516bSRavi Kumar #define AXGBE_SFP_BASE_CABLE			8
1134ac7516bSRavi Kumar #define AXGBE_SFP_BASE_CABLE_PASSIVE		BIT(2)
1144ac7516bSRavi Kumar #define AXGBE_SFP_BASE_CABLE_ACTIVE		BIT(3)
1154ac7516bSRavi Kumar 
1164ac7516bSRavi Kumar #define AXGBE_SFP_BASE_BR			12
1174ac7516bSRavi Kumar #define AXGBE_SFP_BASE_BR_1GBE_MIN		0x0a
1184ac7516bSRavi Kumar #define AXGBE_SFP_BASE_BR_1GBE_MAX		0x0d
1194ac7516bSRavi Kumar #define AXGBE_SFP_BASE_BR_10GBE_MIN		0x64
1204ac7516bSRavi Kumar #define AXGBE_SFP_BASE_BR_10GBE_MAX		0x68
1214ac7516bSRavi Kumar 
1224ac7516bSRavi Kumar #define AXGBE_SFP_BASE_CU_CABLE_LEN		18
1234ac7516bSRavi Kumar 
1244ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_NAME		20
1254ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_NAME_LEN		16
1264ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_PN		40
1274ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_PN_LEN		16
1284ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_REV		56
1294ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_REV_LEN		4
1304ac7516bSRavi Kumar 
1314ac7516bSRavi Kumar #define AXGBE_SFP_BASE_CC			63
1324ac7516bSRavi Kumar 
1334ac7516bSRavi Kumar /* SFP Serial ID Extended ID values relative to an offset of 64 */
1344ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_SN		4
1354ac7516bSRavi Kumar #define AXGBE_SFP_BASE_VENDOR_SN_LEN		16
1364ac7516bSRavi Kumar 
1374ac7516bSRavi Kumar #define AXGBE_SFP_EXTD_DIAG			28
1384ac7516bSRavi Kumar #define AXGBE_SFP_EXTD_DIAG_ADDR_CHANGE		BIT(2)
1394ac7516bSRavi Kumar 
1404ac7516bSRavi Kumar #define AXGBE_SFP_EXTD_SFF_8472			30
1414ac7516bSRavi Kumar 
1424ac7516bSRavi Kumar #define AXGBE_SFP_EXTD_CC			31
1434ac7516bSRavi Kumar 
1444ac7516bSRavi Kumar struct axgbe_sfp_eeprom {
1454ac7516bSRavi Kumar 	u8 base[64];
1464ac7516bSRavi Kumar 	u8 extd[32];
1474ac7516bSRavi Kumar 	u8 vendor[32];
1484ac7516bSRavi Kumar };
1494ac7516bSRavi Kumar 
1504ac7516bSRavi Kumar #define AXGBE_BEL_FUSE_VENDOR	"BEL-FUSE"
1514ac7516bSRavi Kumar #define AXGBE_BEL_FUSE_PARTNO	"1GBT-SFP06"
1524ac7516bSRavi Kumar 
1534ac7516bSRavi Kumar struct axgbe_sfp_ascii {
1544ac7516bSRavi Kumar 	union {
1554ac7516bSRavi Kumar 		char vendor[AXGBE_SFP_BASE_VENDOR_NAME_LEN + 1];
1564ac7516bSRavi Kumar 		char partno[AXGBE_SFP_BASE_VENDOR_PN_LEN + 1];
1574ac7516bSRavi Kumar 		char rev[AXGBE_SFP_BASE_VENDOR_REV_LEN + 1];
1584ac7516bSRavi Kumar 		char serno[AXGBE_SFP_BASE_VENDOR_SN_LEN + 1];
1594ac7516bSRavi Kumar 	} u;
1604ac7516bSRavi Kumar };
1614ac7516bSRavi Kumar 
1624ac7516bSRavi Kumar /* MDIO PHY reset types */
1634ac7516bSRavi Kumar enum axgbe_mdio_reset {
1644ac7516bSRavi Kumar 	AXGBE_MDIO_RESET_NONE = 0,
1654ac7516bSRavi Kumar 	AXGBE_MDIO_RESET_I2C_GPIO,
1664ac7516bSRavi Kumar 	AXGBE_MDIO_RESET_INT_GPIO,
1674ac7516bSRavi Kumar 	AXGBE_MDIO_RESET_MAX,
1684ac7516bSRavi Kumar };
1694ac7516bSRavi Kumar 
1704ac7516bSRavi Kumar /* Re-driver related definitions */
1714ac7516bSRavi Kumar enum axgbe_phy_redrv_if {
1724ac7516bSRavi Kumar 	AXGBE_PHY_REDRV_IF_MDIO = 0,
1734ac7516bSRavi Kumar 	AXGBE_PHY_REDRV_IF_I2C,
1744ac7516bSRavi Kumar 	AXGBE_PHY_REDRV_IF_MAX,
1754ac7516bSRavi Kumar };
1764ac7516bSRavi Kumar 
1774ac7516bSRavi Kumar enum axgbe_phy_redrv_model {
1784ac7516bSRavi Kumar 	AXGBE_PHY_REDRV_MODEL_4223 = 0,
1794ac7516bSRavi Kumar 	AXGBE_PHY_REDRV_MODEL_4227,
1804ac7516bSRavi Kumar 	AXGBE_PHY_REDRV_MODEL_MAX,
1814ac7516bSRavi Kumar };
1824ac7516bSRavi Kumar 
1834ac7516bSRavi Kumar enum axgbe_phy_redrv_mode {
1844ac7516bSRavi Kumar 	AXGBE_PHY_REDRV_MODE_CX = 5,
1854ac7516bSRavi Kumar 	AXGBE_PHY_REDRV_MODE_SR = 9,
1864ac7516bSRavi Kumar };
1874ac7516bSRavi Kumar 
1884ac7516bSRavi Kumar #define AXGBE_PHY_REDRV_MODE_REG	0x12b0
1894ac7516bSRavi Kumar 
1904ac7516bSRavi Kumar /* PHY related configuration information */
1914ac7516bSRavi Kumar struct axgbe_phy_data {
1924ac7516bSRavi Kumar 	enum axgbe_port_mode port_mode;
1934ac7516bSRavi Kumar 
1944ac7516bSRavi Kumar 	unsigned int port_id;
1954ac7516bSRavi Kumar 
1964ac7516bSRavi Kumar 	unsigned int port_speeds;
1974ac7516bSRavi Kumar 
1984ac7516bSRavi Kumar 	enum axgbe_conn_type conn_type;
1994ac7516bSRavi Kumar 
2004ac7516bSRavi Kumar 	enum axgbe_mode cur_mode;
2014ac7516bSRavi Kumar 	enum axgbe_mode start_mode;
2024ac7516bSRavi Kumar 
2034ac7516bSRavi Kumar 	unsigned int rrc_count;
2044ac7516bSRavi Kumar 
2054ac7516bSRavi Kumar 	unsigned int mdio_addr;
2064ac7516bSRavi Kumar 
2074ac7516bSRavi Kumar 	unsigned int comm_owned;
2084ac7516bSRavi Kumar 
2094ac7516bSRavi Kumar 	/* SFP Support */
2104ac7516bSRavi Kumar 	enum axgbe_sfp_comm sfp_comm;
2114ac7516bSRavi Kumar 	unsigned int sfp_mux_address;
2124ac7516bSRavi Kumar 	unsigned int sfp_mux_channel;
2134ac7516bSRavi Kumar 
2144ac7516bSRavi Kumar 	unsigned int sfp_gpio_address;
2154ac7516bSRavi Kumar 	unsigned int sfp_gpio_mask;
2164ac7516bSRavi Kumar 	unsigned int sfp_gpio_rx_los;
2174ac7516bSRavi Kumar 	unsigned int sfp_gpio_tx_fault;
2184ac7516bSRavi Kumar 	unsigned int sfp_gpio_mod_absent;
2194ac7516bSRavi Kumar 	unsigned int sfp_gpio_rate_select;
2204ac7516bSRavi Kumar 
2214ac7516bSRavi Kumar 	unsigned int sfp_rx_los;
2224ac7516bSRavi Kumar 	unsigned int sfp_tx_fault;
2234ac7516bSRavi Kumar 	unsigned int sfp_mod_absent;
2244ac7516bSRavi Kumar 	unsigned int sfp_diags;
2254ac7516bSRavi Kumar 	unsigned int sfp_changed;
2264ac7516bSRavi Kumar 	unsigned int sfp_phy_avail;
2274ac7516bSRavi Kumar 	unsigned int sfp_cable_len;
2284ac7516bSRavi Kumar 	enum axgbe_sfp_base sfp_base;
2294ac7516bSRavi Kumar 	enum axgbe_sfp_cable sfp_cable;
2304ac7516bSRavi Kumar 	enum axgbe_sfp_speed sfp_speed;
2314ac7516bSRavi Kumar 	struct axgbe_sfp_eeprom sfp_eeprom;
2324ac7516bSRavi Kumar 
2334ac7516bSRavi Kumar 	/* External PHY support */
2344ac7516bSRavi Kumar 	enum axgbe_mdio_mode phydev_mode;
2354ac7516bSRavi Kumar 	enum axgbe_mdio_reset mdio_reset;
2364ac7516bSRavi Kumar 	unsigned int mdio_reset_addr;
2374ac7516bSRavi Kumar 	unsigned int mdio_reset_gpio;
2384ac7516bSRavi Kumar 
2394ac7516bSRavi Kumar 	/* Re-driver support */
2404ac7516bSRavi Kumar 	unsigned int redrv;
2414ac7516bSRavi Kumar 	unsigned int redrv_if;
2424ac7516bSRavi Kumar 	unsigned int redrv_addr;
2434ac7516bSRavi Kumar 	unsigned int redrv_lane;
2444ac7516bSRavi Kumar 	unsigned int redrv_model;
24500072056SRavi Kumar 
24600072056SRavi Kumar 	/* KR AN support */
24700072056SRavi Kumar 	unsigned int phy_cdr_notrack;
24800072056SRavi Kumar 	unsigned int phy_cdr_delay;
2494ac7516bSRavi Kumar };
2504ac7516bSRavi Kumar 
251a5c72737SRavi Kumar static enum axgbe_an_mode axgbe_phy_an_mode(struct axgbe_port *pdata);
252a5c72737SRavi Kumar 
253a5c72737SRavi Kumar static int axgbe_phy_i2c_xfer(struct axgbe_port *pdata,
254a5c72737SRavi Kumar 			      struct axgbe_i2c_op *i2c_op)
255a5c72737SRavi Kumar {
256a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
257a5c72737SRavi Kumar 
258a5c72737SRavi Kumar 	/* Be sure we own the bus */
259a5c72737SRavi Kumar 	if (!phy_data->comm_owned)
260a5c72737SRavi Kumar 		return -EIO;
261a5c72737SRavi Kumar 
262a5c72737SRavi Kumar 	return pdata->i2c_if.i2c_xfer(pdata, i2c_op);
263a5c72737SRavi Kumar }
264a5c72737SRavi Kumar 
265a5c72737SRavi Kumar static int axgbe_phy_redrv_write(struct axgbe_port *pdata, unsigned int reg,
266a5c72737SRavi Kumar 				 unsigned int val)
267a5c72737SRavi Kumar {
268a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
269a5c72737SRavi Kumar 	struct axgbe_i2c_op i2c_op;
270a5c72737SRavi Kumar 	uint16_t *redrv_val;
271a5c72737SRavi Kumar 	u8 redrv_data[5], csum;
272a5c72737SRavi Kumar 	unsigned int i, retry;
273a5c72737SRavi Kumar 	int ret;
274a5c72737SRavi Kumar 
275a5c72737SRavi Kumar 	/* High byte of register contains read/write indicator */
276a5c72737SRavi Kumar 	redrv_data[0] = ((reg >> 8) & 0xff) << 1;
277a5c72737SRavi Kumar 	redrv_data[1] = reg & 0xff;
278a5c72737SRavi Kumar 	redrv_val = (uint16_t *)&redrv_data[2];
279a5c72737SRavi Kumar 	*redrv_val = rte_cpu_to_be_16(val);
280a5c72737SRavi Kumar 
281a5c72737SRavi Kumar 	/* Calculate 1 byte checksum */
282a5c72737SRavi Kumar 	csum = 0;
283a5c72737SRavi Kumar 	for (i = 0; i < 4; i++) {
284a5c72737SRavi Kumar 		csum += redrv_data[i];
285a5c72737SRavi Kumar 		if (redrv_data[i] > csum)
286a5c72737SRavi Kumar 			csum++;
287a5c72737SRavi Kumar 	}
288a5c72737SRavi Kumar 	redrv_data[4] = ~csum;
289a5c72737SRavi Kumar 
290a5c72737SRavi Kumar 	retry = 1;
291a5c72737SRavi Kumar again1:
292a5c72737SRavi Kumar 	i2c_op.cmd = AXGBE_I2C_CMD_WRITE;
293a5c72737SRavi Kumar 	i2c_op.target = phy_data->redrv_addr;
294a5c72737SRavi Kumar 	i2c_op.len = sizeof(redrv_data);
295a5c72737SRavi Kumar 	i2c_op.buf = redrv_data;
296a5c72737SRavi Kumar 	ret = axgbe_phy_i2c_xfer(pdata, &i2c_op);
297a5c72737SRavi Kumar 	if (ret) {
298a5c72737SRavi Kumar 		if ((ret == -EAGAIN) && retry--)
299a5c72737SRavi Kumar 			goto again1;
300a5c72737SRavi Kumar 
301a5c72737SRavi Kumar 		return ret;
302a5c72737SRavi Kumar 	}
303a5c72737SRavi Kumar 
304a5c72737SRavi Kumar 	retry = 1;
305a5c72737SRavi Kumar again2:
306a5c72737SRavi Kumar 	i2c_op.cmd = AXGBE_I2C_CMD_READ;
307a5c72737SRavi Kumar 	i2c_op.target = phy_data->redrv_addr;
308a5c72737SRavi Kumar 	i2c_op.len = 1;
309a5c72737SRavi Kumar 	i2c_op.buf = redrv_data;
310a5c72737SRavi Kumar 	ret = axgbe_phy_i2c_xfer(pdata, &i2c_op);
311a5c72737SRavi Kumar 	if (ret) {
312a5c72737SRavi Kumar 		if ((ret == -EAGAIN) && retry--)
313a5c72737SRavi Kumar 			goto again2;
314a5c72737SRavi Kumar 
315a5c72737SRavi Kumar 		return ret;
316a5c72737SRavi Kumar 	}
317a5c72737SRavi Kumar 
318a5c72737SRavi Kumar 	if (redrv_data[0] != 0xff) {
319a5c72737SRavi Kumar 		PMD_DRV_LOG(ERR, "Redriver write checksum error\n");
320a5c72737SRavi Kumar 		ret = -EIO;
321a5c72737SRavi Kumar 	}
322a5c72737SRavi Kumar 
323a5c72737SRavi Kumar 	return ret;
324a5c72737SRavi Kumar }
325a5c72737SRavi Kumar 
326a5c72737SRavi Kumar static int axgbe_phy_i2c_read(struct axgbe_port *pdata, unsigned int target,
327a5c72737SRavi Kumar 			      void *reg, unsigned int reg_len,
328a5c72737SRavi Kumar 			      void *val, unsigned int val_len)
329a5c72737SRavi Kumar {
330a5c72737SRavi Kumar 	struct axgbe_i2c_op i2c_op;
331a5c72737SRavi Kumar 	int retry, ret;
332a5c72737SRavi Kumar 
333a5c72737SRavi Kumar 	retry = 1;
334a5c72737SRavi Kumar again1:
335a5c72737SRavi Kumar 	/* Set the specified register to read */
336a5c72737SRavi Kumar 	i2c_op.cmd = AXGBE_I2C_CMD_WRITE;
337a5c72737SRavi Kumar 	i2c_op.target = target;
338a5c72737SRavi Kumar 	i2c_op.len = reg_len;
339a5c72737SRavi Kumar 	i2c_op.buf = reg;
340a5c72737SRavi Kumar 	ret = axgbe_phy_i2c_xfer(pdata, &i2c_op);
341a5c72737SRavi Kumar 	if (ret) {
342a5c72737SRavi Kumar 		if ((ret == -EAGAIN) && retry--)
343a5c72737SRavi Kumar 			goto again1;
344a5c72737SRavi Kumar 
345a5c72737SRavi Kumar 		return ret;
346a5c72737SRavi Kumar 	}
347a5c72737SRavi Kumar 
348a5c72737SRavi Kumar 	retry = 1;
349a5c72737SRavi Kumar again2:
350a5c72737SRavi Kumar 	/* Read the specfied register */
351a5c72737SRavi Kumar 	i2c_op.cmd = AXGBE_I2C_CMD_READ;
352a5c72737SRavi Kumar 	i2c_op.target = target;
353a5c72737SRavi Kumar 	i2c_op.len = val_len;
354a5c72737SRavi Kumar 	i2c_op.buf = val;
355a5c72737SRavi Kumar 	ret = axgbe_phy_i2c_xfer(pdata, &i2c_op);
356a5c72737SRavi Kumar 	if ((ret == -EAGAIN) && retry--)
357a5c72737SRavi Kumar 		goto again2;
358a5c72737SRavi Kumar 
359a5c72737SRavi Kumar 	return ret;
360a5c72737SRavi Kumar }
361a5c72737SRavi Kumar 
362a5c72737SRavi Kumar static int axgbe_phy_sfp_put_mux(struct axgbe_port *pdata)
363a5c72737SRavi Kumar {
364a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
365a5c72737SRavi Kumar 	struct axgbe_i2c_op i2c_op;
366a5c72737SRavi Kumar 	uint8_t mux_channel;
367a5c72737SRavi Kumar 
368a5c72737SRavi Kumar 	if (phy_data->sfp_comm == AXGBE_SFP_COMM_DIRECT)
369a5c72737SRavi Kumar 		return 0;
370a5c72737SRavi Kumar 
371a5c72737SRavi Kumar 	/* Select no mux channels */
372a5c72737SRavi Kumar 	mux_channel = 0;
373a5c72737SRavi Kumar 	i2c_op.cmd = AXGBE_I2C_CMD_WRITE;
374a5c72737SRavi Kumar 	i2c_op.target = phy_data->sfp_mux_address;
375a5c72737SRavi Kumar 	i2c_op.len = sizeof(mux_channel);
376a5c72737SRavi Kumar 	i2c_op.buf = &mux_channel;
377a5c72737SRavi Kumar 
378a5c72737SRavi Kumar 	return axgbe_phy_i2c_xfer(pdata, &i2c_op);
379a5c72737SRavi Kumar }
380a5c72737SRavi Kumar 
381a5c72737SRavi Kumar static int axgbe_phy_sfp_get_mux(struct axgbe_port *pdata)
382a5c72737SRavi Kumar {
383a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
384a5c72737SRavi Kumar 	struct axgbe_i2c_op i2c_op;
385a5c72737SRavi Kumar 	u8 mux_channel;
386a5c72737SRavi Kumar 
387a5c72737SRavi Kumar 	if (phy_data->sfp_comm == AXGBE_SFP_COMM_DIRECT)
388a5c72737SRavi Kumar 		return 0;
389a5c72737SRavi Kumar 
390a5c72737SRavi Kumar 	/* Select desired mux channel */
391a5c72737SRavi Kumar 	mux_channel = 1 << phy_data->sfp_mux_channel;
392a5c72737SRavi Kumar 	i2c_op.cmd = AXGBE_I2C_CMD_WRITE;
393a5c72737SRavi Kumar 	i2c_op.target = phy_data->sfp_mux_address;
394a5c72737SRavi Kumar 	i2c_op.len = sizeof(mux_channel);
395a5c72737SRavi Kumar 	i2c_op.buf = &mux_channel;
396a5c72737SRavi Kumar 
397a5c72737SRavi Kumar 	return axgbe_phy_i2c_xfer(pdata, &i2c_op);
398a5c72737SRavi Kumar }
399a5c72737SRavi Kumar 
400a5c72737SRavi Kumar static void axgbe_phy_put_comm_ownership(struct axgbe_port *pdata)
401a5c72737SRavi Kumar {
402a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
403a5c72737SRavi Kumar 
404a5c72737SRavi Kumar 	phy_data->comm_owned = 0;
405a5c72737SRavi Kumar 
406a5c72737SRavi Kumar 	pthread_mutex_unlock(&pdata->phy_mutex);
407a5c72737SRavi Kumar }
408a5c72737SRavi Kumar 
409a5c72737SRavi Kumar static int axgbe_phy_get_comm_ownership(struct axgbe_port *pdata)
410a5c72737SRavi Kumar {
411a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
412a5c72737SRavi Kumar 	uint64_t timeout;
413a5c72737SRavi Kumar 	unsigned int mutex_id;
414a5c72737SRavi Kumar 
415a5c72737SRavi Kumar 	/* The I2C and MDIO/GPIO bus is multiplexed between multiple devices,
416a5c72737SRavi Kumar 	 * the driver needs to take the software mutex and then the hardware
417a5c72737SRavi Kumar 	 * mutexes before being able to use the busses.
418a5c72737SRavi Kumar 	 */
419a5c72737SRavi Kumar 	pthread_mutex_lock(&pdata->phy_mutex);
420a5c72737SRavi Kumar 
421c8c2296bSPallantla Poornima 	if (phy_data->comm_owned)
422c8c2296bSPallantla Poornima 		return 0;
423c8c2296bSPallantla Poornima 
424a5c72737SRavi Kumar 	/* Clear the mutexes */
425a5c72737SRavi Kumar 	XP_IOWRITE(pdata, XP_I2C_MUTEX, AXGBE_MUTEX_RELEASE);
426a5c72737SRavi Kumar 	XP_IOWRITE(pdata, XP_MDIO_MUTEX, AXGBE_MUTEX_RELEASE);
427a5c72737SRavi Kumar 
428a5c72737SRavi Kumar 	/* Mutex formats are the same for I2C and MDIO/GPIO */
429a5c72737SRavi Kumar 	mutex_id = 0;
430a5c72737SRavi Kumar 	XP_SET_BITS(mutex_id, XP_I2C_MUTEX, ID, phy_data->port_id);
431a5c72737SRavi Kumar 	XP_SET_BITS(mutex_id, XP_I2C_MUTEX, ACTIVE, 1);
432a5c72737SRavi Kumar 
433a5c72737SRavi Kumar 	timeout = rte_get_timer_cycles() + (rte_get_timer_hz() * 5);
434a5c72737SRavi Kumar 	while (time_before(rte_get_timer_cycles(), timeout)) {
435a5c72737SRavi Kumar 		/* Must be all zeroes in order to obtain the mutex */
436a5c72737SRavi Kumar 		if (XP_IOREAD(pdata, XP_I2C_MUTEX) ||
437a5c72737SRavi Kumar 		    XP_IOREAD(pdata, XP_MDIO_MUTEX)) {
438a5c72737SRavi Kumar 			rte_delay_us(100);
439a5c72737SRavi Kumar 			continue;
440a5c72737SRavi Kumar 		}
441a5c72737SRavi Kumar 
442a5c72737SRavi Kumar 		/* Obtain the mutex */
443a5c72737SRavi Kumar 		XP_IOWRITE(pdata, XP_I2C_MUTEX, mutex_id);
444a5c72737SRavi Kumar 		XP_IOWRITE(pdata, XP_MDIO_MUTEX, mutex_id);
445a5c72737SRavi Kumar 
446a5c72737SRavi Kumar 		phy_data->comm_owned = 1;
447a5c72737SRavi Kumar 		return 0;
448a5c72737SRavi Kumar 	}
449a5c72737SRavi Kumar 
450a5c72737SRavi Kumar 	pthread_mutex_unlock(&pdata->phy_mutex);
451a5c72737SRavi Kumar 
452a5c72737SRavi Kumar 	PMD_DRV_LOG(ERR, "unable to obtain hardware mutexes\n");
453a5c72737SRavi Kumar 
454a5c72737SRavi Kumar 	return -ETIMEDOUT;
455a5c72737SRavi Kumar }
456a5c72737SRavi Kumar 
457a5c72737SRavi Kumar static void axgbe_phy_sfp_phy_settings(struct axgbe_port *pdata)
458a5c72737SRavi Kumar {
459a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
460a5c72737SRavi Kumar 
461a5c72737SRavi Kumar 	if (phy_data->sfp_mod_absent) {
462a5c72737SRavi Kumar 		pdata->phy.speed = SPEED_UNKNOWN;
463a5c72737SRavi Kumar 		pdata->phy.duplex = DUPLEX_UNKNOWN;
464a5c72737SRavi Kumar 		pdata->phy.autoneg = AUTONEG_ENABLE;
465a5c72737SRavi Kumar 		pdata->phy.advertising = pdata->phy.supported;
466a5c72737SRavi Kumar 	}
467a5c72737SRavi Kumar 
468a5c72737SRavi Kumar 	pdata->phy.advertising &= ~ADVERTISED_Autoneg;
469a5c72737SRavi Kumar 	pdata->phy.advertising &= ~ADVERTISED_TP;
470a5c72737SRavi Kumar 	pdata->phy.advertising &= ~ADVERTISED_FIBRE;
471a5c72737SRavi Kumar 	pdata->phy.advertising &= ~ADVERTISED_100baseT_Full;
472a5c72737SRavi Kumar 	pdata->phy.advertising &= ~ADVERTISED_1000baseT_Full;
473a5c72737SRavi Kumar 	pdata->phy.advertising &= ~ADVERTISED_10000baseT_Full;
474a5c72737SRavi Kumar 	pdata->phy.advertising &= ~ADVERTISED_10000baseR_FEC;
475a5c72737SRavi Kumar 
476a5c72737SRavi Kumar 	switch (phy_data->sfp_base) {
477a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_T:
478a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_SX:
479a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_LX:
480a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_CX:
481a5c72737SRavi Kumar 		pdata->phy.speed = SPEED_UNKNOWN;
482a5c72737SRavi Kumar 		pdata->phy.duplex = DUPLEX_UNKNOWN;
483a5c72737SRavi Kumar 		pdata->phy.autoneg = AUTONEG_ENABLE;
484a5c72737SRavi Kumar 		pdata->phy.advertising |= ADVERTISED_Autoneg;
485a5c72737SRavi Kumar 		break;
486a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_10000_SR:
487a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_10000_LR:
488a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_10000_LRM:
489a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_10000_ER:
490a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_10000_CR:
491a5c72737SRavi Kumar 	default:
492a5c72737SRavi Kumar 		pdata->phy.speed = SPEED_10000;
493a5c72737SRavi Kumar 		pdata->phy.duplex = DUPLEX_FULL;
494a5c72737SRavi Kumar 		pdata->phy.autoneg = AUTONEG_DISABLE;
495a5c72737SRavi Kumar 		break;
496a5c72737SRavi Kumar 	}
497a5c72737SRavi Kumar 
498a5c72737SRavi Kumar 	switch (phy_data->sfp_base) {
499a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_T:
500a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_CX:
501a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_10000_CR:
502a5c72737SRavi Kumar 		pdata->phy.advertising |= ADVERTISED_TP;
503a5c72737SRavi Kumar 		break;
504a5c72737SRavi Kumar 	default:
505a5c72737SRavi Kumar 		pdata->phy.advertising |= ADVERTISED_FIBRE;
506a5c72737SRavi Kumar 	}
507a5c72737SRavi Kumar 
508a5c72737SRavi Kumar 	switch (phy_data->sfp_speed) {
509a5c72737SRavi Kumar 	case AXGBE_SFP_SPEED_100_1000:
510a5c72737SRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100)
511a5c72737SRavi Kumar 			pdata->phy.advertising |= ADVERTISED_100baseT_Full;
512a5c72737SRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000)
513a5c72737SRavi Kumar 			pdata->phy.advertising |= ADVERTISED_1000baseT_Full;
514a5c72737SRavi Kumar 		break;
515a5c72737SRavi Kumar 	case AXGBE_SFP_SPEED_1000:
516a5c72737SRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000)
517a5c72737SRavi Kumar 			pdata->phy.advertising |= ADVERTISED_1000baseT_Full;
518a5c72737SRavi Kumar 		break;
519a5c72737SRavi Kumar 	case AXGBE_SFP_SPEED_10000:
520a5c72737SRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000)
521a5c72737SRavi Kumar 			pdata->phy.advertising |= ADVERTISED_10000baseT_Full;
522a5c72737SRavi Kumar 		break;
523a5c72737SRavi Kumar 	default:
524a5c72737SRavi Kumar 		/* Choose the fastest supported speed */
525a5c72737SRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000)
526a5c72737SRavi Kumar 			pdata->phy.advertising |= ADVERTISED_10000baseT_Full;
527a5c72737SRavi Kumar 		else if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000)
528a5c72737SRavi Kumar 			pdata->phy.advertising |= ADVERTISED_1000baseT_Full;
529a5c72737SRavi Kumar 		else if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100)
530a5c72737SRavi Kumar 			pdata->phy.advertising |= ADVERTISED_100baseT_Full;
531a5c72737SRavi Kumar 	}
532a5c72737SRavi Kumar }
533a5c72737SRavi Kumar 
534a5c72737SRavi Kumar static bool axgbe_phy_sfp_bit_rate(struct axgbe_sfp_eeprom *sfp_eeprom,
535a5c72737SRavi Kumar 				   enum axgbe_sfp_speed sfp_speed)
536a5c72737SRavi Kumar {
537a5c72737SRavi Kumar 	u8 *sfp_base, min, max;
538a5c72737SRavi Kumar 
539a5c72737SRavi Kumar 	sfp_base = sfp_eeprom->base;
540a5c72737SRavi Kumar 
541a5c72737SRavi Kumar 	switch (sfp_speed) {
542a5c72737SRavi Kumar 	case AXGBE_SFP_SPEED_1000:
543a5c72737SRavi Kumar 		min = AXGBE_SFP_BASE_BR_1GBE_MIN;
544a5c72737SRavi Kumar 		max = AXGBE_SFP_BASE_BR_1GBE_MAX;
545a5c72737SRavi Kumar 		break;
546a5c72737SRavi Kumar 	case AXGBE_SFP_SPEED_10000:
547a5c72737SRavi Kumar 		min = AXGBE_SFP_BASE_BR_10GBE_MIN;
548a5c72737SRavi Kumar 		max = AXGBE_SFP_BASE_BR_10GBE_MAX;
549a5c72737SRavi Kumar 		break;
550a5c72737SRavi Kumar 	default:
551a5c72737SRavi Kumar 		return false;
552a5c72737SRavi Kumar 	}
553a5c72737SRavi Kumar 
554a5c72737SRavi Kumar 	return ((sfp_base[AXGBE_SFP_BASE_BR] >= min) &&
555a5c72737SRavi Kumar 		(sfp_base[AXGBE_SFP_BASE_BR] <= max));
556a5c72737SRavi Kumar }
557a5c72737SRavi Kumar 
558a5c72737SRavi Kumar static void axgbe_phy_sfp_external_phy(struct axgbe_port *pdata)
559a5c72737SRavi Kumar {
560a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
561a5c72737SRavi Kumar 
562a5c72737SRavi Kumar 	if (!phy_data->sfp_changed)
563a5c72737SRavi Kumar 		return;
564a5c72737SRavi Kumar 
565a5c72737SRavi Kumar 	phy_data->sfp_phy_avail = 0;
566a5c72737SRavi Kumar 
567a5c72737SRavi Kumar 	if (phy_data->sfp_base != AXGBE_SFP_BASE_1000_T)
568a5c72737SRavi Kumar 		return;
569a5c72737SRavi Kumar }
570a5c72737SRavi Kumar 
571a5c72737SRavi Kumar static bool axgbe_phy_belfuse_parse_quirks(struct axgbe_port *pdata)
572a5c72737SRavi Kumar {
573a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
574a5c72737SRavi Kumar 	struct axgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
575a5c72737SRavi Kumar 
576a5c72737SRavi Kumar 	if (memcmp(&sfp_eeprom->base[AXGBE_SFP_BASE_VENDOR_NAME],
57727578231SAndy Green 		   AXGBE_BEL_FUSE_VENDOR, strlen(AXGBE_BEL_FUSE_VENDOR)))
578a5c72737SRavi Kumar 		return false;
579a5c72737SRavi Kumar 
580a5c72737SRavi Kumar 	if (!memcmp(&sfp_eeprom->base[AXGBE_SFP_BASE_VENDOR_PN],
58127578231SAndy Green 		    AXGBE_BEL_FUSE_PARTNO, strlen(AXGBE_BEL_FUSE_PARTNO))) {
582a5c72737SRavi Kumar 		phy_data->sfp_base = AXGBE_SFP_BASE_1000_SX;
583a5c72737SRavi Kumar 		phy_data->sfp_cable = AXGBE_SFP_CABLE_ACTIVE;
584a5c72737SRavi Kumar 		phy_data->sfp_speed = AXGBE_SFP_SPEED_1000;
585a5c72737SRavi Kumar 		return true;
586a5c72737SRavi Kumar 	}
587a5c72737SRavi Kumar 
588a5c72737SRavi Kumar 	return false;
589a5c72737SRavi Kumar }
590a5c72737SRavi Kumar 
591a5c72737SRavi Kumar static bool axgbe_phy_sfp_parse_quirks(struct axgbe_port *pdata)
592a5c72737SRavi Kumar {
593a5c72737SRavi Kumar 	if (axgbe_phy_belfuse_parse_quirks(pdata))
594a5c72737SRavi Kumar 		return true;
595a5c72737SRavi Kumar 
596a5c72737SRavi Kumar 	return false;
597a5c72737SRavi Kumar }
598a5c72737SRavi Kumar 
599a5c72737SRavi Kumar static void axgbe_phy_sfp_parse_eeprom(struct axgbe_port *pdata)
600a5c72737SRavi Kumar {
601a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
602a5c72737SRavi Kumar 	struct axgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
603a5c72737SRavi Kumar 	uint8_t *sfp_base;
604a5c72737SRavi Kumar 
605a5c72737SRavi Kumar 	sfp_base = sfp_eeprom->base;
606a5c72737SRavi Kumar 
607a5c72737SRavi Kumar 	if (sfp_base[AXGBE_SFP_BASE_ID] != AXGBE_SFP_ID_SFP)
608a5c72737SRavi Kumar 		return;
609a5c72737SRavi Kumar 
610a5c72737SRavi Kumar 	if (sfp_base[AXGBE_SFP_BASE_EXT_ID] != AXGBE_SFP_EXT_ID_SFP)
611a5c72737SRavi Kumar 		return;
612a5c72737SRavi Kumar 
613*936e294cSGirish Nandibasappa 	axgbe_phy_sfp_parse_quirks(pdata);
614a5c72737SRavi Kumar 
615a5c72737SRavi Kumar 	/* Assume ACTIVE cable unless told it is PASSIVE */
616a5c72737SRavi Kumar 	if (sfp_base[AXGBE_SFP_BASE_CABLE] & AXGBE_SFP_BASE_CABLE_PASSIVE) {
617a5c72737SRavi Kumar 		phy_data->sfp_cable = AXGBE_SFP_CABLE_PASSIVE;
618a5c72737SRavi Kumar 		phy_data->sfp_cable_len = sfp_base[AXGBE_SFP_BASE_CU_CABLE_LEN];
619a5c72737SRavi Kumar 	} else {
620a5c72737SRavi Kumar 		phy_data->sfp_cable = AXGBE_SFP_CABLE_ACTIVE;
621a5c72737SRavi Kumar 	}
622a5c72737SRavi Kumar 
623a5c72737SRavi Kumar 	/* Determine the type of SFP */
624a5c72737SRavi Kumar 	if (sfp_base[AXGBE_SFP_BASE_10GBE_CC] & AXGBE_SFP_BASE_10GBE_CC_SR)
625a5c72737SRavi Kumar 		phy_data->sfp_base = AXGBE_SFP_BASE_10000_SR;
626a5c72737SRavi Kumar 	else if (sfp_base[AXGBE_SFP_BASE_10GBE_CC] & AXGBE_SFP_BASE_10GBE_CC_LR)
627a5c72737SRavi Kumar 		phy_data->sfp_base = AXGBE_SFP_BASE_10000_LR;
628a5c72737SRavi Kumar 	else if (sfp_base[AXGBE_SFP_BASE_10GBE_CC] &
629a5c72737SRavi Kumar 		 AXGBE_SFP_BASE_10GBE_CC_LRM)
630a5c72737SRavi Kumar 		phy_data->sfp_base = AXGBE_SFP_BASE_10000_LRM;
631a5c72737SRavi Kumar 	else if (sfp_base[AXGBE_SFP_BASE_10GBE_CC] & AXGBE_SFP_BASE_10GBE_CC_ER)
632a5c72737SRavi Kumar 		phy_data->sfp_base = AXGBE_SFP_BASE_10000_ER;
633a5c72737SRavi Kumar 	else if (sfp_base[AXGBE_SFP_BASE_1GBE_CC] & AXGBE_SFP_BASE_1GBE_CC_SX)
634a5c72737SRavi Kumar 		phy_data->sfp_base = AXGBE_SFP_BASE_1000_SX;
635a5c72737SRavi Kumar 	else if (sfp_base[AXGBE_SFP_BASE_1GBE_CC] & AXGBE_SFP_BASE_1GBE_CC_LX)
636a5c72737SRavi Kumar 		phy_data->sfp_base = AXGBE_SFP_BASE_1000_LX;
637a5c72737SRavi Kumar 	else if (sfp_base[AXGBE_SFP_BASE_1GBE_CC] & AXGBE_SFP_BASE_1GBE_CC_CX)
638a5c72737SRavi Kumar 		phy_data->sfp_base = AXGBE_SFP_BASE_1000_CX;
639a5c72737SRavi Kumar 	else if (sfp_base[AXGBE_SFP_BASE_1GBE_CC] & AXGBE_SFP_BASE_1GBE_CC_T)
640a5c72737SRavi Kumar 		phy_data->sfp_base = AXGBE_SFP_BASE_1000_T;
641a5c72737SRavi Kumar 	else if ((phy_data->sfp_cable == AXGBE_SFP_CABLE_PASSIVE) &&
642a5c72737SRavi Kumar 		 axgbe_phy_sfp_bit_rate(sfp_eeprom, AXGBE_SFP_SPEED_10000))
643a5c72737SRavi Kumar 		phy_data->sfp_base = AXGBE_SFP_BASE_10000_CR;
644a5c72737SRavi Kumar 
645a5c72737SRavi Kumar 	switch (phy_data->sfp_base) {
646a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_T:
647a5c72737SRavi Kumar 		phy_data->sfp_speed = AXGBE_SFP_SPEED_100_1000;
648a5c72737SRavi Kumar 		break;
649a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_SX:
650a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_LX:
651a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_CX:
652a5c72737SRavi Kumar 		phy_data->sfp_speed = AXGBE_SFP_SPEED_1000;
653a5c72737SRavi Kumar 		break;
654a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_10000_SR:
655a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_10000_LR:
656a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_10000_LRM:
657a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_10000_ER:
658a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_10000_CR:
659a5c72737SRavi Kumar 		phy_data->sfp_speed = AXGBE_SFP_SPEED_10000;
660a5c72737SRavi Kumar 		break;
661a5c72737SRavi Kumar 	default:
662a5c72737SRavi Kumar 		break;
663a5c72737SRavi Kumar 	}
664a5c72737SRavi Kumar }
665a5c72737SRavi Kumar 
666a5c72737SRavi Kumar static bool axgbe_phy_sfp_verify_eeprom(uint8_t cc_in, uint8_t *buf,
667a5c72737SRavi Kumar 					unsigned int len)
668a5c72737SRavi Kumar {
669a5c72737SRavi Kumar 	uint8_t cc;
670a5c72737SRavi Kumar 
671a5c72737SRavi Kumar 	for (cc = 0; len; buf++, len--)
672a5c72737SRavi Kumar 		cc += *buf;
673a5c72737SRavi Kumar 
674a5c72737SRavi Kumar 	return (cc == cc_in) ? true : false;
675a5c72737SRavi Kumar }
676a5c72737SRavi Kumar 
677a5c72737SRavi Kumar static int axgbe_phy_sfp_read_eeprom(struct axgbe_port *pdata)
678a5c72737SRavi Kumar {
679a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
680a5c72737SRavi Kumar 	struct axgbe_sfp_eeprom sfp_eeprom;
681a5c72737SRavi Kumar 	uint8_t eeprom_addr;
682a5c72737SRavi Kumar 	int ret;
683a5c72737SRavi Kumar 
684a5c72737SRavi Kumar 	ret = axgbe_phy_sfp_get_mux(pdata);
685a5c72737SRavi Kumar 	if (ret) {
686a5c72737SRavi Kumar 		PMD_DRV_LOG(ERR, "I2C error setting SFP MUX\n");
687a5c72737SRavi Kumar 		return ret;
688a5c72737SRavi Kumar 	}
689a5c72737SRavi Kumar 
690a5c72737SRavi Kumar 	/* Read the SFP serial ID eeprom */
691a5c72737SRavi Kumar 	eeprom_addr = 0;
692a5c72737SRavi Kumar 	ret = axgbe_phy_i2c_read(pdata, AXGBE_SFP_SERIAL_ID_ADDRESS,
693a5c72737SRavi Kumar 				 &eeprom_addr, sizeof(eeprom_addr),
694a5c72737SRavi Kumar 				 &sfp_eeprom, sizeof(sfp_eeprom));
695a5c72737SRavi Kumar 	if (ret) {
696a5c72737SRavi Kumar 		PMD_DRV_LOG(ERR, "I2C error reading SFP EEPROM\n");
697a5c72737SRavi Kumar 		goto put;
698a5c72737SRavi Kumar 	}
699a5c72737SRavi Kumar 
700a5c72737SRavi Kumar 	/* Validate the contents read */
701a5c72737SRavi Kumar 	if (!axgbe_phy_sfp_verify_eeprom(sfp_eeprom.base[AXGBE_SFP_BASE_CC],
702a5c72737SRavi Kumar 					 sfp_eeprom.base,
703a5c72737SRavi Kumar 					 sizeof(sfp_eeprom.base) - 1)) {
704a5c72737SRavi Kumar 		ret = -EINVAL;
705a5c72737SRavi Kumar 		goto put;
706a5c72737SRavi Kumar 	}
707a5c72737SRavi Kumar 
708a5c72737SRavi Kumar 	if (!axgbe_phy_sfp_verify_eeprom(sfp_eeprom.extd[AXGBE_SFP_EXTD_CC],
709a5c72737SRavi Kumar 					 sfp_eeprom.extd,
710a5c72737SRavi Kumar 					 sizeof(sfp_eeprom.extd) - 1)) {
711a5c72737SRavi Kumar 		ret = -EINVAL;
712a5c72737SRavi Kumar 		goto put;
713a5c72737SRavi Kumar 	}
714a5c72737SRavi Kumar 
715a5c72737SRavi Kumar 	/* Check for an added or changed SFP */
716a5c72737SRavi Kumar 	if (memcmp(&phy_data->sfp_eeprom, &sfp_eeprom, sizeof(sfp_eeprom))) {
717a5c72737SRavi Kumar 		phy_data->sfp_changed = 1;
718a5c72737SRavi Kumar 		memcpy(&phy_data->sfp_eeprom, &sfp_eeprom, sizeof(sfp_eeprom));
719a5c72737SRavi Kumar 
720a5c72737SRavi Kumar 		if (sfp_eeprom.extd[AXGBE_SFP_EXTD_SFF_8472]) {
721a5c72737SRavi Kumar 			uint8_t diag_type;
722a5c72737SRavi Kumar 			diag_type = sfp_eeprom.extd[AXGBE_SFP_EXTD_DIAG];
723a5c72737SRavi Kumar 
724a5c72737SRavi Kumar 			if (!(diag_type & AXGBE_SFP_EXTD_DIAG_ADDR_CHANGE))
725a5c72737SRavi Kumar 				phy_data->sfp_diags = 1;
726a5c72737SRavi Kumar 		}
727a5c72737SRavi Kumar 	} else {
728a5c72737SRavi Kumar 		phy_data->sfp_changed = 0;
729a5c72737SRavi Kumar 	}
730a5c72737SRavi Kumar 
731a5c72737SRavi Kumar put:
732a5c72737SRavi Kumar 	axgbe_phy_sfp_put_mux(pdata);
733a5c72737SRavi Kumar 
734a5c72737SRavi Kumar 	return ret;
735a5c72737SRavi Kumar }
736a5c72737SRavi Kumar 
737a5c72737SRavi Kumar static void axgbe_phy_sfp_signals(struct axgbe_port *pdata)
738a5c72737SRavi Kumar {
739a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
740a5c72737SRavi Kumar 	unsigned int gpio_input;
741a5c72737SRavi Kumar 	u8 gpio_reg, gpio_ports[2];
742a5c72737SRavi Kumar 	int ret;
743a5c72737SRavi Kumar 
744a5c72737SRavi Kumar 	/* Read the input port registers */
745a5c72737SRavi Kumar 	gpio_reg = 0;
746a5c72737SRavi Kumar 	ret = axgbe_phy_i2c_read(pdata, phy_data->sfp_gpio_address,
747a5c72737SRavi Kumar 				 &gpio_reg, sizeof(gpio_reg),
748a5c72737SRavi Kumar 				 gpio_ports, sizeof(gpio_ports));
749a5c72737SRavi Kumar 	if (ret) {
750a5c72737SRavi Kumar 		PMD_DRV_LOG(ERR, "I2C error reading SFP GPIOs\n");
751a5c72737SRavi Kumar 		return;
752a5c72737SRavi Kumar 	}
753a5c72737SRavi Kumar 
754a5c72737SRavi Kumar 	gpio_input = (gpio_ports[1] << 8) | gpio_ports[0];
755a5c72737SRavi Kumar 
756a5c72737SRavi Kumar 	if (phy_data->sfp_gpio_mask & AXGBE_GPIO_NO_MOD_ABSENT) {
757a5c72737SRavi Kumar 		/* No GPIO, just assume the module is present for now */
758a5c72737SRavi Kumar 		phy_data->sfp_mod_absent = 0;
759a5c72737SRavi Kumar 	} else {
760a5c72737SRavi Kumar 		if (!(gpio_input & (1 << phy_data->sfp_gpio_mod_absent)))
761a5c72737SRavi Kumar 			phy_data->sfp_mod_absent = 0;
762a5c72737SRavi Kumar 	}
763a5c72737SRavi Kumar 
764a5c72737SRavi Kumar 	if (!(phy_data->sfp_gpio_mask & AXGBE_GPIO_NO_RX_LOS) &&
765a5c72737SRavi Kumar 	    (gpio_input & (1 << phy_data->sfp_gpio_rx_los)))
766a5c72737SRavi Kumar 		phy_data->sfp_rx_los = 1;
767a5c72737SRavi Kumar 
768a5c72737SRavi Kumar 	if (!(phy_data->sfp_gpio_mask & AXGBE_GPIO_NO_TX_FAULT) &&
769a5c72737SRavi Kumar 	    (gpio_input & (1 << phy_data->sfp_gpio_tx_fault)))
770a5c72737SRavi Kumar 		phy_data->sfp_tx_fault = 1;
771a5c72737SRavi Kumar }
772a5c72737SRavi Kumar 
773a5c72737SRavi Kumar static void axgbe_phy_sfp_mod_absent(struct axgbe_port *pdata)
774a5c72737SRavi Kumar {
775a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
776a5c72737SRavi Kumar 
777a5c72737SRavi Kumar 	phy_data->sfp_mod_absent = 1;
778a5c72737SRavi Kumar 	phy_data->sfp_phy_avail = 0;
779a5c72737SRavi Kumar 	memset(&phy_data->sfp_eeprom, 0, sizeof(phy_data->sfp_eeprom));
780a5c72737SRavi Kumar }
781a5c72737SRavi Kumar 
782a5c72737SRavi Kumar static void axgbe_phy_sfp_reset(struct axgbe_phy_data *phy_data)
783a5c72737SRavi Kumar {
784a5c72737SRavi Kumar 	phy_data->sfp_rx_los = 0;
785a5c72737SRavi Kumar 	phy_data->sfp_tx_fault = 0;
786a5c72737SRavi Kumar 	phy_data->sfp_mod_absent = 1;
787a5c72737SRavi Kumar 	phy_data->sfp_diags = 0;
788a5c72737SRavi Kumar 	phy_data->sfp_base = AXGBE_SFP_BASE_UNKNOWN;
789a5c72737SRavi Kumar 	phy_data->sfp_cable = AXGBE_SFP_CABLE_UNKNOWN;
790a5c72737SRavi Kumar 	phy_data->sfp_speed = AXGBE_SFP_SPEED_UNKNOWN;
791a5c72737SRavi Kumar }
792a5c72737SRavi Kumar 
793a5c72737SRavi Kumar static void axgbe_phy_sfp_detect(struct axgbe_port *pdata)
794a5c72737SRavi Kumar {
795a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
796a5c72737SRavi Kumar 	int ret;
797a5c72737SRavi Kumar 
798a5c72737SRavi Kumar 	/* Reset the SFP signals and info */
799a5c72737SRavi Kumar 	axgbe_phy_sfp_reset(phy_data);
800a5c72737SRavi Kumar 
801a5c72737SRavi Kumar 	ret = axgbe_phy_get_comm_ownership(pdata);
802a5c72737SRavi Kumar 	if (ret)
803a5c72737SRavi Kumar 		return;
804a5c72737SRavi Kumar 
805a5c72737SRavi Kumar 	/* Read the SFP signals and check for module presence */
806a5c72737SRavi Kumar 	axgbe_phy_sfp_signals(pdata);
807a5c72737SRavi Kumar 	if (phy_data->sfp_mod_absent) {
808a5c72737SRavi Kumar 		axgbe_phy_sfp_mod_absent(pdata);
809a5c72737SRavi Kumar 		goto put;
810a5c72737SRavi Kumar 	}
811a5c72737SRavi Kumar 
812a5c72737SRavi Kumar 	ret = axgbe_phy_sfp_read_eeprom(pdata);
813a5c72737SRavi Kumar 	if (ret) {
814a5c72737SRavi Kumar 		/* Treat any error as if there isn't an SFP plugged in */
815a5c72737SRavi Kumar 		axgbe_phy_sfp_reset(phy_data);
816a5c72737SRavi Kumar 		axgbe_phy_sfp_mod_absent(pdata);
817a5c72737SRavi Kumar 		goto put;
818a5c72737SRavi Kumar 	}
819a5c72737SRavi Kumar 
820a5c72737SRavi Kumar 	axgbe_phy_sfp_parse_eeprom(pdata);
821a5c72737SRavi Kumar 	axgbe_phy_sfp_external_phy(pdata);
822a5c72737SRavi Kumar 
823a5c72737SRavi Kumar put:
824a5c72737SRavi Kumar 	axgbe_phy_sfp_phy_settings(pdata);
825a5c72737SRavi Kumar 	axgbe_phy_put_comm_ownership(pdata);
826a5c72737SRavi Kumar }
827a5c72737SRavi Kumar 
828a5c72737SRavi Kumar static void axgbe_phy_phydev_flowctrl(struct axgbe_port *pdata)
829a5c72737SRavi Kumar {
830a5c72737SRavi Kumar 	pdata->phy.tx_pause = 0;
831a5c72737SRavi Kumar 	pdata->phy.rx_pause = 0;
832a5c72737SRavi Kumar }
833a5c72737SRavi Kumar 
834a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_an73_redrv_outcome(struct axgbe_port *pdata)
835a5c72737SRavi Kumar {
836a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
837a5c72737SRavi Kumar 	enum axgbe_mode mode;
838a5c72737SRavi Kumar 	unsigned int ad_reg, lp_reg;
839a5c72737SRavi Kumar 
840a5c72737SRavi Kumar 	pdata->phy.lp_advertising |= ADVERTISED_Autoneg;
841a5c72737SRavi Kumar 	pdata->phy.lp_advertising |= ADVERTISED_Backplane;
842a5c72737SRavi Kumar 
843a5c72737SRavi Kumar 	/* Use external PHY to determine flow control */
844a5c72737SRavi Kumar 	if (pdata->phy.pause_autoneg)
845a5c72737SRavi Kumar 		axgbe_phy_phydev_flowctrl(pdata);
846a5c72737SRavi Kumar 
847a5c72737SRavi Kumar 	/* Compare Advertisement and Link Partner register 2 */
848a5c72737SRavi Kumar 	ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
849a5c72737SRavi Kumar 	lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
850a5c72737SRavi Kumar 	if (lp_reg & 0x80)
851a5c72737SRavi Kumar 		pdata->phy.lp_advertising |= ADVERTISED_10000baseKR_Full;
852a5c72737SRavi Kumar 	if (lp_reg & 0x20)
853a5c72737SRavi Kumar 		pdata->phy.lp_advertising |= ADVERTISED_1000baseKX_Full;
854a5c72737SRavi Kumar 
855a5c72737SRavi Kumar 	ad_reg &= lp_reg;
856a5c72737SRavi Kumar 	if (ad_reg & 0x80) {
857a5c72737SRavi Kumar 		switch (phy_data->port_mode) {
858a5c72737SRavi Kumar 		case AXGBE_PORT_MODE_BACKPLANE:
859a5c72737SRavi Kumar 			mode = AXGBE_MODE_KR;
860a5c72737SRavi Kumar 			break;
861a5c72737SRavi Kumar 		default:
862a5c72737SRavi Kumar 			mode = AXGBE_MODE_SFI;
863a5c72737SRavi Kumar 			break;
864a5c72737SRavi Kumar 		}
865a5c72737SRavi Kumar 	} else if (ad_reg & 0x20) {
866a5c72737SRavi Kumar 		switch (phy_data->port_mode) {
867a5c72737SRavi Kumar 		case AXGBE_PORT_MODE_BACKPLANE:
868a5c72737SRavi Kumar 			mode = AXGBE_MODE_KX_1000;
869a5c72737SRavi Kumar 			break;
870a5c72737SRavi Kumar 		case AXGBE_PORT_MODE_1000BASE_X:
871a5c72737SRavi Kumar 			mode = AXGBE_MODE_X;
872a5c72737SRavi Kumar 			break;
873a5c72737SRavi Kumar 		case AXGBE_PORT_MODE_SFP:
874a5c72737SRavi Kumar 			switch (phy_data->sfp_base) {
875a5c72737SRavi Kumar 			case AXGBE_SFP_BASE_1000_T:
876a5c72737SRavi Kumar 				mode = AXGBE_MODE_SGMII_1000;
877a5c72737SRavi Kumar 				break;
878a5c72737SRavi Kumar 			case AXGBE_SFP_BASE_1000_SX:
879a5c72737SRavi Kumar 			case AXGBE_SFP_BASE_1000_LX:
880a5c72737SRavi Kumar 			case AXGBE_SFP_BASE_1000_CX:
881a5c72737SRavi Kumar 			default:
882a5c72737SRavi Kumar 				mode = AXGBE_MODE_X;
883a5c72737SRavi Kumar 				break;
884a5c72737SRavi Kumar 			}
885a5c72737SRavi Kumar 			break;
886a5c72737SRavi Kumar 		default:
887a5c72737SRavi Kumar 			mode = AXGBE_MODE_SGMII_1000;
888a5c72737SRavi Kumar 			break;
889a5c72737SRavi Kumar 		}
890a5c72737SRavi Kumar 	} else {
891a5c72737SRavi Kumar 		mode = AXGBE_MODE_UNKNOWN;
892a5c72737SRavi Kumar 	}
893a5c72737SRavi Kumar 
894a5c72737SRavi Kumar 	/* Compare Advertisement and Link Partner register 3 */
895a5c72737SRavi Kumar 	ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
896a5c72737SRavi Kumar 	lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
897a5c72737SRavi Kumar 	if (lp_reg & 0xc000)
898a5c72737SRavi Kumar 		pdata->phy.lp_advertising |= ADVERTISED_10000baseR_FEC;
899a5c72737SRavi Kumar 
900a5c72737SRavi Kumar 	return mode;
901a5c72737SRavi Kumar }
902a5c72737SRavi Kumar 
903a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_an73_outcome(struct axgbe_port *pdata)
904a5c72737SRavi Kumar {
905a5c72737SRavi Kumar 	enum axgbe_mode mode;
906a5c72737SRavi Kumar 	unsigned int ad_reg, lp_reg;
907a5c72737SRavi Kumar 
908a5c72737SRavi Kumar 	pdata->phy.lp_advertising |= ADVERTISED_Autoneg;
909a5c72737SRavi Kumar 	pdata->phy.lp_advertising |= ADVERTISED_Backplane;
910a5c72737SRavi Kumar 
911a5c72737SRavi Kumar 	/* Compare Advertisement and Link Partner register 1 */
912a5c72737SRavi Kumar 	ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
913a5c72737SRavi Kumar 	lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA);
914a5c72737SRavi Kumar 	if (lp_reg & 0x400)
915a5c72737SRavi Kumar 		pdata->phy.lp_advertising |= ADVERTISED_Pause;
916a5c72737SRavi Kumar 	if (lp_reg & 0x800)
917a5c72737SRavi Kumar 		pdata->phy.lp_advertising |= ADVERTISED_Asym_Pause;
918a5c72737SRavi Kumar 
919a5c72737SRavi Kumar 	if (pdata->phy.pause_autoneg) {
920a5c72737SRavi Kumar 		/* Set flow control based on auto-negotiation result */
921a5c72737SRavi Kumar 		pdata->phy.tx_pause = 0;
922a5c72737SRavi Kumar 		pdata->phy.rx_pause = 0;
923a5c72737SRavi Kumar 
924a5c72737SRavi Kumar 		if (ad_reg & lp_reg & 0x400) {
925a5c72737SRavi Kumar 			pdata->phy.tx_pause = 1;
926a5c72737SRavi Kumar 			pdata->phy.rx_pause = 1;
927a5c72737SRavi Kumar 		} else if (ad_reg & lp_reg & 0x800) {
928a5c72737SRavi Kumar 			if (ad_reg & 0x400)
929a5c72737SRavi Kumar 				pdata->phy.rx_pause = 1;
930a5c72737SRavi Kumar 			else if (lp_reg & 0x400)
931a5c72737SRavi Kumar 				pdata->phy.tx_pause = 1;
932a5c72737SRavi Kumar 		}
933a5c72737SRavi Kumar 	}
934a5c72737SRavi Kumar 
935a5c72737SRavi Kumar 	/* Compare Advertisement and Link Partner register 2 */
936a5c72737SRavi Kumar 	ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
937a5c72737SRavi Kumar 	lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
938a5c72737SRavi Kumar 	if (lp_reg & 0x80)
939a5c72737SRavi Kumar 		pdata->phy.lp_advertising |= ADVERTISED_10000baseKR_Full;
940a5c72737SRavi Kumar 	if (lp_reg & 0x20)
941a5c72737SRavi Kumar 		pdata->phy.lp_advertising |= ADVERTISED_1000baseKX_Full;
942a5c72737SRavi Kumar 
943a5c72737SRavi Kumar 	ad_reg &= lp_reg;
944a5c72737SRavi Kumar 	if (ad_reg & 0x80)
945a5c72737SRavi Kumar 		mode = AXGBE_MODE_KR;
946a5c72737SRavi Kumar 	else if (ad_reg & 0x20)
947a5c72737SRavi Kumar 		mode = AXGBE_MODE_KX_1000;
948a5c72737SRavi Kumar 	else
949a5c72737SRavi Kumar 		mode = AXGBE_MODE_UNKNOWN;
950a5c72737SRavi Kumar 
951a5c72737SRavi Kumar 	/* Compare Advertisement and Link Partner register 3 */
952a5c72737SRavi Kumar 	ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
953a5c72737SRavi Kumar 	lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
954a5c72737SRavi Kumar 	if (lp_reg & 0xc000)
955a5c72737SRavi Kumar 		pdata->phy.lp_advertising |= ADVERTISED_10000baseR_FEC;
956a5c72737SRavi Kumar 
957a5c72737SRavi Kumar 	return mode;
958a5c72737SRavi Kumar }
959a5c72737SRavi Kumar 
960a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_an_outcome(struct axgbe_port *pdata)
961a5c72737SRavi Kumar {
962a5c72737SRavi Kumar 	switch (pdata->an_mode) {
963a5c72737SRavi Kumar 	case AXGBE_AN_MODE_CL73:
964a5c72737SRavi Kumar 		return axgbe_phy_an73_outcome(pdata);
965a5c72737SRavi Kumar 	case AXGBE_AN_MODE_CL73_REDRV:
966a5c72737SRavi Kumar 		return axgbe_phy_an73_redrv_outcome(pdata);
967a5c72737SRavi Kumar 	case AXGBE_AN_MODE_CL37:
968a5c72737SRavi Kumar 	case AXGBE_AN_MODE_CL37_SGMII:
969a5c72737SRavi Kumar 	default:
970a5c72737SRavi Kumar 		return AXGBE_MODE_UNKNOWN;
971a5c72737SRavi Kumar 	}
972a5c72737SRavi Kumar }
973a5c72737SRavi Kumar 
974a5c72737SRavi Kumar static unsigned int axgbe_phy_an_advertising(struct axgbe_port *pdata)
975a5c72737SRavi Kumar {
976a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
977a5c72737SRavi Kumar 	unsigned int advertising;
978a5c72737SRavi Kumar 
979a5c72737SRavi Kumar 	/* Without a re-driver, just return current advertising */
980a5c72737SRavi Kumar 	if (!phy_data->redrv)
981a5c72737SRavi Kumar 		return pdata->phy.advertising;
982a5c72737SRavi Kumar 
983a5c72737SRavi Kumar 	/* With the KR re-driver we need to advertise a single speed */
984a5c72737SRavi Kumar 	advertising = pdata->phy.advertising;
985a5c72737SRavi Kumar 	advertising &= ~ADVERTISED_1000baseKX_Full;
986a5c72737SRavi Kumar 	advertising &= ~ADVERTISED_10000baseKR_Full;
987a5c72737SRavi Kumar 
988a5c72737SRavi Kumar 	switch (phy_data->port_mode) {
989a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE:
990a5c72737SRavi Kumar 		advertising |= ADVERTISED_10000baseKR_Full;
991a5c72737SRavi Kumar 		break;
992a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE_2500:
993a5c72737SRavi Kumar 		advertising |= ADVERTISED_1000baseKX_Full;
994a5c72737SRavi Kumar 		break;
995a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_T:
996a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_X:
997a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_NBASE_T:
998a5c72737SRavi Kumar 		advertising |= ADVERTISED_1000baseKX_Full;
999a5c72737SRavi Kumar 		break;
1000a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_T:
1001a5c72737SRavi Kumar 		PMD_DRV_LOG(ERR, "10GBASE_T mode is not supported\n");
1002a5c72737SRavi Kumar 		break;
1003a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_R:
1004a5c72737SRavi Kumar 		advertising |= ADVERTISED_10000baseKR_Full;
1005a5c72737SRavi Kumar 		break;
1006a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_SFP:
1007a5c72737SRavi Kumar 		switch (phy_data->sfp_base) {
1008a5c72737SRavi Kumar 		case AXGBE_SFP_BASE_1000_T:
1009a5c72737SRavi Kumar 		case AXGBE_SFP_BASE_1000_SX:
1010a5c72737SRavi Kumar 		case AXGBE_SFP_BASE_1000_LX:
1011a5c72737SRavi Kumar 		case AXGBE_SFP_BASE_1000_CX:
1012a5c72737SRavi Kumar 			advertising |= ADVERTISED_1000baseKX_Full;
1013a5c72737SRavi Kumar 			break;
1014a5c72737SRavi Kumar 		default:
1015a5c72737SRavi Kumar 			advertising |= ADVERTISED_10000baseKR_Full;
1016a5c72737SRavi Kumar 			break;
1017a5c72737SRavi Kumar 		}
1018a5c72737SRavi Kumar 		break;
1019a5c72737SRavi Kumar 	default:
1020a5c72737SRavi Kumar 		advertising |= ADVERTISED_10000baseKR_Full;
1021a5c72737SRavi Kumar 		break;
1022a5c72737SRavi Kumar 	}
1023a5c72737SRavi Kumar 
1024a5c72737SRavi Kumar 	return advertising;
1025a5c72737SRavi Kumar }
1026a5c72737SRavi Kumar 
1027a5c72737SRavi Kumar static int axgbe_phy_an_config(struct axgbe_port *pdata __rte_unused)
1028a5c72737SRavi Kumar {
1029a5c72737SRavi Kumar 	return 0;
1030a5c72737SRavi Kumar 	/* Dummy API since there is no case to support
1031a5c72737SRavi Kumar 	 * external phy devices registred through kerenl apis
1032a5c72737SRavi Kumar 	 */
1033a5c72737SRavi Kumar }
1034a5c72737SRavi Kumar 
1035a5c72737SRavi Kumar static enum axgbe_an_mode axgbe_phy_an_sfp_mode(struct axgbe_phy_data *phy_data)
1036a5c72737SRavi Kumar {
1037a5c72737SRavi Kumar 	switch (phy_data->sfp_base) {
1038a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_T:
1039a5c72737SRavi Kumar 		return AXGBE_AN_MODE_CL37_SGMII;
1040a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_SX:
1041a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_LX:
1042a5c72737SRavi Kumar 	case AXGBE_SFP_BASE_1000_CX:
1043a5c72737SRavi Kumar 		return AXGBE_AN_MODE_CL37;
1044a5c72737SRavi Kumar 	default:
1045a5c72737SRavi Kumar 		return AXGBE_AN_MODE_NONE;
1046a5c72737SRavi Kumar 	}
1047a5c72737SRavi Kumar }
1048a5c72737SRavi Kumar 
1049a5c72737SRavi Kumar static enum axgbe_an_mode axgbe_phy_an_mode(struct axgbe_port *pdata)
1050a5c72737SRavi Kumar {
1051a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1052a5c72737SRavi Kumar 
1053a5c72737SRavi Kumar 	/* A KR re-driver will always require CL73 AN */
1054a5c72737SRavi Kumar 	if (phy_data->redrv)
1055a5c72737SRavi Kumar 		return AXGBE_AN_MODE_CL73_REDRV;
1056a5c72737SRavi Kumar 
1057a5c72737SRavi Kumar 	switch (phy_data->port_mode) {
1058a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE:
1059a5c72737SRavi Kumar 		return AXGBE_AN_MODE_CL73;
1060a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE_2500:
1061a5c72737SRavi Kumar 		return AXGBE_AN_MODE_NONE;
1062a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_T:
1063a5c72737SRavi Kumar 		return AXGBE_AN_MODE_CL37_SGMII;
1064a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_X:
1065a5c72737SRavi Kumar 		return AXGBE_AN_MODE_CL37;
1066a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_NBASE_T:
1067a5c72737SRavi Kumar 		return AXGBE_AN_MODE_CL37_SGMII;
1068a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_T:
1069a5c72737SRavi Kumar 		return AXGBE_AN_MODE_CL73;
1070a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_R:
1071a5c72737SRavi Kumar 		return AXGBE_AN_MODE_NONE;
1072a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_SFP:
1073a5c72737SRavi Kumar 		return axgbe_phy_an_sfp_mode(phy_data);
1074a5c72737SRavi Kumar 	default:
1075a5c72737SRavi Kumar 		return AXGBE_AN_MODE_NONE;
1076a5c72737SRavi Kumar 	}
1077a5c72737SRavi Kumar }
1078a5c72737SRavi Kumar 
1079a5c72737SRavi Kumar static int axgbe_phy_set_redrv_mode_mdio(struct axgbe_port *pdata,
1080a5c72737SRavi Kumar 					 enum axgbe_phy_redrv_mode mode)
1081a5c72737SRavi Kumar {
1082a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1083a5c72737SRavi Kumar 	u16 redrv_reg, redrv_val;
1084a5c72737SRavi Kumar 
1085a5c72737SRavi Kumar 	redrv_reg = AXGBE_PHY_REDRV_MODE_REG + (phy_data->redrv_lane * 0x1000);
1086a5c72737SRavi Kumar 	redrv_val = (u16)mode;
1087a5c72737SRavi Kumar 
1088a5c72737SRavi Kumar 	return pdata->hw_if.write_ext_mii_regs(pdata, phy_data->redrv_addr,
1089a5c72737SRavi Kumar 					       redrv_reg, redrv_val);
1090a5c72737SRavi Kumar }
1091a5c72737SRavi Kumar 
1092a5c72737SRavi Kumar static int axgbe_phy_set_redrv_mode_i2c(struct axgbe_port *pdata,
1093a5c72737SRavi Kumar 					enum axgbe_phy_redrv_mode mode)
1094a5c72737SRavi Kumar {
1095a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1096a5c72737SRavi Kumar 	unsigned int redrv_reg;
1097a5c72737SRavi Kumar 	int ret;
1098a5c72737SRavi Kumar 
1099a5c72737SRavi Kumar 	/* Calculate the register to write */
1100a5c72737SRavi Kumar 	redrv_reg = AXGBE_PHY_REDRV_MODE_REG + (phy_data->redrv_lane * 0x1000);
1101a5c72737SRavi Kumar 
1102a5c72737SRavi Kumar 	ret = axgbe_phy_redrv_write(pdata, redrv_reg, mode);
1103a5c72737SRavi Kumar 
1104a5c72737SRavi Kumar 	return ret;
1105a5c72737SRavi Kumar }
1106a5c72737SRavi Kumar 
1107a5c72737SRavi Kumar static void axgbe_phy_set_redrv_mode(struct axgbe_port *pdata)
1108a5c72737SRavi Kumar {
1109a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1110a5c72737SRavi Kumar 	enum axgbe_phy_redrv_mode mode;
1111a5c72737SRavi Kumar 	int ret;
1112a5c72737SRavi Kumar 
1113a5c72737SRavi Kumar 	if (!phy_data->redrv)
1114a5c72737SRavi Kumar 		return;
1115a5c72737SRavi Kumar 
1116a5c72737SRavi Kumar 	mode = AXGBE_PHY_REDRV_MODE_CX;
1117a5c72737SRavi Kumar 	if ((phy_data->port_mode == AXGBE_PORT_MODE_SFP) &&
1118a5c72737SRavi Kumar 	    (phy_data->sfp_base != AXGBE_SFP_BASE_1000_CX) &&
1119a5c72737SRavi Kumar 	    (phy_data->sfp_base != AXGBE_SFP_BASE_10000_CR))
1120a5c72737SRavi Kumar 		mode = AXGBE_PHY_REDRV_MODE_SR;
1121a5c72737SRavi Kumar 
1122a5c72737SRavi Kumar 	ret = axgbe_phy_get_comm_ownership(pdata);
1123a5c72737SRavi Kumar 	if (ret)
1124a5c72737SRavi Kumar 		return;
1125a5c72737SRavi Kumar 
1126a5c72737SRavi Kumar 	if (phy_data->redrv_if)
1127a5c72737SRavi Kumar 		axgbe_phy_set_redrv_mode_i2c(pdata, mode);
1128a5c72737SRavi Kumar 	else
1129a5c72737SRavi Kumar 		axgbe_phy_set_redrv_mode_mdio(pdata, mode);
1130a5c72737SRavi Kumar 
1131a5c72737SRavi Kumar 	axgbe_phy_put_comm_ownership(pdata);
1132a5c72737SRavi Kumar }
1133a5c72737SRavi Kumar 
1134a5c72737SRavi Kumar static void axgbe_phy_start_ratechange(struct axgbe_port *pdata)
1135a5c72737SRavi Kumar {
1136a5c72737SRavi Kumar 	if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS))
1137a5c72737SRavi Kumar 		return;
1138a5c72737SRavi Kumar }
1139a5c72737SRavi Kumar 
1140a5c72737SRavi Kumar static void axgbe_phy_complete_ratechange(struct axgbe_port *pdata)
1141a5c72737SRavi Kumar {
1142a5c72737SRavi Kumar 	unsigned int wait;
1143a5c72737SRavi Kumar 
1144a5c72737SRavi Kumar 	/* Wait for command to complete */
1145a5c72737SRavi Kumar 	wait = AXGBE_RATECHANGE_COUNT;
1146a5c72737SRavi Kumar 	while (wait--) {
1147a5c72737SRavi Kumar 		if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS))
1148a5c72737SRavi Kumar 			return;
1149a5c72737SRavi Kumar 
1150a5c72737SRavi Kumar 		rte_delay_us(1500);
1151a5c72737SRavi Kumar 	}
1152a5c72737SRavi Kumar }
1153a5c72737SRavi Kumar 
1154a5c72737SRavi Kumar static void axgbe_phy_rrc(struct axgbe_port *pdata)
1155a5c72737SRavi Kumar {
1156a5c72737SRavi Kumar 	unsigned int s0;
1157a5c72737SRavi Kumar 
1158a5c72737SRavi Kumar 	axgbe_phy_start_ratechange(pdata);
1159a5c72737SRavi Kumar 
1160a5c72737SRavi Kumar 	/* Receiver Reset Cycle */
1161a5c72737SRavi Kumar 	s0 = 0;
1162a5c72737SRavi Kumar 	XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 5);
1163a5c72737SRavi Kumar 	XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 0);
1164a5c72737SRavi Kumar 
1165a5c72737SRavi Kumar 	/* Call FW to make the change */
1166a5c72737SRavi Kumar 	XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1167a5c72737SRavi Kumar 	XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1168a5c72737SRavi Kumar 	XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1169a5c72737SRavi Kumar 
1170a5c72737SRavi Kumar 	axgbe_phy_complete_ratechange(pdata);
1171a5c72737SRavi Kumar }
1172a5c72737SRavi Kumar 
1173a5c72737SRavi Kumar static void axgbe_phy_power_off(struct axgbe_port *pdata)
1174a5c72737SRavi Kumar {
1175a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1176a5c72737SRavi Kumar 
1177a5c72737SRavi Kumar 	axgbe_phy_start_ratechange(pdata);
1178a5c72737SRavi Kumar 
1179a5c72737SRavi Kumar 	/* Call FW to make the change */
1180a5c72737SRavi Kumar 	XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, 0);
1181a5c72737SRavi Kumar 	XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1182a5c72737SRavi Kumar 	XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1183a5c72737SRavi Kumar 	axgbe_phy_complete_ratechange(pdata);
1184a5c72737SRavi Kumar 	phy_data->cur_mode = AXGBE_MODE_UNKNOWN;
1185a5c72737SRavi Kumar }
1186a5c72737SRavi Kumar 
1187a5c72737SRavi Kumar static void axgbe_phy_sfi_mode(struct axgbe_port *pdata)
1188a5c72737SRavi Kumar {
1189a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1190a5c72737SRavi Kumar 	unsigned int s0;
1191a5c72737SRavi Kumar 
1192a5c72737SRavi Kumar 	axgbe_phy_set_redrv_mode(pdata);
1193a5c72737SRavi Kumar 
1194a5c72737SRavi Kumar 	axgbe_phy_start_ratechange(pdata);
1195a5c72737SRavi Kumar 
1196a5c72737SRavi Kumar 	/* 10G/SFI */
1197a5c72737SRavi Kumar 	s0 = 0;
1198a5c72737SRavi Kumar 	XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 3);
1199a5c72737SRavi Kumar 	if (phy_data->sfp_cable != AXGBE_SFP_CABLE_PASSIVE) {
1200a5c72737SRavi Kumar 		XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 0);
1201a5c72737SRavi Kumar 	} else {
1202a5c72737SRavi Kumar 		if (phy_data->sfp_cable_len <= 1)
1203a5c72737SRavi Kumar 			XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 1);
1204a5c72737SRavi Kumar 		else if (phy_data->sfp_cable_len <= 3)
1205a5c72737SRavi Kumar 			XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 2);
1206a5c72737SRavi Kumar 		else
1207a5c72737SRavi Kumar 			XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 3);
1208a5c72737SRavi Kumar 	}
1209a5c72737SRavi Kumar 
1210a5c72737SRavi Kumar 	/* Call FW to make the change */
1211a5c72737SRavi Kumar 	XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1212a5c72737SRavi Kumar 	XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1213a5c72737SRavi Kumar 	XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1214a5c72737SRavi Kumar 	axgbe_phy_complete_ratechange(pdata);
1215a5c72737SRavi Kumar 	phy_data->cur_mode = AXGBE_MODE_SFI;
1216a5c72737SRavi Kumar }
1217a5c72737SRavi Kumar 
1218a5c72737SRavi Kumar static void axgbe_phy_kr_mode(struct axgbe_port *pdata)
1219a5c72737SRavi Kumar {
1220a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1221a5c72737SRavi Kumar 	unsigned int s0;
1222a5c72737SRavi Kumar 
1223a5c72737SRavi Kumar 	axgbe_phy_set_redrv_mode(pdata);
1224a5c72737SRavi Kumar 
1225a5c72737SRavi Kumar 	axgbe_phy_start_ratechange(pdata);
1226a5c72737SRavi Kumar 
1227a5c72737SRavi Kumar 	/* 10G/KR */
1228a5c72737SRavi Kumar 	s0 = 0;
1229a5c72737SRavi Kumar 	XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 4);
1230a5c72737SRavi Kumar 	XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 0);
1231a5c72737SRavi Kumar 
1232a5c72737SRavi Kumar 	/* Call FW to make the change */
1233a5c72737SRavi Kumar 	XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1234a5c72737SRavi Kumar 	XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1235a5c72737SRavi Kumar 	XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1236a5c72737SRavi Kumar 	axgbe_phy_complete_ratechange(pdata);
1237a5c72737SRavi Kumar 	phy_data->cur_mode = AXGBE_MODE_KR;
1238a5c72737SRavi Kumar }
1239a5c72737SRavi Kumar 
1240*936e294cSGirish Nandibasappa static void axgbe_phy_kx_2500_mode(struct axgbe_port *pdata)
1241*936e294cSGirish Nandibasappa {
1242*936e294cSGirish Nandibasappa 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1243*936e294cSGirish Nandibasappa 	unsigned int s0;
1244*936e294cSGirish Nandibasappa 
1245*936e294cSGirish Nandibasappa 	axgbe_phy_set_redrv_mode(pdata);
1246*936e294cSGirish Nandibasappa 	/* 2.5G/KX */
1247*936e294cSGirish Nandibasappa 	axgbe_phy_start_ratechange(pdata);
1248*936e294cSGirish Nandibasappa 	s0 = 0;
1249*936e294cSGirish Nandibasappa 	XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 2);
1250*936e294cSGirish Nandibasappa 	XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 0);
1251*936e294cSGirish Nandibasappa 
1252*936e294cSGirish Nandibasappa 	XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1253*936e294cSGirish Nandibasappa 	XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1254*936e294cSGirish Nandibasappa 
1255*936e294cSGirish Nandibasappa 	XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1256*936e294cSGirish Nandibasappa 
1257*936e294cSGirish Nandibasappa 	phy_data->cur_mode = AXGBE_MODE_KX_2500;
1258*936e294cSGirish Nandibasappa }
1259*936e294cSGirish Nandibasappa 
1260*936e294cSGirish Nandibasappa static void axgbe_phy_sgmii_1000_mode(struct axgbe_port *pdata)
1261*936e294cSGirish Nandibasappa {
1262*936e294cSGirish Nandibasappa 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1263*936e294cSGirish Nandibasappa 	unsigned int s0;
1264*936e294cSGirish Nandibasappa 
1265*936e294cSGirish Nandibasappa 	axgbe_phy_set_redrv_mode(pdata);
1266*936e294cSGirish Nandibasappa 
1267*936e294cSGirish Nandibasappa 	/* 1G/SGMII */
1268*936e294cSGirish Nandibasappa 	axgbe_phy_start_ratechange(pdata);
1269*936e294cSGirish Nandibasappa 	s0 = 0;
1270*936e294cSGirish Nandibasappa 	XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 1);
1271*936e294cSGirish Nandibasappa 	XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 2);
1272*936e294cSGirish Nandibasappa 
1273*936e294cSGirish Nandibasappa 	XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1274*936e294cSGirish Nandibasappa 	XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1275*936e294cSGirish Nandibasappa 
1276*936e294cSGirish Nandibasappa 	XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1277*936e294cSGirish Nandibasappa 
1278*936e294cSGirish Nandibasappa 	phy_data->cur_mode = AXGBE_MODE_SGMII_1000;
1279*936e294cSGirish Nandibasappa }
1280*936e294cSGirish Nandibasappa 
1281a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_cur_mode(struct axgbe_port *pdata)
1282a5c72737SRavi Kumar {
1283a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1284a5c72737SRavi Kumar 
1285a5c72737SRavi Kumar 	return phy_data->cur_mode;
1286a5c72737SRavi Kumar }
1287a5c72737SRavi Kumar 
1288a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_switch_baset_mode(struct axgbe_port *pdata)
1289a5c72737SRavi Kumar {
1290a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1291a5c72737SRavi Kumar 
1292a5c72737SRavi Kumar 	/* No switching if not 10GBase-T */
1293a5c72737SRavi Kumar 	if (phy_data->port_mode != AXGBE_PORT_MODE_10GBASE_T)
1294a5c72737SRavi Kumar 		return axgbe_phy_cur_mode(pdata);
1295a5c72737SRavi Kumar 
1296a5c72737SRavi Kumar 	switch (axgbe_phy_cur_mode(pdata)) {
1297a5c72737SRavi Kumar 	case AXGBE_MODE_SGMII_100:
1298a5c72737SRavi Kumar 	case AXGBE_MODE_SGMII_1000:
1299a5c72737SRavi Kumar 		return AXGBE_MODE_KR;
1300a5c72737SRavi Kumar 	case AXGBE_MODE_KR:
1301a5c72737SRavi Kumar 	default:
1302a5c72737SRavi Kumar 		return AXGBE_MODE_SGMII_1000;
1303a5c72737SRavi Kumar 	}
1304a5c72737SRavi Kumar }
1305a5c72737SRavi Kumar 
1306a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_switch_bp_2500_mode(struct axgbe_port *pdata
1307a5c72737SRavi Kumar 						     __rte_unused)
1308a5c72737SRavi Kumar {
1309a5c72737SRavi Kumar 	return AXGBE_MODE_KX_2500;
1310a5c72737SRavi Kumar }
1311a5c72737SRavi Kumar 
1312a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_switch_bp_mode(struct axgbe_port *pdata)
1313a5c72737SRavi Kumar {
1314a5c72737SRavi Kumar 	/* If we are in KR switch to KX, and vice-versa */
1315a5c72737SRavi Kumar 	switch (axgbe_phy_cur_mode(pdata)) {
1316a5c72737SRavi Kumar 	case AXGBE_MODE_KX_1000:
1317a5c72737SRavi Kumar 		return AXGBE_MODE_KR;
1318a5c72737SRavi Kumar 	case AXGBE_MODE_KR:
1319a5c72737SRavi Kumar 	default:
1320a5c72737SRavi Kumar 		return AXGBE_MODE_KX_1000;
1321a5c72737SRavi Kumar 	}
1322a5c72737SRavi Kumar }
1323a5c72737SRavi Kumar 
1324a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_switch_mode(struct axgbe_port *pdata)
1325a5c72737SRavi Kumar {
1326a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1327a5c72737SRavi Kumar 
1328a5c72737SRavi Kumar 	switch (phy_data->port_mode) {
1329a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE:
1330a5c72737SRavi Kumar 		return axgbe_phy_switch_bp_mode(pdata);
1331a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE_2500:
1332a5c72737SRavi Kumar 		return axgbe_phy_switch_bp_2500_mode(pdata);
1333a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_T:
1334a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_NBASE_T:
1335a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_T:
1336a5c72737SRavi Kumar 		return axgbe_phy_switch_baset_mode(pdata);
1337a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_X:
1338a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_R:
1339a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_SFP:
1340a5c72737SRavi Kumar 		/* No switching, so just return current mode */
1341a5c72737SRavi Kumar 		return axgbe_phy_cur_mode(pdata);
1342a5c72737SRavi Kumar 	default:
1343a5c72737SRavi Kumar 		return AXGBE_MODE_UNKNOWN;
1344a5c72737SRavi Kumar 	}
1345a5c72737SRavi Kumar }
1346a5c72737SRavi Kumar 
1347a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_get_basex_mode(struct axgbe_phy_data *phy_data
1348a5c72737SRavi Kumar 						__rte_unused,
1349a5c72737SRavi Kumar 						int speed)
1350a5c72737SRavi Kumar {
1351a5c72737SRavi Kumar 	switch (speed) {
1352a5c72737SRavi Kumar 	case SPEED_1000:
1353a5c72737SRavi Kumar 		return AXGBE_MODE_X;
1354a5c72737SRavi Kumar 	case SPEED_10000:
1355a5c72737SRavi Kumar 		return AXGBE_MODE_KR;
1356a5c72737SRavi Kumar 	default:
1357a5c72737SRavi Kumar 		return AXGBE_MODE_UNKNOWN;
1358a5c72737SRavi Kumar 	}
1359a5c72737SRavi Kumar }
1360a5c72737SRavi Kumar 
1361a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_get_baset_mode(struct axgbe_phy_data *phy_data
1362a5c72737SRavi Kumar 						__rte_unused,
1363a5c72737SRavi Kumar 						int speed)
1364a5c72737SRavi Kumar {
1365a5c72737SRavi Kumar 	switch (speed) {
1366a5c72737SRavi Kumar 	case SPEED_100:
1367a5c72737SRavi Kumar 		return AXGBE_MODE_SGMII_100;
1368a5c72737SRavi Kumar 	case SPEED_1000:
1369a5c72737SRavi Kumar 		return AXGBE_MODE_SGMII_1000;
1370a5c72737SRavi Kumar 	case SPEED_10000:
1371a5c72737SRavi Kumar 		return AXGBE_MODE_KR;
1372a5c72737SRavi Kumar 	default:
1373a5c72737SRavi Kumar 		return AXGBE_MODE_UNKNOWN;
1374a5c72737SRavi Kumar 	}
1375a5c72737SRavi Kumar }
1376a5c72737SRavi Kumar 
1377a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_get_sfp_mode(struct axgbe_phy_data *phy_data,
1378a5c72737SRavi Kumar 					      int speed)
1379a5c72737SRavi Kumar {
1380a5c72737SRavi Kumar 	switch (speed) {
1381a5c72737SRavi Kumar 	case SPEED_100:
1382a5c72737SRavi Kumar 		return AXGBE_MODE_SGMII_100;
1383a5c72737SRavi Kumar 	case SPEED_1000:
1384a5c72737SRavi Kumar 		if (phy_data->sfp_base == AXGBE_SFP_BASE_1000_T)
1385a5c72737SRavi Kumar 			return AXGBE_MODE_SGMII_1000;
1386a5c72737SRavi Kumar 		else
1387a5c72737SRavi Kumar 			return AXGBE_MODE_X;
1388a5c72737SRavi Kumar 	case SPEED_10000:
1389a5c72737SRavi Kumar 	case SPEED_UNKNOWN:
1390a5c72737SRavi Kumar 		return AXGBE_MODE_SFI;
1391a5c72737SRavi Kumar 	default:
1392a5c72737SRavi Kumar 		return AXGBE_MODE_UNKNOWN;
1393a5c72737SRavi Kumar 	}
1394a5c72737SRavi Kumar }
1395a5c72737SRavi Kumar 
1396a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_get_bp_2500_mode(int speed)
1397a5c72737SRavi Kumar {
1398a5c72737SRavi Kumar 	switch (speed) {
1399a5c72737SRavi Kumar 	case SPEED_2500:
1400a5c72737SRavi Kumar 		return AXGBE_MODE_KX_2500;
1401a5c72737SRavi Kumar 	default:
1402a5c72737SRavi Kumar 		return AXGBE_MODE_UNKNOWN;
1403a5c72737SRavi Kumar 	}
1404a5c72737SRavi Kumar }
1405a5c72737SRavi Kumar 
1406a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_get_bp_mode(int speed)
1407a5c72737SRavi Kumar {
1408a5c72737SRavi Kumar 	switch (speed) {
1409a5c72737SRavi Kumar 	case SPEED_1000:
1410a5c72737SRavi Kumar 		return AXGBE_MODE_KX_1000;
1411a5c72737SRavi Kumar 	case SPEED_10000:
1412a5c72737SRavi Kumar 		return AXGBE_MODE_KR;
1413a5c72737SRavi Kumar 	default:
1414a5c72737SRavi Kumar 		return AXGBE_MODE_UNKNOWN;
1415a5c72737SRavi Kumar 	}
1416a5c72737SRavi Kumar }
1417a5c72737SRavi Kumar 
1418a5c72737SRavi Kumar static enum axgbe_mode axgbe_phy_get_mode(struct axgbe_port *pdata,
1419a5c72737SRavi Kumar 					  int speed)
1420a5c72737SRavi Kumar {
1421a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1422a5c72737SRavi Kumar 
1423a5c72737SRavi Kumar 	switch (phy_data->port_mode) {
1424a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE:
1425a5c72737SRavi Kumar 		return axgbe_phy_get_bp_mode(speed);
1426a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE_2500:
1427a5c72737SRavi Kumar 		return axgbe_phy_get_bp_2500_mode(speed);
1428a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_T:
1429a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_NBASE_T:
1430a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_T:
1431a5c72737SRavi Kumar 		return axgbe_phy_get_baset_mode(phy_data, speed);
1432a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_X:
1433a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_R:
1434a5c72737SRavi Kumar 		return axgbe_phy_get_basex_mode(phy_data, speed);
1435a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_SFP:
1436a5c72737SRavi Kumar 		return axgbe_phy_get_sfp_mode(phy_data, speed);
1437a5c72737SRavi Kumar 	default:
1438a5c72737SRavi Kumar 		return AXGBE_MODE_UNKNOWN;
1439a5c72737SRavi Kumar 	}
1440a5c72737SRavi Kumar }
1441a5c72737SRavi Kumar 
1442a5c72737SRavi Kumar static void axgbe_phy_set_mode(struct axgbe_port *pdata, enum axgbe_mode mode)
1443a5c72737SRavi Kumar {
1444a5c72737SRavi Kumar 	switch (mode) {
1445a5c72737SRavi Kumar 	case AXGBE_MODE_KR:
1446a5c72737SRavi Kumar 		axgbe_phy_kr_mode(pdata);
1447a5c72737SRavi Kumar 		break;
1448a5c72737SRavi Kumar 	case AXGBE_MODE_SFI:
1449a5c72737SRavi Kumar 		axgbe_phy_sfi_mode(pdata);
1450a5c72737SRavi Kumar 		break;
1451*936e294cSGirish Nandibasappa 	case AXGBE_MODE_KX_2500:
1452*936e294cSGirish Nandibasappa 		axgbe_phy_kx_2500_mode(pdata);
1453*936e294cSGirish Nandibasappa 		break;
1454*936e294cSGirish Nandibasappa 	case AXGBE_MODE_SGMII_1000:
1455*936e294cSGirish Nandibasappa 		axgbe_phy_sgmii_1000_mode(pdata);
1456*936e294cSGirish Nandibasappa 		break;
1457a5c72737SRavi Kumar 	default:
1458a5c72737SRavi Kumar 		break;
1459a5c72737SRavi Kumar 	}
1460a5c72737SRavi Kumar }
1461a5c72737SRavi Kumar 
1462a5c72737SRavi Kumar static bool axgbe_phy_check_mode(struct axgbe_port *pdata,
1463a5c72737SRavi Kumar 				 enum axgbe_mode mode, u32 advert)
1464a5c72737SRavi Kumar {
1465a5c72737SRavi Kumar 	if (pdata->phy.autoneg == AUTONEG_ENABLE) {
1466a5c72737SRavi Kumar 		if (pdata->phy.advertising & advert)
1467a5c72737SRavi Kumar 			return true;
1468a5c72737SRavi Kumar 	} else {
1469a5c72737SRavi Kumar 		enum axgbe_mode cur_mode;
1470a5c72737SRavi Kumar 
1471a5c72737SRavi Kumar 		cur_mode = axgbe_phy_get_mode(pdata, pdata->phy.speed);
1472a5c72737SRavi Kumar 		if (cur_mode == mode)
1473a5c72737SRavi Kumar 			return true;
1474a5c72737SRavi Kumar 	}
1475a5c72737SRavi Kumar 
1476a5c72737SRavi Kumar 	return false;
1477a5c72737SRavi Kumar }
1478a5c72737SRavi Kumar 
1479a5c72737SRavi Kumar static bool axgbe_phy_use_basex_mode(struct axgbe_port *pdata,
1480a5c72737SRavi Kumar 				     enum axgbe_mode mode)
1481a5c72737SRavi Kumar {
1482a5c72737SRavi Kumar 	switch (mode) {
1483a5c72737SRavi Kumar 	case AXGBE_MODE_X:
1484a5c72737SRavi Kumar 		return axgbe_phy_check_mode(pdata, mode,
1485a5c72737SRavi Kumar 					    ADVERTISED_1000baseT_Full);
1486a5c72737SRavi Kumar 	case AXGBE_MODE_KR:
1487a5c72737SRavi Kumar 		return axgbe_phy_check_mode(pdata, mode,
1488a5c72737SRavi Kumar 					    ADVERTISED_10000baseT_Full);
1489a5c72737SRavi Kumar 	default:
1490a5c72737SRavi Kumar 		return false;
1491a5c72737SRavi Kumar 	}
1492a5c72737SRavi Kumar }
1493a5c72737SRavi Kumar 
1494a5c72737SRavi Kumar static bool axgbe_phy_use_baset_mode(struct axgbe_port *pdata,
1495a5c72737SRavi Kumar 				     enum axgbe_mode mode)
1496a5c72737SRavi Kumar {
1497a5c72737SRavi Kumar 	switch (mode) {
1498a5c72737SRavi Kumar 	case AXGBE_MODE_SGMII_100:
1499a5c72737SRavi Kumar 		return axgbe_phy_check_mode(pdata, mode,
1500a5c72737SRavi Kumar 					    ADVERTISED_100baseT_Full);
1501a5c72737SRavi Kumar 	case AXGBE_MODE_SGMII_1000:
1502a5c72737SRavi Kumar 		return axgbe_phy_check_mode(pdata, mode,
1503a5c72737SRavi Kumar 					    ADVERTISED_1000baseT_Full);
1504a5c72737SRavi Kumar 	case AXGBE_MODE_KR:
1505a5c72737SRavi Kumar 		return axgbe_phy_check_mode(pdata, mode,
1506a5c72737SRavi Kumar 					    ADVERTISED_10000baseT_Full);
1507a5c72737SRavi Kumar 	default:
1508a5c72737SRavi Kumar 		return false;
1509a5c72737SRavi Kumar 	}
1510a5c72737SRavi Kumar }
1511a5c72737SRavi Kumar 
1512a5c72737SRavi Kumar static bool axgbe_phy_use_sfp_mode(struct axgbe_port *pdata,
1513a5c72737SRavi Kumar 				   enum axgbe_mode mode)
1514a5c72737SRavi Kumar {
1515a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1516a5c72737SRavi Kumar 
1517a5c72737SRavi Kumar 	switch (mode) {
1518a5c72737SRavi Kumar 	case AXGBE_MODE_X:
1519a5c72737SRavi Kumar 		if (phy_data->sfp_base == AXGBE_SFP_BASE_1000_T)
1520a5c72737SRavi Kumar 			return false;
1521a5c72737SRavi Kumar 		return axgbe_phy_check_mode(pdata, mode,
1522a5c72737SRavi Kumar 					    ADVERTISED_1000baseT_Full);
1523a5c72737SRavi Kumar 	case AXGBE_MODE_SGMII_100:
1524a5c72737SRavi Kumar 		if (phy_data->sfp_base != AXGBE_SFP_BASE_1000_T)
1525a5c72737SRavi Kumar 			return false;
1526a5c72737SRavi Kumar 		return axgbe_phy_check_mode(pdata, mode,
1527a5c72737SRavi Kumar 					    ADVERTISED_100baseT_Full);
1528a5c72737SRavi Kumar 	case AXGBE_MODE_SGMII_1000:
1529a5c72737SRavi Kumar 		if (phy_data->sfp_base != AXGBE_SFP_BASE_1000_T)
1530a5c72737SRavi Kumar 			return false;
1531a5c72737SRavi Kumar 		return axgbe_phy_check_mode(pdata, mode,
1532a5c72737SRavi Kumar 					    ADVERTISED_1000baseT_Full);
1533a5c72737SRavi Kumar 	case AXGBE_MODE_SFI:
1534a5c72737SRavi Kumar 		return axgbe_phy_check_mode(pdata, mode,
1535a5c72737SRavi Kumar 					    ADVERTISED_10000baseT_Full);
1536a5c72737SRavi Kumar 	default:
1537a5c72737SRavi Kumar 		return false;
1538a5c72737SRavi Kumar 	}
1539a5c72737SRavi Kumar }
1540a5c72737SRavi Kumar 
1541a5c72737SRavi Kumar static bool axgbe_phy_use_bp_2500_mode(struct axgbe_port *pdata,
1542a5c72737SRavi Kumar 				       enum axgbe_mode mode)
1543a5c72737SRavi Kumar {
1544a5c72737SRavi Kumar 	switch (mode) {
1545a5c72737SRavi Kumar 	case AXGBE_MODE_KX_2500:
1546a5c72737SRavi Kumar 		return axgbe_phy_check_mode(pdata, mode,
1547a5c72737SRavi Kumar 					    ADVERTISED_2500baseX_Full);
1548a5c72737SRavi Kumar 	default:
1549a5c72737SRavi Kumar 		return false;
1550a5c72737SRavi Kumar 	}
1551a5c72737SRavi Kumar }
1552a5c72737SRavi Kumar 
1553a5c72737SRavi Kumar static bool axgbe_phy_use_bp_mode(struct axgbe_port *pdata,
1554a5c72737SRavi Kumar 				  enum axgbe_mode mode)
1555a5c72737SRavi Kumar {
1556a5c72737SRavi Kumar 	switch (mode) {
1557a5c72737SRavi Kumar 	case AXGBE_MODE_KX_1000:
1558a5c72737SRavi Kumar 		return axgbe_phy_check_mode(pdata, mode,
1559a5c72737SRavi Kumar 					    ADVERTISED_1000baseKX_Full);
1560a5c72737SRavi Kumar 	case AXGBE_MODE_KR:
1561a5c72737SRavi Kumar 		return axgbe_phy_check_mode(pdata, mode,
1562a5c72737SRavi Kumar 					    ADVERTISED_10000baseKR_Full);
1563a5c72737SRavi Kumar 	default:
1564a5c72737SRavi Kumar 		return false;
1565a5c72737SRavi Kumar 	}
1566a5c72737SRavi Kumar }
1567a5c72737SRavi Kumar 
1568a5c72737SRavi Kumar static bool axgbe_phy_use_mode(struct axgbe_port *pdata, enum axgbe_mode mode)
1569a5c72737SRavi Kumar {
1570a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1571a5c72737SRavi Kumar 
1572a5c72737SRavi Kumar 	switch (phy_data->port_mode) {
1573a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE:
1574a5c72737SRavi Kumar 		return axgbe_phy_use_bp_mode(pdata, mode);
1575a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE_2500:
1576a5c72737SRavi Kumar 		return axgbe_phy_use_bp_2500_mode(pdata, mode);
1577a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_T:
1578a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_NBASE_T:
1579a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_T:
1580a5c72737SRavi Kumar 		return axgbe_phy_use_baset_mode(pdata, mode);
1581a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_X:
1582a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_R:
1583a5c72737SRavi Kumar 		return axgbe_phy_use_basex_mode(pdata, mode);
1584a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_SFP:
1585a5c72737SRavi Kumar 		return axgbe_phy_use_sfp_mode(pdata, mode);
1586a5c72737SRavi Kumar 	default:
1587a5c72737SRavi Kumar 		return false;
1588a5c72737SRavi Kumar 	}
1589a5c72737SRavi Kumar }
1590a5c72737SRavi Kumar 
1591a5c72737SRavi Kumar static int axgbe_phy_link_status(struct axgbe_port *pdata, int *an_restart)
1592a5c72737SRavi Kumar {
1593a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1594a5c72737SRavi Kumar 	unsigned int reg;
1595a5c72737SRavi Kumar 
1596a5c72737SRavi Kumar 	*an_restart = 0;
1597a5c72737SRavi Kumar 
1598a5c72737SRavi Kumar 	if (phy_data->port_mode == AXGBE_PORT_MODE_SFP) {
1599a5c72737SRavi Kumar 		/* Check SFP signals */
1600a5c72737SRavi Kumar 		axgbe_phy_sfp_detect(pdata);
1601a5c72737SRavi Kumar 
1602a5c72737SRavi Kumar 		if (phy_data->sfp_changed) {
1603a5c72737SRavi Kumar 			*an_restart = 1;
1604a5c72737SRavi Kumar 			return 0;
1605a5c72737SRavi Kumar 		}
1606a5c72737SRavi Kumar 
1607a5c72737SRavi Kumar 		if (phy_data->sfp_mod_absent || phy_data->sfp_rx_los)
1608a5c72737SRavi Kumar 			return 0;
1609a5c72737SRavi Kumar 	}
1610a5c72737SRavi Kumar 
1611a5c72737SRavi Kumar 	/* Link status is latched low, so read once to clear
1612a5c72737SRavi Kumar 	 * and then read again to get current state
1613a5c72737SRavi Kumar 	 */
1614a5c72737SRavi Kumar 	reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
1615a5c72737SRavi Kumar 	reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
1616a5c72737SRavi Kumar 	if (reg & MDIO_STAT1_LSTATUS)
1617a5c72737SRavi Kumar 		return 1;
1618a5c72737SRavi Kumar 
1619a5c72737SRavi Kumar 	/* No link, attempt a receiver reset cycle */
1620a5c72737SRavi Kumar 	if (phy_data->rrc_count++) {
1621a5c72737SRavi Kumar 		phy_data->rrc_count = 0;
1622a5c72737SRavi Kumar 		axgbe_phy_rrc(pdata);
1623a5c72737SRavi Kumar 	}
1624a5c72737SRavi Kumar 
1625a5c72737SRavi Kumar 	return 0;
1626a5c72737SRavi Kumar }
1627a5c72737SRavi Kumar 
16284ac7516bSRavi Kumar static void axgbe_phy_sfp_gpio_setup(struct axgbe_port *pdata)
16294ac7516bSRavi Kumar {
16304ac7516bSRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
16314ac7516bSRavi Kumar 	unsigned int reg;
16324ac7516bSRavi Kumar 
16334ac7516bSRavi Kumar 	reg = XP_IOREAD(pdata, XP_PROP_3);
16344ac7516bSRavi Kumar 
16354ac7516bSRavi Kumar 	phy_data->sfp_gpio_address = AXGBE_GPIO_ADDRESS_PCA9555 +
16364ac7516bSRavi Kumar 		XP_GET_BITS(reg, XP_PROP_3, GPIO_ADDR);
16374ac7516bSRavi Kumar 
16384ac7516bSRavi Kumar 	phy_data->sfp_gpio_mask = XP_GET_BITS(reg, XP_PROP_3, GPIO_MASK);
16394ac7516bSRavi Kumar 
16404ac7516bSRavi Kumar 	phy_data->sfp_gpio_rx_los = XP_GET_BITS(reg, XP_PROP_3,
16414ac7516bSRavi Kumar 						GPIO_RX_LOS);
16424ac7516bSRavi Kumar 	phy_data->sfp_gpio_tx_fault = XP_GET_BITS(reg, XP_PROP_3,
16434ac7516bSRavi Kumar 						  GPIO_TX_FAULT);
16444ac7516bSRavi Kumar 	phy_data->sfp_gpio_mod_absent = XP_GET_BITS(reg, XP_PROP_3,
16454ac7516bSRavi Kumar 						    GPIO_MOD_ABS);
16464ac7516bSRavi Kumar 	phy_data->sfp_gpio_rate_select = XP_GET_BITS(reg, XP_PROP_3,
16474ac7516bSRavi Kumar 						     GPIO_RATE_SELECT);
16484ac7516bSRavi Kumar }
16494ac7516bSRavi Kumar 
16504ac7516bSRavi Kumar static void axgbe_phy_sfp_comm_setup(struct axgbe_port *pdata)
16514ac7516bSRavi Kumar {
16524ac7516bSRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
16534ac7516bSRavi Kumar 	unsigned int reg, mux_addr_hi, mux_addr_lo;
16544ac7516bSRavi Kumar 
16554ac7516bSRavi Kumar 	reg = XP_IOREAD(pdata, XP_PROP_4);
16564ac7516bSRavi Kumar 
16574ac7516bSRavi Kumar 	mux_addr_hi = XP_GET_BITS(reg, XP_PROP_4, MUX_ADDR_HI);
16584ac7516bSRavi Kumar 	mux_addr_lo = XP_GET_BITS(reg, XP_PROP_4, MUX_ADDR_LO);
16594ac7516bSRavi Kumar 	if (mux_addr_lo == AXGBE_SFP_DIRECT)
16604ac7516bSRavi Kumar 		return;
16614ac7516bSRavi Kumar 
16624ac7516bSRavi Kumar 	phy_data->sfp_comm = AXGBE_SFP_COMM_PCA9545;
16634ac7516bSRavi Kumar 	phy_data->sfp_mux_address = (mux_addr_hi << 2) + mux_addr_lo;
16644ac7516bSRavi Kumar 	phy_data->sfp_mux_channel = XP_GET_BITS(reg, XP_PROP_4, MUX_CHAN);
16654ac7516bSRavi Kumar }
16664ac7516bSRavi Kumar 
16674ac7516bSRavi Kumar static void axgbe_phy_sfp_setup(struct axgbe_port *pdata)
16684ac7516bSRavi Kumar {
16694ac7516bSRavi Kumar 	axgbe_phy_sfp_comm_setup(pdata);
16704ac7516bSRavi Kumar 	axgbe_phy_sfp_gpio_setup(pdata);
16714ac7516bSRavi Kumar }
16724ac7516bSRavi Kumar 
16734ac7516bSRavi Kumar static bool axgbe_phy_redrv_error(struct axgbe_phy_data *phy_data)
16744ac7516bSRavi Kumar {
16754ac7516bSRavi Kumar 	if (!phy_data->redrv)
16764ac7516bSRavi Kumar 		return false;
16774ac7516bSRavi Kumar 
16784ac7516bSRavi Kumar 	if (phy_data->redrv_if >= AXGBE_PHY_REDRV_IF_MAX)
16794ac7516bSRavi Kumar 		return true;
16804ac7516bSRavi Kumar 
16814ac7516bSRavi Kumar 	switch (phy_data->redrv_model) {
16824ac7516bSRavi Kumar 	case AXGBE_PHY_REDRV_MODEL_4223:
16834ac7516bSRavi Kumar 		if (phy_data->redrv_lane > 3)
16844ac7516bSRavi Kumar 			return true;
16854ac7516bSRavi Kumar 		break;
16864ac7516bSRavi Kumar 	case AXGBE_PHY_REDRV_MODEL_4227:
16874ac7516bSRavi Kumar 		if (phy_data->redrv_lane > 1)
16884ac7516bSRavi Kumar 			return true;
16894ac7516bSRavi Kumar 		break;
16904ac7516bSRavi Kumar 	default:
16914ac7516bSRavi Kumar 		return true;
16924ac7516bSRavi Kumar 	}
16934ac7516bSRavi Kumar 
16944ac7516bSRavi Kumar 	return false;
16954ac7516bSRavi Kumar }
16964ac7516bSRavi Kumar 
16974ac7516bSRavi Kumar static int axgbe_phy_mdio_reset_setup(struct axgbe_port *pdata)
16984ac7516bSRavi Kumar {
16994ac7516bSRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
17004ac7516bSRavi Kumar 	unsigned int reg;
17014ac7516bSRavi Kumar 
17024ac7516bSRavi Kumar 	if (phy_data->conn_type != AXGBE_CONN_TYPE_MDIO)
17034ac7516bSRavi Kumar 		return 0;
17044ac7516bSRavi Kumar 	reg = XP_IOREAD(pdata, XP_PROP_3);
17054ac7516bSRavi Kumar 	phy_data->mdio_reset = XP_GET_BITS(reg, XP_PROP_3, MDIO_RESET);
17064ac7516bSRavi Kumar 	switch (phy_data->mdio_reset) {
17074ac7516bSRavi Kumar 	case AXGBE_MDIO_RESET_NONE:
17084ac7516bSRavi Kumar 	case AXGBE_MDIO_RESET_I2C_GPIO:
17094ac7516bSRavi Kumar 	case AXGBE_MDIO_RESET_INT_GPIO:
17104ac7516bSRavi Kumar 		break;
17114ac7516bSRavi Kumar 	default:
17124ac7516bSRavi Kumar 		PMD_DRV_LOG(ERR, "unsupported MDIO reset (%#x)\n",
17134ac7516bSRavi Kumar 			    phy_data->mdio_reset);
17144ac7516bSRavi Kumar 		return -EINVAL;
17154ac7516bSRavi Kumar 	}
17164ac7516bSRavi Kumar 	if (phy_data->mdio_reset == AXGBE_MDIO_RESET_I2C_GPIO) {
17174ac7516bSRavi Kumar 		phy_data->mdio_reset_addr = AXGBE_GPIO_ADDRESS_PCA9555 +
17184ac7516bSRavi Kumar 			XP_GET_BITS(reg, XP_PROP_3,
17194ac7516bSRavi Kumar 				    MDIO_RESET_I2C_ADDR);
17204ac7516bSRavi Kumar 		phy_data->mdio_reset_gpio = XP_GET_BITS(reg, XP_PROP_3,
17214ac7516bSRavi Kumar 							MDIO_RESET_I2C_GPIO);
17224ac7516bSRavi Kumar 	} else if (phy_data->mdio_reset == AXGBE_MDIO_RESET_INT_GPIO) {
17234ac7516bSRavi Kumar 		phy_data->mdio_reset_gpio = XP_GET_BITS(reg, XP_PROP_3,
17244ac7516bSRavi Kumar 							MDIO_RESET_INT_GPIO);
17254ac7516bSRavi Kumar 	}
17264ac7516bSRavi Kumar 
17274ac7516bSRavi Kumar 	return 0;
17284ac7516bSRavi Kumar }
17294ac7516bSRavi Kumar 
17304ac7516bSRavi Kumar static bool axgbe_phy_port_mode_mismatch(struct axgbe_port *pdata)
17314ac7516bSRavi Kumar {
17324ac7516bSRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
17334ac7516bSRavi Kumar 
17344ac7516bSRavi Kumar 	switch (phy_data->port_mode) {
17354ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE:
17364ac7516bSRavi Kumar 		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) ||
17374ac7516bSRavi Kumar 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000))
17384ac7516bSRavi Kumar 			return false;
17394ac7516bSRavi Kumar 		break;
17404ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE_2500:
17414ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500)
17424ac7516bSRavi Kumar 			return false;
17434ac7516bSRavi Kumar 		break;
17444ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_T:
17454ac7516bSRavi Kumar 		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
17464ac7516bSRavi Kumar 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000))
17474ac7516bSRavi Kumar 			return false;
17484ac7516bSRavi Kumar 		break;
17494ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_X:
17504ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000)
17514ac7516bSRavi Kumar 			return false;
17524ac7516bSRavi Kumar 		break;
17534ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_NBASE_T:
17544ac7516bSRavi Kumar 		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
17554ac7516bSRavi Kumar 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) ||
17564ac7516bSRavi Kumar 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500))
17574ac7516bSRavi Kumar 			return false;
17584ac7516bSRavi Kumar 		break;
17594ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_T:
17604ac7516bSRavi Kumar 		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
17614ac7516bSRavi Kumar 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) ||
17624ac7516bSRavi Kumar 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000))
17634ac7516bSRavi Kumar 			return false;
17644ac7516bSRavi Kumar 		break;
17654ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_R:
17664ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000)
17674ac7516bSRavi Kumar 			return false;
17684ac7516bSRavi Kumar 		break;
17694ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_SFP:
17704ac7516bSRavi Kumar 		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
17714ac7516bSRavi Kumar 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) ||
17724ac7516bSRavi Kumar 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000))
17734ac7516bSRavi Kumar 			return false;
17744ac7516bSRavi Kumar 		break;
17754ac7516bSRavi Kumar 	default:
17764ac7516bSRavi Kumar 		break;
17774ac7516bSRavi Kumar 	}
17784ac7516bSRavi Kumar 
17794ac7516bSRavi Kumar 	return true;
17804ac7516bSRavi Kumar }
17814ac7516bSRavi Kumar 
17824ac7516bSRavi Kumar static bool axgbe_phy_conn_type_mismatch(struct axgbe_port *pdata)
17834ac7516bSRavi Kumar {
17844ac7516bSRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
17854ac7516bSRavi Kumar 
17864ac7516bSRavi Kumar 	switch (phy_data->port_mode) {
17874ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE:
17884ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE_2500:
17894ac7516bSRavi Kumar 		if (phy_data->conn_type == AXGBE_CONN_TYPE_BACKPLANE)
17904ac7516bSRavi Kumar 			return false;
17914ac7516bSRavi Kumar 		break;
17924ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_T:
17934ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_X:
17944ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_NBASE_T:
17954ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_T:
17964ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_R:
17974ac7516bSRavi Kumar 		if (phy_data->conn_type == AXGBE_CONN_TYPE_MDIO)
17984ac7516bSRavi Kumar 			return false;
17994ac7516bSRavi Kumar 		break;
18004ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_SFP:
18014ac7516bSRavi Kumar 		if (phy_data->conn_type == AXGBE_CONN_TYPE_SFP)
18024ac7516bSRavi Kumar 			return false;
18034ac7516bSRavi Kumar 		break;
18044ac7516bSRavi Kumar 	default:
18054ac7516bSRavi Kumar 		break;
18064ac7516bSRavi Kumar 	}
18074ac7516bSRavi Kumar 
18084ac7516bSRavi Kumar 	return true;
18094ac7516bSRavi Kumar }
18104ac7516bSRavi Kumar 
18114ac7516bSRavi Kumar static bool axgbe_phy_port_enabled(struct axgbe_port *pdata)
18124ac7516bSRavi Kumar {
18134ac7516bSRavi Kumar 	unsigned int reg;
18144ac7516bSRavi Kumar 
18154ac7516bSRavi Kumar 	reg = XP_IOREAD(pdata, XP_PROP_0);
18164ac7516bSRavi Kumar 	if (!XP_GET_BITS(reg, XP_PROP_0, PORT_SPEEDS))
18174ac7516bSRavi Kumar 		return false;
18184ac7516bSRavi Kumar 	if (!XP_GET_BITS(reg, XP_PROP_0, CONN_TYPE))
18194ac7516bSRavi Kumar 		return false;
18204ac7516bSRavi Kumar 
18214ac7516bSRavi Kumar 	return true;
18224ac7516bSRavi Kumar }
18234ac7516bSRavi Kumar 
182400072056SRavi Kumar static void axgbe_phy_cdr_track(struct axgbe_port *pdata)
182500072056SRavi Kumar {
182600072056SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
182700072056SRavi Kumar 
182800072056SRavi Kumar 	if (!pdata->vdata->an_cdr_workaround)
182900072056SRavi Kumar 		return;
183000072056SRavi Kumar 
183100072056SRavi Kumar 	if (!phy_data->phy_cdr_notrack)
183200072056SRavi Kumar 		return;
183300072056SRavi Kumar 
183400072056SRavi Kumar 	rte_delay_us(phy_data->phy_cdr_delay + 400);
183500072056SRavi Kumar 
183600072056SRavi Kumar 	XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_CDR_CONTROL,
183700072056SRavi Kumar 			 AXGBE_PMA_CDR_TRACK_EN_MASK,
183800072056SRavi Kumar 			 AXGBE_PMA_CDR_TRACK_EN_ON);
183900072056SRavi Kumar 
184000072056SRavi Kumar 	phy_data->phy_cdr_notrack = 0;
184100072056SRavi Kumar }
184200072056SRavi Kumar 
184300072056SRavi Kumar static void axgbe_phy_cdr_notrack(struct axgbe_port *pdata)
184400072056SRavi Kumar {
184500072056SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
184600072056SRavi Kumar 
184700072056SRavi Kumar 	if (!pdata->vdata->an_cdr_workaround)
184800072056SRavi Kumar 		return;
184900072056SRavi Kumar 
185000072056SRavi Kumar 	if (phy_data->phy_cdr_notrack)
185100072056SRavi Kumar 		return;
185200072056SRavi Kumar 
185300072056SRavi Kumar 	XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_CDR_CONTROL,
185400072056SRavi Kumar 			 AXGBE_PMA_CDR_TRACK_EN_MASK,
185500072056SRavi Kumar 			 AXGBE_PMA_CDR_TRACK_EN_OFF);
185600072056SRavi Kumar 
185700072056SRavi Kumar 	axgbe_phy_rrc(pdata);
185800072056SRavi Kumar 
185900072056SRavi Kumar 	phy_data->phy_cdr_notrack = 1;
186000072056SRavi Kumar }
186100072056SRavi Kumar 
186200072056SRavi Kumar static void axgbe_phy_kr_training_post(struct axgbe_port *pdata)
186300072056SRavi Kumar {
186400072056SRavi Kumar 	if (!pdata->cdr_track_early)
186500072056SRavi Kumar 		axgbe_phy_cdr_track(pdata);
186600072056SRavi Kumar }
186700072056SRavi Kumar 
186800072056SRavi Kumar static void axgbe_phy_kr_training_pre(struct axgbe_port *pdata)
186900072056SRavi Kumar {
187000072056SRavi Kumar 	if (pdata->cdr_track_early)
187100072056SRavi Kumar 		axgbe_phy_cdr_track(pdata);
187200072056SRavi Kumar }
187300072056SRavi Kumar 
187400072056SRavi Kumar static void axgbe_phy_an_post(struct axgbe_port *pdata)
187500072056SRavi Kumar {
187600072056SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
187700072056SRavi Kumar 
187800072056SRavi Kumar 	switch (pdata->an_mode) {
187900072056SRavi Kumar 	case AXGBE_AN_MODE_CL73:
188000072056SRavi Kumar 	case AXGBE_AN_MODE_CL73_REDRV:
188100072056SRavi Kumar 		if (phy_data->cur_mode != AXGBE_MODE_KR)
188200072056SRavi Kumar 			break;
188300072056SRavi Kumar 
188400072056SRavi Kumar 		axgbe_phy_cdr_track(pdata);
188500072056SRavi Kumar 
188600072056SRavi Kumar 		switch (pdata->an_result) {
188700072056SRavi Kumar 		case AXGBE_AN_READY:
188800072056SRavi Kumar 		case AXGBE_AN_COMPLETE:
188900072056SRavi Kumar 			break;
189000072056SRavi Kumar 		default:
189100072056SRavi Kumar 			if (phy_data->phy_cdr_delay < AXGBE_CDR_DELAY_MAX)
189200072056SRavi Kumar 				phy_data->phy_cdr_delay += AXGBE_CDR_DELAY_INC;
189300072056SRavi Kumar 			break;
189400072056SRavi Kumar 		}
189500072056SRavi Kumar 		break;
189600072056SRavi Kumar 	default:
189700072056SRavi Kumar 		break;
189800072056SRavi Kumar 	}
189900072056SRavi Kumar }
190000072056SRavi Kumar 
190100072056SRavi Kumar static void axgbe_phy_an_pre(struct axgbe_port *pdata)
190200072056SRavi Kumar {
190300072056SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
190400072056SRavi Kumar 
190500072056SRavi Kumar 	switch (pdata->an_mode) {
190600072056SRavi Kumar 	case AXGBE_AN_MODE_CL73:
190700072056SRavi Kumar 	case AXGBE_AN_MODE_CL73_REDRV:
190800072056SRavi Kumar 		if (phy_data->cur_mode != AXGBE_MODE_KR)
190900072056SRavi Kumar 			break;
191000072056SRavi Kumar 
191100072056SRavi Kumar 		axgbe_phy_cdr_notrack(pdata);
191200072056SRavi Kumar 		break;
191300072056SRavi Kumar 	default:
191400072056SRavi Kumar 		break;
191500072056SRavi Kumar 	}
191600072056SRavi Kumar }
191700072056SRavi Kumar 
1918a5c72737SRavi Kumar static void axgbe_phy_stop(struct axgbe_port *pdata)
1919a5c72737SRavi Kumar {
1920a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1921a5c72737SRavi Kumar 
1922a5c72737SRavi Kumar 	/* Reset SFP data */
1923a5c72737SRavi Kumar 	axgbe_phy_sfp_reset(phy_data);
1924a5c72737SRavi Kumar 	axgbe_phy_sfp_mod_absent(pdata);
1925a5c72737SRavi Kumar 
192600072056SRavi Kumar 	/* Reset CDR support */
192700072056SRavi Kumar 	axgbe_phy_cdr_track(pdata);
192800072056SRavi Kumar 
1929a5c72737SRavi Kumar 	/* Power off the PHY */
1930a5c72737SRavi Kumar 	axgbe_phy_power_off(pdata);
1931a5c72737SRavi Kumar 
1932a5c72737SRavi Kumar 	/* Stop the I2C controller */
1933a5c72737SRavi Kumar 	pdata->i2c_if.i2c_stop(pdata);
1934a5c72737SRavi Kumar }
1935a5c72737SRavi Kumar 
1936a5c72737SRavi Kumar static int axgbe_phy_start(struct axgbe_port *pdata)
1937a5c72737SRavi Kumar {
1938a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1939a5c72737SRavi Kumar 	int ret;
1940a5c72737SRavi Kumar 
1941a5c72737SRavi Kumar 	/* Start the I2C controller */
1942a5c72737SRavi Kumar 	ret = pdata->i2c_if.i2c_start(pdata);
1943a5c72737SRavi Kumar 	if (ret)
1944a5c72737SRavi Kumar 		return ret;
1945a5c72737SRavi Kumar 
1946a5c72737SRavi Kumar 	/* Start in highest supported mode */
1947a5c72737SRavi Kumar 	axgbe_phy_set_mode(pdata, phy_data->start_mode);
1948a5c72737SRavi Kumar 
194900072056SRavi Kumar 	/* Reset CDR support */
195000072056SRavi Kumar 	axgbe_phy_cdr_track(pdata);
195100072056SRavi Kumar 
1952a5c72737SRavi Kumar 	/* After starting the I2C controller, we can check for an SFP */
1953a5c72737SRavi Kumar 	switch (phy_data->port_mode) {
1954a5c72737SRavi Kumar 	case AXGBE_PORT_MODE_SFP:
1955a5c72737SRavi Kumar 		axgbe_phy_sfp_detect(pdata);
1956a5c72737SRavi Kumar 		break;
1957a5c72737SRavi Kumar 	default:
1958a5c72737SRavi Kumar 		break;
1959a5c72737SRavi Kumar 	}
1960a5c72737SRavi Kumar 
1961a5c72737SRavi Kumar 	return ret;
1962a5c72737SRavi Kumar }
1963a5c72737SRavi Kumar 
1964a5c72737SRavi Kumar static int axgbe_phy_reset(struct axgbe_port *pdata)
1965a5c72737SRavi Kumar {
1966a5c72737SRavi Kumar 	struct axgbe_phy_data *phy_data = pdata->phy_data;
1967a5c72737SRavi Kumar 	enum axgbe_mode cur_mode;
1968a5c72737SRavi Kumar 
1969a5c72737SRavi Kumar 	/* Reset by power cycling the PHY */
1970a5c72737SRavi Kumar 	cur_mode = phy_data->cur_mode;
1971a5c72737SRavi Kumar 	axgbe_phy_power_off(pdata);
1972a5c72737SRavi Kumar 	/* First time reset is done with passed unknown mode*/
1973a5c72737SRavi Kumar 	axgbe_phy_set_mode(pdata, cur_mode);
1974a5c72737SRavi Kumar 	return 0;
1975a5c72737SRavi Kumar }
1976a5c72737SRavi Kumar 
19774ac7516bSRavi Kumar static int axgbe_phy_init(struct axgbe_port *pdata)
19784ac7516bSRavi Kumar {
19794ac7516bSRavi Kumar 	struct axgbe_phy_data *phy_data;
19804ac7516bSRavi Kumar 	unsigned int reg;
19814ac7516bSRavi Kumar 	int ret;
19824ac7516bSRavi Kumar 
19834ac7516bSRavi Kumar 	/* Check if enabled */
19844ac7516bSRavi Kumar 	if (!axgbe_phy_port_enabled(pdata)) {
19854ac7516bSRavi Kumar 		PMD_DRV_LOG(ERR, "device is not enabled\n");
19864ac7516bSRavi Kumar 		return -ENODEV;
19874ac7516bSRavi Kumar 	}
19884ac7516bSRavi Kumar 
19894ac7516bSRavi Kumar 	/* Initialize the I2C controller */
19904ac7516bSRavi Kumar 	ret = pdata->i2c_if.i2c_init(pdata);
19914ac7516bSRavi Kumar 	if (ret)
19924ac7516bSRavi Kumar 		return ret;
19934ac7516bSRavi Kumar 
19944ac7516bSRavi Kumar 	phy_data = rte_zmalloc("phy_data memory", sizeof(*phy_data), 0);
19954ac7516bSRavi Kumar 	if (!phy_data) {
19964ac7516bSRavi Kumar 		PMD_DRV_LOG(ERR, "phy_data allocation failed\n");
19974ac7516bSRavi Kumar 		return -ENOMEM;
19984ac7516bSRavi Kumar 	}
19994ac7516bSRavi Kumar 	pdata->phy_data = phy_data;
20004ac7516bSRavi Kumar 
20014ac7516bSRavi Kumar 	reg = XP_IOREAD(pdata, XP_PROP_0);
20024ac7516bSRavi Kumar 	phy_data->port_mode = XP_GET_BITS(reg, XP_PROP_0, PORT_MODE);
20034ac7516bSRavi Kumar 	phy_data->port_id = XP_GET_BITS(reg, XP_PROP_0, PORT_ID);
20044ac7516bSRavi Kumar 	phy_data->port_speeds = XP_GET_BITS(reg, XP_PROP_0, PORT_SPEEDS);
20054ac7516bSRavi Kumar 	phy_data->conn_type = XP_GET_BITS(reg, XP_PROP_0, CONN_TYPE);
20064ac7516bSRavi Kumar 	phy_data->mdio_addr = XP_GET_BITS(reg, XP_PROP_0, MDIO_ADDR);
20074ac7516bSRavi Kumar 
20084ac7516bSRavi Kumar 	reg = XP_IOREAD(pdata, XP_PROP_4);
20094ac7516bSRavi Kumar 	phy_data->redrv = XP_GET_BITS(reg, XP_PROP_4, REDRV_PRESENT);
20104ac7516bSRavi Kumar 	phy_data->redrv_if = XP_GET_BITS(reg, XP_PROP_4, REDRV_IF);
20114ac7516bSRavi Kumar 	phy_data->redrv_addr = XP_GET_BITS(reg, XP_PROP_4, REDRV_ADDR);
20124ac7516bSRavi Kumar 	phy_data->redrv_lane = XP_GET_BITS(reg, XP_PROP_4, REDRV_LANE);
20134ac7516bSRavi Kumar 	phy_data->redrv_model = XP_GET_BITS(reg, XP_PROP_4, REDRV_MODEL);
20144ac7516bSRavi Kumar 
20154ac7516bSRavi Kumar 	/* Validate the connection requested */
20164ac7516bSRavi Kumar 	if (axgbe_phy_conn_type_mismatch(pdata)) {
20174ac7516bSRavi Kumar 		PMD_DRV_LOG(ERR, "phy mode/connection mismatch (%#x/%#x)\n",
20184ac7516bSRavi Kumar 			    phy_data->port_mode, phy_data->conn_type);
20194ac7516bSRavi Kumar 		return -EINVAL;
20204ac7516bSRavi Kumar 	}
20214ac7516bSRavi Kumar 
20224ac7516bSRavi Kumar 	/* Validate the mode requested */
20234ac7516bSRavi Kumar 	if (axgbe_phy_port_mode_mismatch(pdata)) {
20244ac7516bSRavi Kumar 		PMD_DRV_LOG(ERR, "phy mode/speed mismatch (%#x/%#x)\n",
20254ac7516bSRavi Kumar 			    phy_data->port_mode, phy_data->port_speeds);
20264ac7516bSRavi Kumar 		return -EINVAL;
20274ac7516bSRavi Kumar 	}
20284ac7516bSRavi Kumar 
20294ac7516bSRavi Kumar 	/* Check for and validate MDIO reset support */
20304ac7516bSRavi Kumar 	ret = axgbe_phy_mdio_reset_setup(pdata);
20314ac7516bSRavi Kumar 	if (ret)
20324ac7516bSRavi Kumar 		return ret;
20334ac7516bSRavi Kumar 
20344ac7516bSRavi Kumar 	/* Validate the re-driver information */
20354ac7516bSRavi Kumar 	if (axgbe_phy_redrv_error(phy_data)) {
20364ac7516bSRavi Kumar 		PMD_DRV_LOG(ERR, "phy re-driver settings error\n");
20374ac7516bSRavi Kumar 		return -EINVAL;
20384ac7516bSRavi Kumar 	}
20394ac7516bSRavi Kumar 	pdata->kr_redrv = phy_data->redrv;
20404ac7516bSRavi Kumar 
20414ac7516bSRavi Kumar 	/* Indicate current mode is unknown */
20424ac7516bSRavi Kumar 	phy_data->cur_mode = AXGBE_MODE_UNKNOWN;
20434ac7516bSRavi Kumar 
20444ac7516bSRavi Kumar 	/* Initialize supported features */
20454ac7516bSRavi Kumar 	pdata->phy.supported = 0;
20464ac7516bSRavi Kumar 
20474ac7516bSRavi Kumar 	switch (phy_data->port_mode) {
20484ac7516bSRavi Kumar 		/* Backplane support */
20494ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE:
20504ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Autoneg;
20514ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
20524ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Backplane;
20534ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) {
20544ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_1000baseKX_Full;
20554ac7516bSRavi Kumar 			phy_data->start_mode = AXGBE_MODE_KX_1000;
20564ac7516bSRavi Kumar 		}
20574ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000) {
20584ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_10000baseKR_Full;
20594ac7516bSRavi Kumar 			if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
20604ac7516bSRavi Kumar 				pdata->phy.supported |=
20614ac7516bSRavi Kumar 					SUPPORTED_10000baseR_FEC;
20624ac7516bSRavi Kumar 			phy_data->start_mode = AXGBE_MODE_KR;
20634ac7516bSRavi Kumar 		}
20644ac7516bSRavi Kumar 
20654ac7516bSRavi Kumar 		phy_data->phydev_mode = AXGBE_MDIO_MODE_NONE;
20664ac7516bSRavi Kumar 		break;
20674ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_BACKPLANE_2500:
20684ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
20694ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Backplane;
20704ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_2500baseX_Full;
20714ac7516bSRavi Kumar 		phy_data->start_mode = AXGBE_MODE_KX_2500;
20724ac7516bSRavi Kumar 
20734ac7516bSRavi Kumar 		phy_data->phydev_mode = AXGBE_MDIO_MODE_NONE;
20744ac7516bSRavi Kumar 		break;
20754ac7516bSRavi Kumar 
20764ac7516bSRavi Kumar 		/* MDIO 1GBase-T support */
20774ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_T:
20784ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Autoneg;
20794ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
20804ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_TP;
20814ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) {
20824ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_100baseT_Full;
20834ac7516bSRavi Kumar 			phy_data->start_mode = AXGBE_MODE_SGMII_100;
20844ac7516bSRavi Kumar 		}
20854ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) {
20864ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_1000baseT_Full;
20874ac7516bSRavi Kumar 			phy_data->start_mode = AXGBE_MODE_SGMII_1000;
20884ac7516bSRavi Kumar 		}
20894ac7516bSRavi Kumar 
20904ac7516bSRavi Kumar 		phy_data->phydev_mode = AXGBE_MDIO_MODE_CL22;
20914ac7516bSRavi Kumar 		break;
20924ac7516bSRavi Kumar 
20934ac7516bSRavi Kumar 		/* MDIO Base-X support */
20944ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_1000BASE_X:
20954ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Autoneg;
20964ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
20974ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_FIBRE;
20984ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_1000baseT_Full;
20994ac7516bSRavi Kumar 		phy_data->start_mode = AXGBE_MODE_X;
21004ac7516bSRavi Kumar 
21014ac7516bSRavi Kumar 		phy_data->phydev_mode = AXGBE_MDIO_MODE_CL22;
21024ac7516bSRavi Kumar 		break;
21034ac7516bSRavi Kumar 
21044ac7516bSRavi Kumar 		/* MDIO NBase-T support */
21054ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_NBASE_T:
21064ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Autoneg;
21074ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
21084ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_TP;
21094ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) {
21104ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_100baseT_Full;
21114ac7516bSRavi Kumar 			phy_data->start_mode = AXGBE_MODE_SGMII_100;
21124ac7516bSRavi Kumar 		}
21134ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) {
21144ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_1000baseT_Full;
21154ac7516bSRavi Kumar 			phy_data->start_mode = AXGBE_MODE_SGMII_1000;
21164ac7516bSRavi Kumar 		}
21174ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500) {
21184ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_2500baseX_Full;
21194ac7516bSRavi Kumar 			phy_data->start_mode = AXGBE_MODE_KX_2500;
21204ac7516bSRavi Kumar 		}
21214ac7516bSRavi Kumar 
21224ac7516bSRavi Kumar 		phy_data->phydev_mode = AXGBE_MDIO_MODE_CL45;
21234ac7516bSRavi Kumar 		break;
21244ac7516bSRavi Kumar 
21254ac7516bSRavi Kumar 		/* 10GBase-T support */
21264ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_T:
21274ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Autoneg;
21284ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
21294ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_TP;
21304ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) {
21314ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_100baseT_Full;
21324ac7516bSRavi Kumar 			phy_data->start_mode = AXGBE_MODE_SGMII_100;
21334ac7516bSRavi Kumar 		}
21344ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) {
21354ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_1000baseT_Full;
21364ac7516bSRavi Kumar 			phy_data->start_mode = AXGBE_MODE_SGMII_1000;
21374ac7516bSRavi Kumar 		}
21384ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000) {
21394ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_10000baseT_Full;
21404ac7516bSRavi Kumar 			phy_data->start_mode = AXGBE_MODE_KR;
21414ac7516bSRavi Kumar 		}
21424ac7516bSRavi Kumar 
21434ac7516bSRavi Kumar 		phy_data->phydev_mode = AXGBE_MDIO_MODE_NONE;
21444ac7516bSRavi Kumar 		break;
21454ac7516bSRavi Kumar 
21464ac7516bSRavi Kumar 		/* 10GBase-R support */
21474ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_10GBASE_R:
21484ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Autoneg;
21494ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
21504ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_TP;
21514ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_10000baseT_Full;
21524ac7516bSRavi Kumar 		if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
21534ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_10000baseR_FEC;
21544ac7516bSRavi Kumar 		phy_data->start_mode = AXGBE_MODE_SFI;
21554ac7516bSRavi Kumar 
21564ac7516bSRavi Kumar 		phy_data->phydev_mode = AXGBE_MDIO_MODE_NONE;
21574ac7516bSRavi Kumar 		break;
21584ac7516bSRavi Kumar 
21594ac7516bSRavi Kumar 		/* SFP support */
21604ac7516bSRavi Kumar 	case AXGBE_PORT_MODE_SFP:
21614ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Autoneg;
21624ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
21634ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_TP;
21644ac7516bSRavi Kumar 		pdata->phy.supported |= SUPPORTED_FIBRE;
21654ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) {
21664ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_100baseT_Full;
21674ac7516bSRavi Kumar 			phy_data->start_mode = AXGBE_MODE_SGMII_100;
21684ac7516bSRavi Kumar 		}
21694ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) {
21704ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_1000baseT_Full;
21714ac7516bSRavi Kumar 			phy_data->start_mode = AXGBE_MODE_SGMII_1000;
21724ac7516bSRavi Kumar 		}
21734ac7516bSRavi Kumar 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000) {
21744ac7516bSRavi Kumar 			pdata->phy.supported |= SUPPORTED_10000baseT_Full;
21754ac7516bSRavi Kumar 			phy_data->start_mode = AXGBE_MODE_SFI;
21764ac7516bSRavi Kumar 			if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
21774ac7516bSRavi Kumar 				pdata->phy.supported |=
21784ac7516bSRavi Kumar 					SUPPORTED_10000baseR_FEC;
21794ac7516bSRavi Kumar 		}
21804ac7516bSRavi Kumar 
21814ac7516bSRavi Kumar 		phy_data->phydev_mode = AXGBE_MDIO_MODE_CL22;
21824ac7516bSRavi Kumar 
21834ac7516bSRavi Kumar 		axgbe_phy_sfp_setup(pdata);
21844ac7516bSRavi Kumar 		break;
21854ac7516bSRavi Kumar 	default:
21864ac7516bSRavi Kumar 		return -EINVAL;
21874ac7516bSRavi Kumar 	}
21884ac7516bSRavi Kumar 
21894ac7516bSRavi Kumar 	if ((phy_data->conn_type & AXGBE_CONN_TYPE_MDIO) &&
21904ac7516bSRavi Kumar 	    (phy_data->phydev_mode != AXGBE_MDIO_MODE_NONE)) {
21914ac7516bSRavi Kumar 		ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->mdio_addr,
21924ac7516bSRavi Kumar 						    phy_data->phydev_mode);
21934ac7516bSRavi Kumar 		if (ret) {
21944ac7516bSRavi Kumar 			PMD_DRV_LOG(ERR, "mdio port/clause not compatible (%d/%u)\n",
21954ac7516bSRavi Kumar 				    phy_data->mdio_addr, phy_data->phydev_mode);
21964ac7516bSRavi Kumar 			return -EINVAL;
21974ac7516bSRavi Kumar 		}
21984ac7516bSRavi Kumar 	}
21994ac7516bSRavi Kumar 
22004ac7516bSRavi Kumar 	if (phy_data->redrv && !phy_data->redrv_if) {
22014ac7516bSRavi Kumar 		ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->redrv_addr,
22024ac7516bSRavi Kumar 						    AXGBE_MDIO_MODE_CL22);
22034ac7516bSRavi Kumar 		if (ret) {
22044ac7516bSRavi Kumar 			PMD_DRV_LOG(ERR, "redriver mdio port not compatible (%u)\n",
22054ac7516bSRavi Kumar 				    phy_data->redrv_addr);
22064ac7516bSRavi Kumar 			return -EINVAL;
22074ac7516bSRavi Kumar 		}
22084ac7516bSRavi Kumar 	}
220900072056SRavi Kumar 
221000072056SRavi Kumar 	phy_data->phy_cdr_delay = AXGBE_CDR_DELAY_INIT;
22114ac7516bSRavi Kumar 	return 0;
22124ac7516bSRavi Kumar }
22134ac7516bSRavi Kumar void axgbe_init_function_ptrs_phy_v2(struct axgbe_phy_if *phy_if)
22144ac7516bSRavi Kumar {
22154ac7516bSRavi Kumar 	struct axgbe_phy_impl_if *phy_impl = &phy_if->phy_impl;
22164ac7516bSRavi Kumar 
22174ac7516bSRavi Kumar 	phy_impl->init			= axgbe_phy_init;
2218a5c72737SRavi Kumar 	phy_impl->reset			= axgbe_phy_reset;
2219a5c72737SRavi Kumar 	phy_impl->start			= axgbe_phy_start;
2220a5c72737SRavi Kumar 	phy_impl->stop			= axgbe_phy_stop;
2221a5c72737SRavi Kumar 	phy_impl->link_status		= axgbe_phy_link_status;
2222a5c72737SRavi Kumar 	phy_impl->use_mode		= axgbe_phy_use_mode;
2223a5c72737SRavi Kumar 	phy_impl->set_mode		= axgbe_phy_set_mode;
2224a5c72737SRavi Kumar 	phy_impl->get_mode		= axgbe_phy_get_mode;
2225a5c72737SRavi Kumar 	phy_impl->switch_mode		= axgbe_phy_switch_mode;
2226a5c72737SRavi Kumar 	phy_impl->cur_mode		= axgbe_phy_cur_mode;
2227a5c72737SRavi Kumar 	phy_impl->an_mode		= axgbe_phy_an_mode;
2228a5c72737SRavi Kumar 	phy_impl->an_config		= axgbe_phy_an_config;
2229a5c72737SRavi Kumar 	phy_impl->an_advertising	= axgbe_phy_an_advertising;
2230a5c72737SRavi Kumar 	phy_impl->an_outcome		= axgbe_phy_an_outcome;
223100072056SRavi Kumar 
223200072056SRavi Kumar 	phy_impl->an_pre		= axgbe_phy_an_pre;
223300072056SRavi Kumar 	phy_impl->an_post		= axgbe_phy_an_post;
223400072056SRavi Kumar 
223500072056SRavi Kumar 	phy_impl->kr_training_pre	= axgbe_phy_kr_training_pre;
223600072056SRavi Kumar 	phy_impl->kr_training_post	= axgbe_phy_kr_training_post;
22374ac7516bSRavi Kumar }
2238