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