elink.c revision c300e355
1/*
2 * Copyright (c) 2007-2013 QLogic Corporation. All rights reserved.
3 *
4 * Eric Davis        <edavis@broadcom.com>
5 * David Christensen <davidch@broadcom.com>
6 * Gary Zambrano     <zambrano@broadcom.com>
7 *
8 * Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
9 * Copyright (c) 2015 QLogic Corporation.
10 * All rights reserved.
11 * www.qlogic.com
12 *
13 * See LICENSE.bnx2x_pmd for copyright and licensing details.
14 */
15
16#include "bnx2x.h"
17#include "elink.h"
18#include "ecore_mfw_req.h"
19#include "ecore_fw_defs.h"
20#include "ecore_hsi.h"
21#include "ecore_reg.h"
22
23static elink_status_t elink_link_reset(struct elink_params *params,
24				       struct elink_vars *vars,
25				       uint8_t reset_ext_phy);
26static elink_status_t elink_check_half_open_conn(struct elink_params *params,
27						 struct elink_vars *vars,
28						 uint8_t notify);
29static elink_status_t elink_sfp_module_detection(struct elink_phy *phy,
30						 struct elink_params *params);
31
32#define MDIO_REG_BANK_CL73_IEEEB0			0x0
33#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL		0x0
34#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN	0x0200
35#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN		0x1000
36#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_MAIN_RST	0x8000
37
38#define MDIO_REG_BANK_CL73_IEEEB1			0x10
39#define MDIO_CL73_IEEEB1_AN_ADV1			0x00
40#define	MDIO_CL73_IEEEB1_AN_ADV1_PAUSE			0x0400
41#define	MDIO_CL73_IEEEB1_AN_ADV1_ASYMMETRIC 		0x0800
42#define	MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH		0x0C00
43#define	MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK		0x0C00
44#define MDIO_CL73_IEEEB1_AN_ADV2				0x01
45#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M		0x0000
46#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX		0x0020
47#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4		0x0040
48#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR		0x0080
49#define	MDIO_CL73_IEEEB1_AN_LP_ADV1			0x03
50#define	MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE		0x0400
51#define	MDIO_CL73_IEEEB1_AN_LP_ADV1_ASYMMETRIC 		0x0800
52#define	MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_BOTH		0x0C00
53#define	MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK		0x0C00
54#define	MDIO_CL73_IEEEB1_AN_LP_ADV2			0x04
55
56#define	MDIO_REG_BANK_RX0				0x80b0
57#define	MDIO_RX0_RX_STATUS				0x10
58#define	MDIO_RX0_RX_STATUS_SIGDET			0x8000
59#define	MDIO_RX0_RX_STATUS_RX_SEQ_DONE			0x1000
60#define	MDIO_RX0_RX_EQ_BOOST				0x1c
61#define	MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
62#define	MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL		0x10
63
64#define	MDIO_REG_BANK_RX1				0x80c0
65#define	MDIO_RX1_RX_EQ_BOOST				0x1c
66#define	MDIO_RX1_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
67#define	MDIO_RX1_RX_EQ_BOOST_OFFSET_CTRL		0x10
68
69#define	MDIO_REG_BANK_RX2				0x80d0
70#define	MDIO_RX2_RX_EQ_BOOST				0x1c
71#define	MDIO_RX2_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
72#define	MDIO_RX2_RX_EQ_BOOST_OFFSET_CTRL		0x10
73
74#define	MDIO_REG_BANK_RX3				0x80e0
75#define	MDIO_RX3_RX_EQ_BOOST				0x1c
76#define	MDIO_RX3_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
77#define	MDIO_RX3_RX_EQ_BOOST_OFFSET_CTRL		0x10
78
79#define	MDIO_REG_BANK_RX_ALL				0x80f0
80#define	MDIO_RX_ALL_RX_EQ_BOOST				0x1c
81#define	MDIO_RX_ALL_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
82#define	MDIO_RX_ALL_RX_EQ_BOOST_OFFSET_CTRL	0x10
83
84#define	MDIO_REG_BANK_TX0				0x8060
85#define	MDIO_TX0_TX_DRIVER				0x17
86#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
87#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
88#define	MDIO_TX0_TX_DRIVER_IDRIVER_MASK			0x0f00
89#define	MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
90#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
91#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
92#define	MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
93#define	MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
94#define	MDIO_TX0_TX_DRIVER_ICBUF1T			1
95
96#define	MDIO_REG_BANK_TX1				0x8070
97#define	MDIO_TX1_TX_DRIVER				0x17
98#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
99#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
100#define	MDIO_TX0_TX_DRIVER_IDRIVER_MASK			0x0f00
101#define	MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
102#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
103#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
104#define	MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
105#define	MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
106#define	MDIO_TX0_TX_DRIVER_ICBUF1T			1
107
108#define	MDIO_REG_BANK_TX2				0x8080
109#define	MDIO_TX2_TX_DRIVER				0x17
110#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
111#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
112#define	MDIO_TX0_TX_DRIVER_IDRIVER_MASK			0x0f00
113#define	MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
114#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
115#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
116#define	MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
117#define	MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
118#define	MDIO_TX0_TX_DRIVER_ICBUF1T			1
119
120#define	MDIO_REG_BANK_TX3				0x8090
121#define	MDIO_TX3_TX_DRIVER				0x17
122#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
123#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
124#define	MDIO_TX0_TX_DRIVER_IDRIVER_MASK			0x0f00
125#define	MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
126#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
127#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
128#define	MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
129#define	MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
130#define	MDIO_TX0_TX_DRIVER_ICBUF1T			1
131
132#define	MDIO_REG_BANK_XGXS_BLOCK0			0x8000
133#define	MDIO_BLOCK0_XGXS_CONTROL			0x10
134
135#define	MDIO_REG_BANK_XGXS_BLOCK1			0x8010
136#define	MDIO_BLOCK1_LANE_CTRL0				0x15
137#define	MDIO_BLOCK1_LANE_CTRL1				0x16
138#define	MDIO_BLOCK1_LANE_CTRL2				0x17
139#define	MDIO_BLOCK1_LANE_PRBS				0x19
140
141#define	MDIO_REG_BANK_XGXS_BLOCK2			0x8100
142#define	MDIO_XGXS_BLOCK2_RX_LN_SWAP			0x10
143#define	MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE		0x8000
144#define	MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE	0x4000
145#define	MDIO_XGXS_BLOCK2_TX_LN_SWAP		0x11
146#define	MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE		0x8000
147#define	MDIO_XGXS_BLOCK2_UNICORE_MODE_10G	0x14
148#define	MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS	0x0001
149#define	MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS	0x0010
150#define	MDIO_XGXS_BLOCK2_TEST_MODE_LANE		0x15
151
152#define	MDIO_REG_BANK_GP_STATUS				0x8120
153#define	MDIO_GP_STATUS_TOP_AN_STATUS1				0x1B
154#define	MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE	0x0001
155#define	MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE	0x0002
156#define	MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS		0x0004
157#define	MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS		0x0008
158#define	MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE	0x0010
159#define	MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_LP_NP_BAM_ABLE	0x0020
160#define	MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE	0x0040
161#define	MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE	0x0080
162#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK		0x3f00
163#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M		0x0000
164#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M		0x0100
165#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G		0x0200
166#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G		0x0300
167#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G		0x0400
168#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G		0x0500
169#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG	0x0600
170#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4	0x0700
171#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG	0x0800
172#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G	0x0900
173#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G		0x0A00
174#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G		0x0B00
175#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G		0x0C00
176#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX	0x0D00
177#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4	0x0E00
178#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR	0x0F00
179#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI	0x1B00
180#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS	0x1E00
181#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI	0x1F00
182#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_KR2	0x3900
183
184#define	MDIO_REG_BANK_10G_PARALLEL_DETECT		0x8130
185#define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS		0x10
186#define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK		0x8000
187#define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL		0x11
188#define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN	0x1
189#define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK		0x13
190#define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT		(0xb71<<1)
191
192#define	MDIO_REG_BANK_SERDES_DIGITAL			0x8300
193#define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1			0x10
194#define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE			0x0001
195#define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_TBI_IF			0x0002
196#define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN		0x0004
197#define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT	0x0008
198#define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET			0x0010
199#define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE			0x0020
200#define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL2			0x11
201#define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN			0x0001
202#define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_AN_FST_TMR			0x0040
203#define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1			0x14
204#define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SGMII			0x0001
205#define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_LINK			0x0002
206#define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_DUPLEX			0x0004
207#define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_MASK			0x0018
208#define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_SHIFT			3
209#define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_2_5G			0x0018
210#define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_1G			0x0010
211#define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_100M			0x0008
212#define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_10M			0x0000
213#define	MDIO_SERDES_DIGITAL_A_1000X_STATUS2			0x15
214#define	MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED			0x0002
215#define	MDIO_SERDES_DIGITAL_MISC1				0x18
216#define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_MASK			0xE000
217#define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_25M			0x0000
218#define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_100M			0x2000
219#define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_125M			0x4000
220#define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M			0x6000
221#define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_187_5M			0x8000
222#define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL			0x0010
223#define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK			0x000f
224#define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_2_5G			0x0000
225#define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_5G			0x0001
226#define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_6G			0x0002
227#define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_HIG			0x0003
228#define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4			0x0004
229#define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12G			0x0005
230#define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12_5G			0x0006
231#define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G			0x0007
232#define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_15G			0x0008
233#define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_16G			0x0009
234
235#define	MDIO_REG_BANK_OVER_1G				0x8320
236#define	MDIO_OVER_1G_DIGCTL_3_4					0x14
237#define	MDIO_OVER_1G_DIGCTL_3_4_MP_ID_MASK				0xffe0
238#define	MDIO_OVER_1G_DIGCTL_3_4_MP_ID_SHIFT				5
239#define	MDIO_OVER_1G_UP1					0x19
240#define	MDIO_OVER_1G_UP1_2_5G						0x0001
241#define	MDIO_OVER_1G_UP1_5G						0x0002
242#define	MDIO_OVER_1G_UP1_6G						0x0004
243#define	MDIO_OVER_1G_UP1_10G						0x0010
244#define	MDIO_OVER_1G_UP1_10GH						0x0008
245#define	MDIO_OVER_1G_UP1_12G						0x0020
246#define	MDIO_OVER_1G_UP1_12_5G						0x0040
247#define	MDIO_OVER_1G_UP1_13G						0x0080
248#define	MDIO_OVER_1G_UP1_15G						0x0100
249#define	MDIO_OVER_1G_UP1_16G						0x0200
250#define	MDIO_OVER_1G_UP2					0x1A
251#define	MDIO_OVER_1G_UP2_IPREDRIVER_MASK				0x0007
252#define	MDIO_OVER_1G_UP2_IDRIVER_MASK					0x0038
253#define	MDIO_OVER_1G_UP2_PREEMPHASIS_MASK				0x03C0
254#define	MDIO_OVER_1G_UP3					0x1B
255#define	MDIO_OVER_1G_UP3_HIGIG2						0x0001
256#define	MDIO_OVER_1G_LP_UP1					0x1C
257#define	MDIO_OVER_1G_LP_UP2					0x1D
258#define	MDIO_OVER_1G_LP_UP2_MR_ADV_OVER_1G_MASK				0x03ff
259#define	MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK				0x0780
260#define	MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT				7
261#define	MDIO_OVER_1G_LP_UP3						0x1E
262
263#define	MDIO_REG_BANK_REMOTE_PHY			0x8330
264#define	MDIO_REMOTE_PHY_MISC_RX_STATUS				0x10
265#define	MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG	0x0010
266#define	MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG	0x0600
267
268#define	MDIO_REG_BANK_BAM_NEXT_PAGE			0x8350
269#define	MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL			0x10
270#define	MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE			0x0001
271#define	MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN			0x0002
272
273#define	MDIO_REG_BANK_CL73_USERB0		0x8370
274#define	MDIO_CL73_USERB0_CL73_UCTRL				0x10
275#define	MDIO_CL73_USERB0_CL73_UCTRL_USTAT1_MUXSEL			0x0002
276#define	MDIO_CL73_USERB0_CL73_USTAT1				0x11
277#define	MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK			0x0100
278#define	MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37		0x0400
279#define	MDIO_CL73_USERB0_CL73_BAM_CTRL1				0x12
280#define	MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN				0x8000
281#define	MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN		0x4000
282#define	MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN		0x2000
283#define	MDIO_CL73_USERB0_CL73_BAM_CTRL3				0x14
284#define	MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR			0x0001
285
286#define	MDIO_REG_BANK_AER_BLOCK			0xFFD0
287#define	MDIO_AER_BLOCK_AER_REG					0x1E
288
289#define	MDIO_REG_BANK_COMBO_IEEE0		0xFFE0
290#define	MDIO_COMBO_IEEE0_MII_CONTROL				0x10
291#define	MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK			0x2040
292#define	MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_10			0x0000
293#define	MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100			0x2000
294#define	MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000			0x0040
295#define	MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX				0x0100
296#define	MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN				0x0200
297#define	MDIO_COMBO_IEEO_MII_CONTROL_AN_EN				0x1000
298#define	MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK				0x4000
299#define	MDIO_COMBO_IEEO_MII_CONTROL_RESET				0x8000
300#define	MDIO_COMBO_IEEE0_MII_STATUS				0x11
301#define	MDIO_COMBO_IEEE0_MII_STATUS_LINK_PASS				0x0004
302#define	MDIO_COMBO_IEEE0_MII_STATUS_AUTONEG_COMPLETE			0x0020
303#define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV				0x14
304#define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX			0x0020
305#define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_HALF_DUPLEX			0x0040
306#define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK			0x0180
307#define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE			0x0000
308#define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC			0x0080
309#define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC			0x0100
310#define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH			0x0180
311#define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_NEXT_PAGE				0x8000
312#define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1		0x15
313#define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_NEXT_PAGE	0x8000
314#define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_ACK		0x4000
315#define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_MASK	0x0180
316#define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_NONE	0x0000
317#define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_BOTH	0x0180
318#define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_HALF_DUP_CAP	0x0040
319#define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_FULL_DUP_CAP	0x0020
320/*WhenthelinkpartnerisinSGMIImode(bit0=1),then
321bit15=link,bit12=duplex,bits11:10=speed,bit14=acknowledge.
322Theotherbitsarereservedandshouldbezero*/
323#define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_SGMII_MODE	0x0001
324
325#define	MDIO_PMA_DEVAD			0x1
326/*ieee*/
327#define	MDIO_PMA_REG_CTRL		0x0
328#define	MDIO_PMA_REG_STATUS		0x1
329#define	MDIO_PMA_REG_10G_CTRL2		0x7
330#define MDIO_PMA_REG_TX_DISABLE		0x0009
331#define	MDIO_PMA_REG_RX_SD		0xa
332/*bnx2x*/
333#define	MDIO_PMA_REG_BNX2X_CTRL		0x0096
334#define MDIO_PMA_REG_FEC_CTRL		0x00ab
335#define	MDIO_PMA_LASI_RXCTRL		0x9000
336#define	MDIO_PMA_LASI_TXCTRL		0x9001
337#define	MDIO_PMA_LASI_CTRL		0x9002
338#define	MDIO_PMA_LASI_RXSTAT		0x9003
339#define	MDIO_PMA_LASI_TXSTAT		0x9004
340#define	MDIO_PMA_LASI_STAT		0x9005
341#define	MDIO_PMA_REG_PHY_IDENTIFIER	0xc800
342#define	MDIO_PMA_REG_DIGITAL_CTRL	0xc808
343#define	MDIO_PMA_REG_DIGITAL_STATUS	0xc809
344#define	MDIO_PMA_REG_TX_POWER_DOWN	0xca02
345#define	MDIO_PMA_REG_CMU_PLL_BYPASS	0xca09
346#define	MDIO_PMA_REG_MISC_CTRL		0xca0a
347#define	MDIO_PMA_REG_GEN_CTRL		0xca10
348#define	MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP	0x0188
349#define	MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET		0x018a
350#define	MDIO_PMA_REG_M8051_MSGIN_REG	0xca12
351#define	MDIO_PMA_REG_M8051_MSGOUT_REG	0xca13
352#define	MDIO_PMA_REG_ROM_VER1		0xca19
353#define	MDIO_PMA_REG_ROM_VER2		0xca1a
354#define	MDIO_PMA_REG_EDC_FFE_MAIN	0xca1b
355#define	MDIO_PMA_REG_PLL_BANDWIDTH	0xca1d
356#define MDIO_PMA_REG_PLL_CTRL 		0xca1e
357#define MDIO_PMA_REG_MISC_CTRL0 	0xca23
358#define MDIO_PMA_REG_LRM_MODE	 	0xca3f
359#define	MDIO_PMA_REG_CDR_BANDWIDTH 	0xca46
360#define	MDIO_PMA_REG_MISC_CTRL1		0xca85
361
362#define MDIO_PMA_REG_SFP_TWO_WIRE_CTRL		0x8000
363#define MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK 	0x000c
364#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE 		0x0000
365#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE 	0x0004
366#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IN_PROGRESS 	0x0008
367#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_FAILED 	0x000c
368#define MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT 	0x8002
369#define MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR 	0x8003
370#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF	0xc820
371#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK 0xff
372#define MDIO_PMA_REG_8726_TX_CTRL1		0xca01
373#define MDIO_PMA_REG_8726_TX_CTRL2		0xca05
374
375#define MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR	0x8005
376#define MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF	0x8007
377#define MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK 0xff
378#define MDIO_PMA_REG_8727_MISC_CTRL		0x8309
379#define MDIO_PMA_REG_8727_TX_CTRL1		0xca02
380#define MDIO_PMA_REG_8727_TX_CTRL2		0xca05
381#define MDIO_PMA_REG_8727_PCS_OPT_CTRL		0xc808
382#define MDIO_PMA_REG_8727_GPIO_CTRL		0xc80e
383#define MDIO_PMA_REG_8727_PCS_GP		0xc842
384#define MDIO_PMA_REG_8727_OPT_CFG_REG		0xc8e4
385
386#define MDIO_AN_REG_8727_MISC_CTRL		0x8309
387#define	MDIO_PMA_REG_8073_CHIP_REV			0xc801
388#define MDIO_PMA_REG_8073_SPEED_LINK_STATUS		0xc820
389#define MDIO_PMA_REG_8073_XAUI_WA 			0xc841
390#define MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL 		0xcd08
391
392#define MDIO_PMA_REG_7101_RESET		0xc000
393#define	MDIO_PMA_REG_7107_LED_CNTL	0xc007
394#define	MDIO_PMA_REG_7107_LINK_LED_CNTL	0xc009
395#define	MDIO_PMA_REG_7101_VER1		0xc026
396#define	MDIO_PMA_REG_7101_VER2		0xc027
397
398#define MDIO_PMA_REG_8481_PMD_SIGNAL	0xa811
399#define MDIO_PMA_REG_8481_LED1_MASK	0xa82c
400#define MDIO_PMA_REG_8481_LED2_MASK	0xa82f
401#define MDIO_PMA_REG_8481_LED3_MASK	0xa832
402#define MDIO_PMA_REG_8481_LED3_BLINK	0xa834
403#define MDIO_PMA_REG_8481_LED5_MASK	                0xa838
404#define MDIO_PMA_REG_8481_SIGNAL_MASK	0xa835
405#define MDIO_PMA_REG_8481_LINK_SIGNAL	0xa83b
406#define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK	0x800
407#define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT	11
408
409#define	MDIO_WIS_DEVAD			0x2
410/*bnx2x*/
411#define	MDIO_WIS_REG_LASI_CNTL		0x9002
412#define	MDIO_WIS_REG_LASI_STATUS	0x9005
413
414#define	MDIO_PCS_DEVAD			0x3
415#define	MDIO_PCS_REG_STATUS		0x0020
416#define MDIO_PCS_REG_LASI_STATUS	0x9005
417#define MDIO_PCS_REG_7101_DSP_ACCESS	0xD000
418#define MDIO_PCS_REG_7101_SPI_MUX 	0xD008
419#define MDIO_PCS_REG_7101_SPI_CTRL_ADDR 0xE12A
420#define MDIO_PCS_REG_7101_SPI_RESET_BIT (5)
421#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR 0xE02A
422#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD (6)
423#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD   (0xC7)
424#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD (2)
425#define MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR 0xE028
426
427#define	MDIO_XS_DEVAD			0x4
428#define	MDIO_XS_REG_STATUS		0x0001
429#define MDIO_XS_PLL_SEQUENCER 		0x8000
430#define	MDIO_XS_SFX7101_XGXS_TEST1	0xc00a
431
432#define MDIO_XS_8706_REG_BANK_RX0	0x80bc
433#define MDIO_XS_8706_REG_BANK_RX1	0x80cc
434#define MDIO_XS_8706_REG_BANK_RX2	0x80dc
435#define MDIO_XS_8706_REG_BANK_RX3	0x80ec
436#define MDIO_XS_8706_REG_BANK_RXA	0x80fc
437
438#define MDIO_XS_REG_8073_RX_CTRL_PCIE	0x80FA
439
440#define	MDIO_AN_DEVAD			0x7
441/*ieee*/
442#define	MDIO_AN_REG_CTRL		0x0000
443#define	MDIO_AN_REG_STATUS		0x0001
444#define	MDIO_AN_REG_STATUS_AN_COMPLETE		0x0020
445#define	MDIO_AN_REG_ADV_PAUSE		0x0010
446#define	MDIO_AN_REG_ADV_PAUSE_PAUSE		0x0400
447#define	MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC	0x0800
448#define	MDIO_AN_REG_ADV_PAUSE_BOTH		0x0C00
449#define	MDIO_AN_REG_ADV_PAUSE_MASK		0x0C00
450#define	MDIO_AN_REG_ADV			0x0011
451#define MDIO_AN_REG_ADV2		0x0012
452#define	MDIO_AN_REG_LP_AUTO_NEG		0x0013
453#define	MDIO_AN_REG_LP_AUTO_NEG2	0x0014
454#define	MDIO_AN_REG_MASTER_STATUS	0x0021
455#define	MDIO_AN_REG_EEE_ADV		0x003c
456#define	MDIO_AN_REG_LP_EEE_ADV		0x003d
457/*bnx2x*/
458#define	MDIO_AN_REG_LINK_STATUS		0x8304
459#define	MDIO_AN_REG_CL37_CL73		0x8370
460#define	MDIO_AN_REG_CL37_AN		0xffe0
461#define	MDIO_AN_REG_CL37_FC_LD		0xffe4
462#define 	MDIO_AN_REG_CL37_FC_LP		0xffe5
463#define 	MDIO_AN_REG_1000T_STATUS	0xffea
464
465#define MDIO_AN_REG_8073_2_5G		0x8329
466#define MDIO_AN_REG_8073_BAM		0x8350
467
468#define MDIO_AN_REG_8481_10GBASE_T_AN_CTRL	0x0020
469#define MDIO_AN_REG_8481_LEGACY_MII_CTRL	0xffe0
470#define MDIO_AN_REG_8481_MII_CTRL_FORCE_1G	0x40
471#define MDIO_AN_REG_8481_LEGACY_MII_STATUS	0xffe1
472#define MDIO_AN_REG_8481_LEGACY_AN_ADV		0xffe4
473#define MDIO_AN_REG_8481_LEGACY_AN_EXPANSION	0xffe6
474#define MDIO_AN_REG_8481_1000T_CTRL		0xffe9
475#define MDIO_AN_REG_8481_1G_100T_EXT_CTRL	0xfff0
476#define MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF	0x0008
477#define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW	0xfff5
478#define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS	0xfff7
479#define MDIO_AN_REG_8481_AUX_CTRL		0xfff8
480#define MDIO_AN_REG_8481_LEGACY_SHADOW		0xfffc
481
482/* BNX2X84823 only */
483#define	MDIO_CTL_DEVAD			0x1e
484#define MDIO_CTL_REG_84823_MEDIA		0x401a
485#define MDIO_CTL_REG_84823_MEDIA_MAC_MASK		0x0018
486	/* These pins configure the BNX2X84823 interface to MAC after reset. */
487#define MDIO_CTL_REG_84823_CTRL_MAC_XFI			0x0008
488#define MDIO_CTL_REG_84823_MEDIA_MAC_XAUI_M		0x0010
489	/* These pins configure the BNX2X84823 interface to Line after reset. */
490#define MDIO_CTL_REG_84823_MEDIA_LINE_MASK		0x0060
491#define MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L		0x0020
492#define MDIO_CTL_REG_84823_MEDIA_LINE_XFI		0x0040
493	/* When this pin is active high during reset, 10GBASE-T core is power
494	 * down, When it is active low the 10GBASE-T is power up
495	 */
496#define MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN	0x0080
497#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK		0x0100
498#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER	0x0000
499#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER		0x0100
500#define MDIO_CTL_REG_84823_MEDIA_FIBER_1G			0x1000
501#define MDIO_CTL_REG_84823_USER_CTRL_REG			0x4005
502#define MDIO_CTL_REG_84823_USER_CTRL_CMS			0x0080
503#define MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH		0xa82b
504#define MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ	0x2f
505#define MDIO_PMA_REG_84823_CTL_LED_CTL_1			0xa8e3
506#define MDIO_PMA_REG_84833_CTL_LED_CTL_1			0xa8ec
507#define MDIO_PMA_REG_84823_LED3_STRETCH_EN			0x0080
508
509/* BNX2X84833 only */
510#define MDIO_84833_TOP_CFG_FW_REV			0x400f
511#define MDIO_84833_TOP_CFG_FW_EEE		0x10b1
512#define MDIO_84833_TOP_CFG_FW_NO_EEE		0x1f81
513#define MDIO_84833_TOP_CFG_XGPHY_STRAP1 		0x401a
514#define MDIO_84833_SUPER_ISOLATE 		0x8000
515/* These are mailbox register set used by 84833. */
516#define MDIO_84833_TOP_CFG_SCRATCH_REG0			0x4005
517#define MDIO_84833_TOP_CFG_SCRATCH_REG1 		0x4006
518#define MDIO_84833_TOP_CFG_SCRATCH_REG2			0x4007
519#define MDIO_84833_TOP_CFG_SCRATCH_REG3			0x4008
520#define MDIO_84833_TOP_CFG_SCRATCH_REG4			0x4009
521#define MDIO_84833_TOP_CFG_SCRATCH_REG26		0x4037
522#define MDIO_84833_TOP_CFG_SCRATCH_REG27		0x4038
523#define MDIO_84833_TOP_CFG_SCRATCH_REG28		0x4039
524#define MDIO_84833_TOP_CFG_SCRATCH_REG29		0x403a
525#define MDIO_84833_TOP_CFG_SCRATCH_REG30		0x403b
526#define MDIO_84833_TOP_CFG_SCRATCH_REG31		0x403c
527#define MDIO_84833_CMD_HDLR_COMMAND	MDIO_84833_TOP_CFG_SCRATCH_REG0
528#define MDIO_84833_CMD_HDLR_STATUS	MDIO_84833_TOP_CFG_SCRATCH_REG26
529#define MDIO_84833_CMD_HDLR_DATA1	MDIO_84833_TOP_CFG_SCRATCH_REG27
530#define MDIO_84833_CMD_HDLR_DATA2	MDIO_84833_TOP_CFG_SCRATCH_REG28
531#define MDIO_84833_CMD_HDLR_DATA3	MDIO_84833_TOP_CFG_SCRATCH_REG29
532#define MDIO_84833_CMD_HDLR_DATA4	MDIO_84833_TOP_CFG_SCRATCH_REG30
533#define MDIO_84833_CMD_HDLR_DATA5	MDIO_84833_TOP_CFG_SCRATCH_REG31
534
535/* Mailbox command set used by 84833. */
536#define PHY84833_CMD_SET_PAIR_SWAP			0x8001
537#define PHY84833_CMD_GET_EEE_MODE			0x8008
538#define PHY84833_CMD_SET_EEE_MODE			0x8009
539#define PHY84833_CMD_GET_CURRENT_TEMP			0x8031
540/* Mailbox status set used by 84833. */
541#define PHY84833_STATUS_CMD_RECEIVED			0x0001
542#define PHY84833_STATUS_CMD_IN_PROGRESS			0x0002
543#define PHY84833_STATUS_CMD_COMPLETE_PASS		0x0004
544#define PHY84833_STATUS_CMD_COMPLETE_ERROR		0x0008
545#define PHY84833_STATUS_CMD_OPEN_FOR_CMDS		0x0010
546#define PHY84833_STATUS_CMD_SYSTEM_BOOT			0x0020
547#define PHY84833_STATUS_CMD_NOT_OPEN_FOR_CMDS		0x0040
548#define PHY84833_STATUS_CMD_CLEAR_COMPLETE		0x0080
549#define PHY84833_STATUS_CMD_OPEN_OVERRIDE		0xa5a5
550
551/* Warpcore clause 45 addressing */
552#define MDIO_WC_DEVAD					0x3
553#define MDIO_WC_REG_IEEE0BLK_MIICNTL                    0x0
554#define MDIO_WC_REG_IEEE0BLK_AUTONEGNP                  0x7
555#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT0       0x10
556#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1       0x11
557#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2       0x12
558#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY	0x4000
559#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ		0x8000
560#define MDIO_WC_REG_PCS_STATUS2				0x0021
561#define MDIO_WC_REG_PMD_KR_CONTROL			0x0096
562#define MDIO_WC_REG_XGXSBLK0_XGXSCONTROL                0x8000
563#define MDIO_WC_REG_XGXSBLK0_MISCCONTROL1               0x800e
564#define MDIO_WC_REG_XGXSBLK1_DESKEW                     0x8010
565#define MDIO_WC_REG_XGXSBLK1_LANECTRL0                  0x8015
566#define MDIO_WC_REG_XGXSBLK1_LANECTRL1                  0x8016
567#define MDIO_WC_REG_XGXSBLK1_LANECTRL2                  0x8017
568#define MDIO_WC_REG_XGXSBLK1_LANECTRL3                  0x8018
569#define MDIO_WC_REG_XGXSBLK1_LANETEST0                  0x801a
570#define MDIO_WC_REG_TX0_ANA_CTRL0			0x8061
571#define MDIO_WC_REG_TX1_ANA_CTRL0			0x8071
572#define MDIO_WC_REG_TX2_ANA_CTRL0			0x8081
573#define MDIO_WC_REG_TX3_ANA_CTRL0			0x8091
574#define MDIO_WC_REG_TX0_TX_DRIVER			0x8067
575#define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET		0x04
576#define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_MASK			0x00f0
577#define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET		0x08
578#define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_MASK				0x0f00
579#define MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET		0x0c
580#define MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_MASK			0x7000
581#define MDIO_WC_REG_TX1_TX_DRIVER			0x8077
582#define MDIO_WC_REG_TX2_TX_DRIVER			0x8087
583#define MDIO_WC_REG_TX3_TX_DRIVER			0x8097
584#define MDIO_WC_REG_RX0_ANARXCONTROL1G                  0x80b9
585#define MDIO_WC_REG_RX2_ANARXCONTROL1G                  0x80d9
586#define MDIO_WC_REG_RX0_PCI_CTRL			0x80ba
587#define MDIO_WC_REG_RX1_PCI_CTRL			0x80ca
588#define MDIO_WC_REG_RX2_PCI_CTRL			0x80da
589#define MDIO_WC_REG_RX3_PCI_CTRL			0x80ea
590#define MDIO_WC_REG_XGXSBLK2_UNICORE_MODE_10G 		0x8104
591#define MDIO_WC_REG_XGXS_STATUS3			0x8129
592#define MDIO_WC_REG_PAR_DET_10G_STATUS			0x8130
593#define MDIO_WC_REG_PAR_DET_10G_CTRL			0x8131
594#define MDIO_WC_REG_XGXS_STATUS4                        0x813c
595#define MDIO_WC_REG_XGXS_X2_CONTROL2 		        0x8141
596#define MDIO_WC_REG_XGXS_X2_CONTROL3 		        0x8142
597#define MDIO_WC_REG_XGXS_RX_LN_SWAP1		      	0x816B
598#define MDIO_WC_REG_XGXS_TX_LN_SWAP1		      	0x8169
599#define MDIO_WC_REG_GP2_STATUS_GP_2_0			0x81d0
600#define MDIO_WC_REG_GP2_STATUS_GP_2_1			0x81d1
601#define MDIO_WC_REG_GP2_STATUS_GP_2_2			0x81d2
602#define MDIO_WC_REG_GP2_STATUS_GP_2_3			0x81d3
603#define MDIO_WC_REG_GP2_STATUS_GP_2_4			0x81d4
604#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL 0x1000
605#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CMPL 0x0100
606#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP 0x0010
607#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CAP 0x1
608#define MDIO_WC_REG_UC_INFO_B0_DEAD_TRAP                0x81EE
609#define MDIO_WC_REG_UC_INFO_B1_VERSION                  0x81F0
610#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE		0x81F2
611#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE0_OFFSET	0x0
612#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT        0x0
613#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_OPT_LR     0x1
614#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC        0x2
615#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_XLAUI      0x3
616#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_LONG_CH_6G     0x4
617#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE1_OFFSET	0x4
618#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE2_OFFSET	0x8
619#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE3_OFFSET	0xc
620#define MDIO_WC_REG_UC_INFO_B1_CRC                      0x81FE
621#define MDIO_WC_REG_DSC1B0_UC_CTRL				0x820e
622#define MDIO_WC_REG_DSC1B0_UC_CTRL_RDY4CMD			(1<<7)
623#define MDIO_WC_REG_DSC_SMC				0x8213
624#define MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0		0x821e
625#define MDIO_WC_REG_TX_FIR_TAP				0x82e2
626#define MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET		0x00
627#define MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_MASK			0x000f
628#define MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET		0x04
629#define MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_MASK		0x03f0
630#define MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET		0x0a
631#define MDIO_WC_REG_TX_FIR_TAP_POST_TAP_MASK		0x7c00
632#define MDIO_WC_REG_TX_FIR_TAP_ENABLE		0x8000
633#define MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP		0x82e2
634#define MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL      0x82e3
635#define MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL	0x82e6
636#define MDIO_WC_REG_CL72_USERB0_CL72_BR_DEF_CTRL	0x82e7
637#define MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL	0x82e8
638#define MDIO_WC_REG_CL72_USERB0_CL72_MISC4_CONTROL      0x82ec
639#define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1         0x8300
640#define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2         0x8301
641#define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3         0x8302
642#define MDIO_WC_REG_SERDESDIGITAL_STATUS1000X1          0x8304
643#define MDIO_WC_REG_SERDESDIGITAL_MISC1                 0x8308
644#define MDIO_WC_REG_SERDESDIGITAL_MISC2                 0x8309
645#define MDIO_WC_REG_DIGITAL3_UP1                        0x8329
646#define MDIO_WC_REG_DIGITAL3_LP_UP1                     0x832c
647#define MDIO_WC_REG_DIGITAL4_MISC3                      0x833c
648#define MDIO_WC_REG_DIGITAL4_MISC5                      0x833e
649#define MDIO_WC_REG_DIGITAL5_MISC6                      0x8345
650#define MDIO_WC_REG_DIGITAL5_MISC7                      0x8349
651#define MDIO_WC_REG_DIGITAL5_LINK_STATUS		0x834d
652#define MDIO_WC_REG_DIGITAL5_ACTUAL_SPEED               0x834e
653#define MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL           0x8350
654#define MDIO_WC_REG_CL49_USERB0_CTRL	                0x8368
655#define MDIO_WC_REG_CL73_USERB0_CTRL                    0x8370
656#define MDIO_WC_REG_CL73_USERB0_USTAT                   0x8371
657#define MDIO_WC_REG_CL73_BAM_CTRL1			0x8372
658#define MDIO_WC_REG_CL73_BAM_CTRL2			0x8373
659#define MDIO_WC_REG_CL73_BAM_CTRL3			0x8374
660#define MDIO_WC_REG_CL73_BAM_CODE_FIELD			0x837b
661#define MDIO_WC_REG_EEE_COMBO_CONTROL0                  0x8390
662#define MDIO_WC_REG_TX66_CONTROL                        0x83b0
663#define MDIO_WC_REG_RX66_CONTROL                        0x83c0
664#define MDIO_WC_REG_RX66_SCW0                           0x83c2
665#define MDIO_WC_REG_RX66_SCW1                           0x83c3
666#define MDIO_WC_REG_RX66_SCW2                           0x83c4
667#define MDIO_WC_REG_RX66_SCW3                           0x83c5
668#define MDIO_WC_REG_RX66_SCW0_MASK                      0x83c6
669#define MDIO_WC_REG_RX66_SCW1_MASK                      0x83c7
670#define MDIO_WC_REG_RX66_SCW2_MASK                      0x83c8
671#define MDIO_WC_REG_RX66_SCW3_MASK                      0x83c9
672#define MDIO_WC_REG_FX100_CTRL1				0x8400
673#define MDIO_WC_REG_FX100_CTRL3				0x8402
674#define MDIO_WC_REG_CL82_USERB1_TX_CTRL5		0x8436
675#define MDIO_WC_REG_CL82_USERB1_TX_CTRL6		0x8437
676#define MDIO_WC_REG_CL82_USERB1_TX_CTRL7		0x8438
677#define MDIO_WC_REG_CL82_USERB1_TX_CTRL9		0x8439
678#define MDIO_WC_REG_CL82_USERB1_RX_CTRL10		0x843a
679#define MDIO_WC_REG_CL82_USERB1_RX_CTRL11		0x843b
680#define MDIO_WC_REG_ETA_CL73_OUI1			0x8453
681#define MDIO_WC_REG_ETA_CL73_OUI2			0x8454
682#define MDIO_WC_REG_ETA_CL73_OUI3			0x8455
683#define MDIO_WC_REG_ETA_CL73_LD_BAM_CODE		0x8456
684#define MDIO_WC_REG_ETA_CL73_LD_UD_CODE			0x8457
685#define MDIO_WC_REG_MICROBLK_CMD                        0xffc2
686#define MDIO_WC_REG_MICROBLK_DL_STATUS                  0xffc5
687#define MDIO_WC_REG_MICROBLK_CMD3                       0xffcc
688
689#define MDIO_WC_REG_AERBLK_AER                          0xffde
690#define MDIO_WC_REG_COMBO_IEEE0_MIICTRL			0xffe0
691#define MDIO_WC_REG_COMBO_IEEE0_MIIISTAT                0xffe1
692
693#define MDIO_WC0_XGXS_BLK2_LANE_RESET                   0x810A
694#define MDIO_WC0_XGXS_BLK2_LANE_RESET_RX_BITSHIFT 	0
695#define MDIO_WC0_XGXS_BLK2_LANE_RESET_TX_BITSHIFT 	4
696
697#define MDIO_WC0_XGXS_BLK6_XGXS_X2_CONTROL2             0x8141
698
699#define DIGITAL5_ACTUAL_SPEED_TX_MASK                   0x003f
700
701/* 54618se */
702#define MDIO_REG_GPHY_MII_STATUS			0x1
703#define MDIO_REG_GPHY_PHYID_LSB				0x3
704#define MDIO_REG_GPHY_CL45_ADDR_REG			0xd
705#define MDIO_REG_GPHY_CL45_REG_WRITE		0x4000
706#define MDIO_REG_GPHY_CL45_REG_READ		0xc000
707#define MDIO_REG_GPHY_CL45_DATA_REG			0xe
708#define MDIO_REG_GPHY_EEE_RESOLVED		0x803e
709#define MDIO_REG_GPHY_EXP_ACCESS_GATE			0x15
710#define MDIO_REG_GPHY_EXP_ACCESS			0x17
711#define MDIO_REG_GPHY_EXP_ACCESS_TOP		0xd00
712#define MDIO_REG_GPHY_EXP_TOP_2K_BUF		0x40
713#define MDIO_REG_GPHY_AUX_STATUS			0x19
714#define MDIO_REG_INTR_STATUS				0x1a
715#define MDIO_REG_INTR_MASK				0x1b
716#define MDIO_REG_INTR_MASK_LINK_STATUS			(0x1 << 1)
717#define MDIO_REG_GPHY_SHADOW				0x1c
718#define MDIO_REG_GPHY_SHADOW_LED_SEL1			(0x0d << 10)
719#define MDIO_REG_GPHY_SHADOW_LED_SEL2			(0x0e << 10)
720#define MDIO_REG_GPHY_SHADOW_WR_ENA			(0x1 << 15)
721#define MDIO_REG_GPHY_SHADOW_AUTO_DET_MED		(0x1e << 10)
722#define MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD		(0x1 << 8)
723
724typedef elink_status_t(*read_sfp_module_eeprom_func_p) (struct elink_phy * phy,
725							struct elink_params *
726							params,
727							uint8_t dev_addr,
728							uint16_t addr,
729							uint8_t byte_cnt,
730							uint8_t * o_buf,
731							uint8_t);
732/********************************************************/
733#define ELINK_ETH_HLEN			14
734/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
735#define ELINK_ETH_OVREHEAD			(ELINK_ETH_HLEN + 8 + 8)
736#define ELINK_ETH_MIN_PACKET_SIZE		60
737#define ELINK_ETH_MAX_PACKET_SIZE		1500
738#define ELINK_ETH_MAX_JUMBO_PACKET_SIZE	9600
739#define ELINK_MDIO_ACCESS_TIMEOUT		1000
740#define WC_LANE_MAX			4
741#define I2C_SWITCH_WIDTH		2
742#define I2C_BSC0			0
743#define I2C_BSC1			1
744#define I2C_WA_RETRY_CNT		3
745#define I2C_WA_PWR_ITER			(I2C_WA_RETRY_CNT - 1)
746#define MCPR_IMC_COMMAND_READ_OP	1
747#define MCPR_IMC_COMMAND_WRITE_OP	2
748
749/* LED Blink rate that will achieve ~15.9Hz */
750#define LED_BLINK_RATE_VAL_E3		354
751#define LED_BLINK_RATE_VAL_E1X_E2	480
752/***********************************************************/
753/*			Shortcut definitions		   */
754/***********************************************************/
755
756#define ELINK_NIG_LATCH_BC_ENABLE_MI_INT 0
757
758#define ELINK_NIG_STATUS_EMAC0_MI_INT \
759		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
760#define ELINK_NIG_STATUS_XGXS0_LINK10G \
761		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
762#define ELINK_NIG_STATUS_XGXS0_LINK_STATUS \
763		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
764#define ELINK_NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
765		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
766#define ELINK_NIG_STATUS_SERDES0_LINK_STATUS \
767		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
768#define ELINK_NIG_MASK_MI_INT \
769		NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
770#define ELINK_NIG_MASK_XGXS0_LINK10G \
771		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
772#define ELINK_NIG_MASK_XGXS0_LINK_STATUS \
773		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
774#define ELINK_NIG_MASK_SERDES0_LINK_STATUS \
775		NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
776
777#define ELINK_MDIO_AN_CL73_OR_37_COMPLETE \
778		(MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
779		 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
780
781#define ELINK_XGXS_RESET_BITS \
782	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
783	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
784	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
785	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
786	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
787
788#define ELINK_SERDES_RESET_BITS \
789	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
790	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
791	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
792	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
793
794#define ELINK_AUTONEG_CL37		SHARED_HW_CFG_AN_ENABLE_CL37
795#define ELINK_AUTONEG_CL73		SHARED_HW_CFG_AN_ENABLE_CL73
796#define ELINK_AUTONEG_BAM		SHARED_HW_CFG_AN_ENABLE_BAM
797#define ELINK_AUTONEG_PARALLEL \
798				SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
799#define ELINK_AUTONEG_SGMII_FIBER_AUTODET \
800				SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
801#define ELINK_AUTONEG_REMOTE_PHY	SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
802
803#define ELINK_GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
804			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
805#define ELINK_GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
806			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
807#define ELINK_GP_STATUS_SPEED_MASK \
808			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
809#define ELINK_GP_STATUS_10M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
810#define ELINK_GP_STATUS_100M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
811#define ELINK_GP_STATUS_1G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
812#define ELINK_GP_STATUS_2_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
813#define ELINK_GP_STATUS_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
814#define ELINK_GP_STATUS_6G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
815#define ELINK_GP_STATUS_10G_HIG \
816			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
817#define ELINK_GP_STATUS_10G_CX4 \
818			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
819#define ELINK_GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
820#define ELINK_GP_STATUS_10G_KX4 \
821			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
822#define	ELINK_GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
823#define	ELINK_GP_STATUS_10G_XFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
824#define	ELINK_GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
825#define	ELINK_GP_STATUS_10G_SFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
826#define	ELINK_GP_STATUS_20G_KR2 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_KR2
827#define ELINK_LINK_10THD		LINK_STATUS_SPEED_AND_DUPLEX_10THD
828#define ELINK_LINK_10TFD		LINK_STATUS_SPEED_AND_DUPLEX_10TFD
829#define ELINK_LINK_100TXHD		LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
830#define ELINK_LINK_100T4		LINK_STATUS_SPEED_AND_DUPLEX_100T4
831#define ELINK_LINK_100TXFD		LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
832#define ELINK_LINK_1000THD		LINK_STATUS_SPEED_AND_DUPLEX_1000THD
833#define ELINK_LINK_1000TFD		LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
834#define ELINK_LINK_1000XFD		LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
835#define ELINK_LINK_2500THD		LINK_STATUS_SPEED_AND_DUPLEX_2500THD
836#define ELINK_LINK_2500TFD		LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
837#define ELINK_LINK_2500XFD		LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
838#define ELINK_LINK_10GTFD		LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
839#define ELINK_LINK_10GXFD		LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
840#define ELINK_LINK_20GTFD		LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
841#define ELINK_LINK_20GXFD		LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
842
843#define ELINK_LINK_UPDATE_MASK \
844			(LINK_STATUS_SPEED_AND_DUPLEX_MASK | \
845			 LINK_STATUS_LINK_UP | \
846			 LINK_STATUS_PHYSICAL_LINK_FLAG | \
847			 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \
848			 LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \
849			 LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \
850			 LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \
851			 LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \
852			 LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE)
853
854#define ELINK_SFP_EEPROM_CON_TYPE_ADDR		0x2
855#define ELINK_SFP_EEPROM_CON_TYPE_VAL_LC	0x7
856#define ELINK_SFP_EEPROM_CON_TYPE_VAL_COPPER	0x21
857#define ELINK_SFP_EEPROM_CON_TYPE_VAL_RJ45	0x22
858
859#define ELINK_SFP_EEPROM_COMP_CODE_ADDR		0x3
860#define ELINK_SFP_EEPROM_COMP_CODE_SR_MASK	(1<<4)
861#define ELINK_SFP_EEPROM_COMP_CODE_LR_MASK	(1<<5)
862#define ELINK_SFP_EEPROM_COMP_CODE_LRM_MASK	(1<<6)
863
864#define ELINK_SFP_EEPROM_FC_TX_TECH_ADDR		0x8
865#define ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
866#define ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE  0x8
867
868#define ELINK_SFP_EEPROM_OPTIONS_ADDR			0x40
869#define ELINK_SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
870#define ELINK_SFP_EEPROM_OPTIONS_SIZE			2
871
872#define ELINK_EDC_MODE_LINEAR				0x0022
873#define ELINK_EDC_MODE_LIMITING				0x0044
874#define ELINK_EDC_MODE_PASSIVE_DAC			0x0055
875#define ELINK_EDC_MODE_ACTIVE_DAC			0x0066
876
877/* ETS defines*/
878#define DCBX_INVALID_COS					(0xFF)
879
880#define ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND		(0x5000)
881#define ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT		(0x5000)
882#define ELINK_ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS		(1360)
883#define ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS			(2720)
884#define ELINK_ETS_E3B0_PBF_MIN_W_VAL				(10000)
885
886#define ELINK_MAX_PACKET_SIZE					(9700)
887#define MAX_KR_LINK_RETRY				4
888
889/**********************************************************/
890/*                     INTERFACE                          */
891/**********************************************************/
892
893#define CL22_WR_OVER_CL45(_sc, _phy, _bank, _addr, _val) \
894	elink_cl45_write(_sc, _phy, \
895		(_phy)->def_md_devad, \
896		(_bank + (_addr & 0xf)), \
897		_val)
898
899#define CL22_RD_OVER_CL45(_sc, _phy, _bank, _addr, _val) \
900	elink_cl45_read(_sc, _phy, \
901		(_phy)->def_md_devad, \
902		(_bank + (_addr & 0xf)), \
903		_val)
904
905static uint32_t elink_bits_en(struct bnx2x_softc *sc, uint32_t reg, uint32_t bits)
906{
907	uint32_t val = REG_RD(sc, reg);
908
909	val |= bits;
910	REG_WR(sc, reg, val);
911	return val;
912}
913
914static uint32_t elink_bits_dis(struct bnx2x_softc *sc, uint32_t reg,
915			       uint32_t bits)
916{
917	uint32_t val = REG_RD(sc, reg);
918
919	val &= ~bits;
920	REG_WR(sc, reg, val);
921	return val;
922}
923
924/*
925 * elink_check_lfa - This function checks if link reinitialization is required,
926 *                   or link flap can be avoided.
927 *
928 * @params:	link parameters
929 * Returns 0 if Link Flap Avoidance conditions are met otherwise, the failed
930 *         condition code.
931 */
932static int elink_check_lfa(struct elink_params *params)
933{
934	uint32_t link_status, cfg_idx, lfa_mask, cfg_size;
935	uint32_t cur_speed_cap_mask, cur_req_fc_auto_adv, additional_config;
936	uint32_t saved_val, req_val, eee_status;
937	struct bnx2x_softc *sc = params->sc;
938
939	additional_config =
940	    REG_RD(sc, params->lfa_base +
941		   offsetof(struct shmem_lfa, additional_config));
942
943	/* NOTE: must be first condition checked -
944	 * to verify DCC bit is cleared in any case!
945	 */
946	if (additional_config & NO_LFA_DUE_TO_DCC_MASK) {
947		PMD_DRV_LOG(DEBUG, "No LFA due to DCC flap after clp exit");
948		REG_WR(sc, params->lfa_base +
949		       offsetof(struct shmem_lfa, additional_config),
950		       additional_config & ~NO_LFA_DUE_TO_DCC_MASK);
951		return LFA_DCC_LFA_DISABLED;
952	}
953
954	/* Verify that link is up */
955	link_status = REG_RD(sc, params->shmem_base +
956			     offsetof(struct shmem_region,
957				      port_mb[params->port].link_status));
958	if (!(link_status & LINK_STATUS_LINK_UP))
959		return LFA_LINK_DOWN;
960
961	/* if loaded after BOOT from SAN, don't flap the link in any case and
962	 * rely on link set by preboot driver
963	 */
964	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_BOOT_FROM_SAN)
965		return 0;
966
967	/* Verify that loopback mode is not set */
968	if (params->loopback_mode)
969		return LFA_LOOPBACK_ENABLED;
970
971	/* Verify that MFW supports LFA */
972	if (!params->lfa_base)
973		return LFA_MFW_IS_TOO_OLD;
974
975	if (params->num_phys == 3) {
976		cfg_size = 2;
977		lfa_mask = 0xffffffff;
978	} else {
979		cfg_size = 1;
980		lfa_mask = 0xffff;
981	}
982
983	/* Compare Duplex */
984	saved_val = REG_RD(sc, params->lfa_base +
985			   offsetof(struct shmem_lfa, req_duplex));
986	req_val = params->req_duplex[0] | (params->req_duplex[1] << 16);
987	if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
988		PMD_DRV_LOG(INFO, "Duplex mismatch %x vs. %x",
989			    (saved_val & lfa_mask), (req_val & lfa_mask));
990		return LFA_DUPLEX_MISMATCH;
991	}
992	/* Compare Flow Control */
993	saved_val = REG_RD(sc, params->lfa_base +
994			   offsetof(struct shmem_lfa, req_flow_ctrl));
995	req_val = params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16);
996	if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
997		PMD_DRV_LOG(DEBUG, "Flow control mismatch %x vs. %x",
998			    (saved_val & lfa_mask), (req_val & lfa_mask));
999		return LFA_FLOW_CTRL_MISMATCH;
1000	}
1001	/* Compare Link Speed */
1002	saved_val = REG_RD(sc, params->lfa_base +
1003			   offsetof(struct shmem_lfa, req_line_speed));
1004	req_val = params->req_line_speed[0] | (params->req_line_speed[1] << 16);
1005	if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
1006		PMD_DRV_LOG(DEBUG, "Link speed mismatch %x vs. %x",
1007			    (saved_val & lfa_mask), (req_val & lfa_mask));
1008		return LFA_LINK_SPEED_MISMATCH;
1009	}
1010
1011	for (cfg_idx = 0; cfg_idx < cfg_size; cfg_idx++) {
1012		cur_speed_cap_mask = REG_RD(sc, params->lfa_base +
1013					    offsetof(struct shmem_lfa,
1014						     speed_cap_mask[cfg_idx]));
1015
1016		if (cur_speed_cap_mask != params->speed_cap_mask[cfg_idx]) {
1017			PMD_DRV_LOG(DEBUG, "Speed Cap mismatch %x vs. %x",
1018				    cur_speed_cap_mask,
1019				    params->speed_cap_mask[cfg_idx]);
1020			return LFA_SPEED_CAP_MISMATCH;
1021		}
1022	}
1023
1024	cur_req_fc_auto_adv =
1025	    REG_RD(sc, params->lfa_base +
1026		   offsetof(struct shmem_lfa, additional_config)) &
1027	    REQ_FC_AUTO_ADV_MASK;
1028
1029	if ((uint16_t) cur_req_fc_auto_adv != params->req_fc_auto_adv) {
1030		PMD_DRV_LOG(DEBUG, "Flow Ctrl AN mismatch %x vs. %x",
1031			    cur_req_fc_auto_adv, params->req_fc_auto_adv);
1032		return LFA_FLOW_CTRL_MISMATCH;
1033	}
1034
1035	eee_status = REG_RD(sc, params->shmem2_base +
1036			    offsetof(struct shmem2_region,
1037				     eee_status[params->port]));
1038
1039	if (((eee_status & SHMEM_EEE_LPI_REQUESTED_BIT) ^
1040	     (params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)) ||
1041	    ((eee_status & SHMEM_EEE_REQUESTED_BIT) ^
1042	     (params->eee_mode & ELINK_EEE_MODE_ADV_LPI))) {
1043		PMD_DRV_LOG(DEBUG, "EEE mismatch %x vs. %x", params->eee_mode,
1044			    eee_status);
1045		return LFA_EEE_MISMATCH;
1046	}
1047
1048	/* LFA conditions are met */
1049	return 0;
1050}
1051
1052/******************************************************************/
1053/*			EPIO/GPIO section			  */
1054/******************************************************************/
1055static void elink_get_epio(struct bnx2x_softc *sc, uint32_t epio_pin,
1056			   uint32_t * en)
1057{
1058	uint32_t epio_mask, gp_oenable;
1059	*en = 0;
1060	/* Sanity check */
1061	if (epio_pin > 31) {
1062		PMD_DRV_LOG(DEBUG, "Invalid EPIO pin %d to get", epio_pin);
1063		return;
1064	}
1065
1066	epio_mask = 1 << epio_pin;
1067	/* Set this EPIO to output */
1068	gp_oenable = REG_RD(sc, MCP_REG_MCPR_GP_OENABLE);
1069	REG_WR(sc, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask);
1070
1071	*en = (REG_RD(sc, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin;
1072}
1073
1074static void elink_set_epio(struct bnx2x_softc *sc, uint32_t epio_pin, uint32_t en)
1075{
1076	uint32_t epio_mask, gp_output, gp_oenable;
1077
1078	/* Sanity check */
1079	if (epio_pin > 31) {
1080		PMD_DRV_LOG(DEBUG, "Invalid EPIO pin %d to set", epio_pin);
1081		return;
1082	}
1083	PMD_DRV_LOG(DEBUG, "Setting EPIO pin %d to %d", epio_pin, en);
1084	epio_mask = 1 << epio_pin;
1085	/* Set this EPIO to output */
1086	gp_output = REG_RD(sc, MCP_REG_MCPR_GP_OUTPUTS);
1087	if (en)
1088		gp_output |= epio_mask;
1089	else
1090		gp_output &= ~epio_mask;
1091
1092	REG_WR(sc, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
1093
1094	/* Set the value for this EPIO */
1095	gp_oenable = REG_RD(sc, MCP_REG_MCPR_GP_OENABLE);
1096	REG_WR(sc, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
1097}
1098
1099static void elink_set_cfg_pin(struct bnx2x_softc *sc, uint32_t pin_cfg,
1100			      uint32_t val)
1101{
1102	if (pin_cfg == PIN_CFG_NA)
1103		return;
1104	if (pin_cfg >= PIN_CFG_EPIO0) {
1105		elink_set_epio(sc, pin_cfg - PIN_CFG_EPIO0, val);
1106	} else {
1107		uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
1108		uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
1109		elink_cb_gpio_write(sc, gpio_num, (uint8_t) val, gpio_port);
1110	}
1111}
1112
1113static uint32_t elink_get_cfg_pin(struct bnx2x_softc *sc, uint32_t pin_cfg,
1114				  uint32_t * val)
1115{
1116	if (pin_cfg == PIN_CFG_NA)
1117		return ELINK_STATUS_ERROR;
1118	if (pin_cfg >= PIN_CFG_EPIO0) {
1119		elink_get_epio(sc, pin_cfg - PIN_CFG_EPIO0, val);
1120	} else {
1121		uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
1122		uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
1123		*val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
1124	}
1125	return ELINK_STATUS_OK;
1126
1127}
1128
1129/******************************************************************/
1130/*			PFC section				  */
1131/******************************************************************/
1132static void elink_update_pfc_xmac(struct elink_params *params,
1133				  struct elink_vars *vars)
1134{
1135	struct bnx2x_softc *sc = params->sc;
1136	uint32_t xmac_base;
1137	uint32_t pause_val, pfc0_val, pfc1_val;
1138
1139	/* XMAC base adrr */
1140	xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1141
1142	/* Initialize pause and pfc registers */
1143	pause_val = 0x18000;
1144	pfc0_val = 0xFFFF8000;
1145	pfc1_val = 0x2;
1146
1147	/* No PFC support */
1148	if (!(params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)) {
1149
1150		/* RX flow control - Process pause frame in receive direction
1151		 */
1152		if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
1153			pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
1154
1155		/* TX flow control - Send pause packet when buffer is full */
1156		if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
1157			pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
1158	} else {		/* PFC support */
1159		pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
1160		    XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
1161		    XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
1162		    XMAC_PFC_CTRL_HI_REG_TX_PFC_EN |
1163		    XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
1164		/* Write pause and PFC registers */
1165		REG_WR(sc, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
1166		REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
1167		REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
1168		pfc1_val &= ~XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
1169
1170	}
1171
1172	/* Write pause and PFC registers */
1173	REG_WR(sc, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
1174	REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
1175	REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
1176
1177	/* Set MAC address for source TX Pause/PFC frames */
1178	REG_WR(sc, xmac_base + XMAC_REG_CTRL_SA_LO,
1179	       ((params->mac_addr[2] << 24) |
1180		(params->mac_addr[3] << 16) |
1181		(params->mac_addr[4] << 8) | (params->mac_addr[5])));
1182	REG_WR(sc, xmac_base + XMAC_REG_CTRL_SA_HI,
1183	       ((params->mac_addr[0] << 8) | (params->mac_addr[1])));
1184
1185	DELAY(30);
1186}
1187
1188/******************************************************************/
1189/*			MAC/PBF section				  */
1190/******************************************************************/
1191static void elink_set_mdio_clk(struct bnx2x_softc *sc, uint32_t emac_base)
1192{
1193	uint32_t new_mode, cur_mode;
1194	uint32_t clc_cnt;
1195	/* Set clause 45 mode, slow down the MDIO clock to 2.5MHz
1196	 * (a value of 49==0x31) and make sure that the AUTO poll is off
1197	 */
1198	cur_mode = REG_RD(sc, emac_base + EMAC_REG_EMAC_MDIO_MODE);
1199
1200	if (USES_WARPCORE(sc))
1201		clc_cnt = 74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
1202	else
1203		clc_cnt = 49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
1204
1205	if (((cur_mode & EMAC_MDIO_MODE_CLOCK_CNT) == clc_cnt) &&
1206	    (cur_mode & (EMAC_MDIO_MODE_CLAUSE_45)))
1207		return;
1208
1209	new_mode = cur_mode &
1210	    ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
1211	new_mode |= clc_cnt;
1212	new_mode |= (EMAC_MDIO_MODE_CLAUSE_45);
1213
1214	PMD_DRV_LOG(DEBUG, "Changing emac_mode from 0x%x to 0x%x",
1215		    cur_mode, new_mode);
1216	REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_MODE, new_mode);
1217	DELAY(40);
1218}
1219
1220static void elink_set_mdio_emac_per_phy(struct bnx2x_softc *sc,
1221					struct elink_params *params)
1222{
1223	uint8_t phy_index;
1224	/* Set mdio clock per phy */
1225	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
1226	     phy_index++)
1227		elink_set_mdio_clk(sc, params->phy[phy_index].mdio_ctrl);
1228}
1229
1230static uint8_t elink_is_4_port_mode(struct bnx2x_softc *sc)
1231{
1232	uint32_t port4mode_ovwr_val;
1233	/* Check 4-port override enabled */
1234	port4mode_ovwr_val = REG_RD(sc, MISC_REG_PORT4MODE_EN_OVWR);
1235	if (port4mode_ovwr_val & (1 << 0)) {
1236		/* Return 4-port mode override value */
1237		return (port4mode_ovwr_val & (1 << 1)) == (1 << 1);
1238	}
1239	/* Return 4-port mode from input pin */
1240	return (uint8_t) REG_RD(sc, MISC_REG_PORT4MODE_EN);
1241}
1242
1243static void elink_emac_init(struct elink_params *params)
1244{
1245	/* reset and unreset the emac core */
1246	struct bnx2x_softc *sc = params->sc;
1247	uint8_t port = params->port;
1248	uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1249	uint32_t val;
1250	uint16_t timeout;
1251
1252	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1253	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1254	DELAY(5);
1255	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1256	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1257
1258	/* init emac - use read-modify-write */
1259	/* self clear reset */
1260	val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
1261	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE,
1262			   (val | EMAC_MODE_RESET));
1263
1264	timeout = 200;
1265	do {
1266		val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
1267		PMD_DRV_LOG(DEBUG, "EMAC reset reg is %u", val);
1268		if (!timeout) {
1269			PMD_DRV_LOG(DEBUG, "EMAC timeout!");
1270			return;
1271		}
1272		timeout--;
1273	} while (val & EMAC_MODE_RESET);
1274
1275	elink_set_mdio_emac_per_phy(sc, params);
1276	/* Set mac address */
1277	val = ((params->mac_addr[0] << 8) | params->mac_addr[1]);
1278	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MAC_MATCH, val);
1279
1280	val = ((params->mac_addr[2] << 24) |
1281	       (params->mac_addr[3] << 16) |
1282	       (params->mac_addr[4] << 8) | params->mac_addr[5]);
1283	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MAC_MATCH + 4, val);
1284}
1285
1286static void elink_set_xumac_nig(struct elink_params *params,
1287				uint16_t tx_pause_en, uint8_t enable)
1288{
1289	struct bnx2x_softc *sc = params->sc;
1290
1291	REG_WR(sc, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
1292	       enable);
1293	REG_WR(sc, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
1294	       enable);
1295	REG_WR(sc, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
1296	       NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
1297}
1298
1299static void elink_set_umac_rxtx(struct elink_params *params, uint8_t en)
1300{
1301	uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1302	uint32_t val;
1303	struct bnx2x_softc *sc = params->sc;
1304	if (!(REG_RD(sc, MISC_REG_RESET_REG_2) &
1305	      (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)))
1306		return;
1307	val = REG_RD(sc, umac_base + UMAC_REG_COMMAND_CONFIG);
1308	if (en)
1309		val |= (UMAC_COMMAND_CONFIG_REG_TX_ENA |
1310			UMAC_COMMAND_CONFIG_REG_RX_ENA);
1311	else
1312		val &= ~(UMAC_COMMAND_CONFIG_REG_TX_ENA |
1313			 UMAC_COMMAND_CONFIG_REG_RX_ENA);
1314	/* Disable RX and TX */
1315	REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1316}
1317
1318static void elink_umac_enable(struct elink_params *params,
1319			      struct elink_vars *vars, uint8_t lb)
1320{
1321	uint32_t val;
1322	uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1323	struct bnx2x_softc *sc = params->sc;
1324	/* Reset UMAC */
1325	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1326	       (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1327	DELAY(1000 * 1);
1328
1329	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1330	       (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1331
1332	PMD_DRV_LOG(DEBUG, "enabling UMAC");
1333
1334	/* This register opens the gate for the UMAC despite its name */
1335	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port * 4, 1);
1336
1337	val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
1338	    UMAC_COMMAND_CONFIG_REG_PAD_EN |
1339	    UMAC_COMMAND_CONFIG_REG_SW_RESET |
1340	    UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
1341	switch (vars->line_speed) {
1342	case ELINK_SPEED_10:
1343		val |= (0 << 2);
1344		break;
1345	case ELINK_SPEED_100:
1346		val |= (1 << 2);
1347		break;
1348	case ELINK_SPEED_1000:
1349		val |= (2 << 2);
1350		break;
1351	case ELINK_SPEED_2500:
1352		val |= (3 << 2);
1353		break;
1354	default:
1355		PMD_DRV_LOG(DEBUG, "Invalid speed for UMAC %d",
1356			    vars->line_speed);
1357		break;
1358	}
1359	if (!(vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
1360		val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE;
1361
1362	if (!(vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
1363		val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
1364
1365	if (vars->duplex == DUPLEX_HALF)
1366		val |= UMAC_COMMAND_CONFIG_REG_HD_ENA;
1367
1368	REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1369	DELAY(50);
1370
1371	/* Configure UMAC for EEE */
1372	if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
1373		PMD_DRV_LOG(DEBUG, "configured UMAC for EEE");
1374		REG_WR(sc, umac_base + UMAC_REG_UMAC_EEE_CTRL,
1375		       UMAC_UMAC_EEE_CTRL_REG_EEE_EN);
1376		REG_WR(sc, umac_base + UMAC_REG_EEE_WAKE_TIMER, 0x11);
1377	} else {
1378		REG_WR(sc, umac_base + UMAC_REG_UMAC_EEE_CTRL, 0x0);
1379	}
1380
1381	/* Set MAC address for source TX Pause/PFC frames (under SW reset) */
1382	REG_WR(sc, umac_base + UMAC_REG_MAC_ADDR0,
1383	       ((params->mac_addr[2] << 24) |
1384		(params->mac_addr[3] << 16) |
1385		(params->mac_addr[4] << 8) | (params->mac_addr[5])));
1386	REG_WR(sc, umac_base + UMAC_REG_MAC_ADDR1,
1387	       ((params->mac_addr[0] << 8) | (params->mac_addr[1])));
1388
1389	/* Enable RX and TX */
1390	val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
1391	val |= UMAC_COMMAND_CONFIG_REG_TX_ENA | UMAC_COMMAND_CONFIG_REG_RX_ENA;
1392	REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1393	DELAY(50);
1394
1395	/* Remove SW Reset */
1396	val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
1397
1398	/* Check loopback mode */
1399	if (lb)
1400		val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
1401	REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1402
1403	/* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
1404	 * length used by the MAC receive logic to check frames.
1405	 */
1406	REG_WR(sc, umac_base + UMAC_REG_MAXFR, 0x2710);
1407	elink_set_xumac_nig(params,
1408			    ((vars->flow_ctrl & ELINK_FLOW_CTRL_TX) != 0), 1);
1409	vars->mac_type = ELINK_MAC_TYPE_UMAC;
1410
1411}
1412
1413/* Define the XMAC mode */
1414static void elink_xmac_init(struct elink_params *params, uint32_t max_speed)
1415{
1416	struct bnx2x_softc *sc = params->sc;
1417	uint32_t is_port4mode = elink_is_4_port_mode(sc);
1418
1419	/* In 4-port mode, need to set the mode only once, so if XMAC is
1420	 * already out of reset, it means the mode has already been set,
1421	 * and it must not* reset the XMAC again, since it controls both
1422	 * ports of the path
1423	 */
1424
1425	if (((CHIP_NUM(sc) == CHIP_NUM_57840_4_10) ||
1426	     (CHIP_NUM(sc) == CHIP_NUM_57840_2_20) ||
1427	     (CHIP_NUM(sc) == CHIP_NUM_57840_OBS)) &&
1428	    is_port4mode &&
1429	    (REG_RD(sc, MISC_REG_RESET_REG_2) &
1430	     MISC_REGISTERS_RESET_REG_2_XMAC)) {
1431		PMD_DRV_LOG(DEBUG, "XMAC already out of reset in 4-port mode");
1432		return;
1433	}
1434
1435	/* Hard reset */
1436	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1437	       MISC_REGISTERS_RESET_REG_2_XMAC);
1438	DELAY(1000 * 1);
1439
1440	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1441	       MISC_REGISTERS_RESET_REG_2_XMAC);
1442	if (is_port4mode) {
1443		PMD_DRV_LOG(DEBUG, "Init XMAC to 2 ports x 10G per path");
1444
1445		/* Set the number of ports on the system side to up to 2 */
1446		REG_WR(sc, MISC_REG_XMAC_CORE_PORT_MODE, 1);
1447
1448		/* Set the number of ports on the Warp Core to 10G */
1449		REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1450	} else {
1451		/* Set the number of ports on the system side to 1 */
1452		REG_WR(sc, MISC_REG_XMAC_CORE_PORT_MODE, 0);
1453		if (max_speed == ELINK_SPEED_10000) {
1454			PMD_DRV_LOG(DEBUG,
1455				    "Init XMAC to 10G x 1 port per path");
1456			/* Set the number of ports on the Warp Core to 10G */
1457			REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1458		} else {
1459			PMD_DRV_LOG(DEBUG,
1460				    "Init XMAC to 20G x 2 ports per path");
1461			/* Set the number of ports on the Warp Core to 20G */
1462			REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 1);
1463		}
1464	}
1465	/* Soft reset */
1466	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1467	       MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1468	DELAY(1000 * 1);
1469
1470	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1471	       MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1472
1473}
1474
1475static void elink_set_xmac_rxtx(struct elink_params *params, uint8_t en)
1476{
1477	uint8_t port = params->port;
1478	struct bnx2x_softc *sc = params->sc;
1479	uint32_t pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1480	uint32_t val;
1481
1482	if (REG_RD(sc, MISC_REG_RESET_REG_2) & MISC_REGISTERS_RESET_REG_2_XMAC) {
1483		/* Send an indication to change the state in the NIG back to XON
1484		 * Clearing this bit enables the next set of this bit to get
1485		 * rising edge
1486		 */
1487		pfc_ctrl = REG_RD(sc, xmac_base + XMAC_REG_PFC_CTRL_HI);
1488		REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI,
1489		       (pfc_ctrl & ~(1 << 1)));
1490		REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI,
1491		       (pfc_ctrl | (1 << 1)));
1492		PMD_DRV_LOG(DEBUG, "Disable XMAC on port %x", port);
1493		val = REG_RD(sc, xmac_base + XMAC_REG_CTRL);
1494		if (en)
1495			val |= (XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
1496		else
1497			val &= ~(XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
1498		REG_WR(sc, xmac_base + XMAC_REG_CTRL, val);
1499	}
1500}
1501
1502static elink_status_t elink_xmac_enable(struct elink_params *params,
1503					struct elink_vars *vars, uint8_t lb)
1504{
1505	uint32_t val, xmac_base;
1506	struct bnx2x_softc *sc = params->sc;
1507	PMD_DRV_LOG(DEBUG, "enabling XMAC");
1508
1509	xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1510
1511	elink_xmac_init(params, vars->line_speed);
1512
1513	/* This register determines on which events the MAC will assert
1514	 * error on the i/f to the NIG along w/ EOP.
1515	 */
1516
1517	/* This register tells the NIG whether to send traffic to UMAC
1518	 * or XMAC
1519	 */
1520	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port * 4, 0);
1521
1522	/* When XMAC is in XLGMII mode, disable sending idles for fault
1523	 * detection.
1524	 */
1525	if (!(params->phy[ELINK_INT_PHY].flags & ELINK_FLAGS_TX_ERROR_CHECK)) {
1526		REG_WR(sc, xmac_base + XMAC_REG_RX_LSS_CTRL,
1527		       (XMAC_RX_LSS_CTRL_REG_LOCAL_FAULT_DISABLE |
1528			XMAC_RX_LSS_CTRL_REG_REMOTE_FAULT_DISABLE));
1529		REG_WR(sc, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
1530		REG_WR(sc, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
1531		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
1532		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
1533	}
1534	/* Set Max packet size */
1535	REG_WR(sc, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
1536
1537	/* CRC append for Tx packets */
1538	REG_WR(sc, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
1539
1540	/* update PFC */
1541	elink_update_pfc_xmac(params, vars);
1542
1543	if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
1544		PMD_DRV_LOG(DEBUG, "Setting XMAC for EEE");
1545		REG_WR(sc, xmac_base + XMAC_REG_EEE_TIMERS_HI, 0x1380008);
1546		REG_WR(sc, xmac_base + XMAC_REG_EEE_CTRL, 0x1);
1547	} else {
1548		REG_WR(sc, xmac_base + XMAC_REG_EEE_CTRL, 0x0);
1549	}
1550
1551	/* Enable TX and RX */
1552	val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
1553
1554	/* Set MAC in XLGMII mode for dual-mode */
1555	if ((vars->line_speed == ELINK_SPEED_20000) &&
1556	    (params->phy[ELINK_INT_PHY].supported &
1557	     ELINK_SUPPORTED_20000baseKR2_Full))
1558		val |= XMAC_CTRL_REG_XLGMII_ALIGN_ENB;
1559
1560	/* Check loopback mode */
1561	if (lb)
1562		val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK;
1563	REG_WR(sc, xmac_base + XMAC_REG_CTRL, val);
1564	elink_set_xumac_nig(params,
1565			    ((vars->flow_ctrl & ELINK_FLOW_CTRL_TX) != 0), 1);
1566
1567	vars->mac_type = ELINK_MAC_TYPE_XMAC;
1568
1569	return ELINK_STATUS_OK;
1570}
1571
1572static elink_status_t elink_emac_enable(struct elink_params *params,
1573					struct elink_vars *vars, uint8_t lb)
1574{
1575	struct bnx2x_softc *sc = params->sc;
1576	uint8_t port = params->port;
1577	uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1578	uint32_t val;
1579
1580	PMD_DRV_LOG(DEBUG, "enabling EMAC");
1581
1582	/* Disable BMAC */
1583	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1584	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1585
1586	/* enable emac and not bmac */
1587	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + port * 4, 1);
1588
1589#ifdef ELINK_INCLUDE_EMUL
1590	/* for paladium */
1591	if (CHIP_REV_IS_EMUL(sc)) {
1592		/* Use lane 1 (of lanes 0-3) */
1593		REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, 1);
1594		REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 1);
1595	}
1596	/* for fpga */
1597	else
1598#endif
1599#ifdef ELINK_INCLUDE_FPGA
1600	if (CHIP_REV_IS_FPGA(sc)) {
1601		/* Use lane 1 (of lanes 0-3) */
1602		PMD_DRV_LOG(DEBUG, "elink_emac_enable: Setting FPGA");
1603
1604		REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, 1);
1605		REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 0);
1606	} else
1607#endif
1608		/* ASIC */
1609	if (vars->phy_flags & PHY_XGXS_FLAG) {
1610		uint32_t ser_lane = ((params->lane_config &
1611				      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1612				     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1613
1614		PMD_DRV_LOG(DEBUG, "XGXS");
1615		/* select the master lanes (out of 0-3) */
1616		REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, ser_lane);
1617		/* select XGXS */
1618		REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 1);
1619
1620	} else {		/* SerDes */
1621		PMD_DRV_LOG(DEBUG, "SerDes");
1622		/* select SerDes */
1623		REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 0);
1624	}
1625
1626	elink_bits_en(sc, emac_base + EMAC_REG_EMAC_RX_MODE,
1627		      EMAC_RX_MODE_RESET);
1628	elink_bits_en(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
1629		      EMAC_TX_MODE_RESET);
1630
1631#if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
1632	if (CHIP_REV_IS_SLOW(sc)) {
1633		/* config GMII mode */
1634		val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
1635		elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE,
1636				   (val | EMAC_MODE_PORT_GMII));
1637	} else {		/* ASIC */
1638#endif
1639		/* pause enable/disable */
1640		elink_bits_dis(sc, emac_base + EMAC_REG_EMAC_RX_MODE,
1641			       EMAC_RX_MODE_FLOW_EN);
1642
1643		elink_bits_dis(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
1644			       (EMAC_TX_MODE_EXT_PAUSE_EN |
1645				EMAC_TX_MODE_FLOW_EN));
1646		if (!(params->feature_config_flags &
1647		      ELINK_FEATURE_CONFIG_PFC_ENABLED)) {
1648			if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
1649				elink_bits_en(sc, emac_base +
1650					      EMAC_REG_EMAC_RX_MODE,
1651					      EMAC_RX_MODE_FLOW_EN);
1652
1653			if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
1654				elink_bits_en(sc, emac_base +
1655					      EMAC_REG_EMAC_TX_MODE,
1656					      (EMAC_TX_MODE_EXT_PAUSE_EN |
1657					       EMAC_TX_MODE_FLOW_EN));
1658		} else
1659			elink_bits_en(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
1660				      EMAC_TX_MODE_FLOW_EN);
1661#if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
1662	}
1663#endif
1664
1665	/* KEEP_VLAN_TAG, promiscuous */
1666	val = REG_RD(sc, emac_base + EMAC_REG_EMAC_RX_MODE);
1667	val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
1668
1669	/* Setting this bit causes MAC control frames (except for pause
1670	 * frames) to be passed on for processing. This setting has no
1671	 * affect on the operation of the pause frames. This bit effects
1672	 * all packets regardless of RX Parser packet sorting logic.
1673	 * Turn the PFC off to make sure we are in Xon state before
1674	 * enabling it.
1675	 */
1676	elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_MODE, 0);
1677	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED) {
1678		PMD_DRV_LOG(DEBUG, "PFC is enabled");
1679		/* Enable PFC again */
1680		elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_MODE,
1681				   EMAC_REG_RX_PFC_MODE_RX_EN |
1682				   EMAC_REG_RX_PFC_MODE_TX_EN |
1683				   EMAC_REG_RX_PFC_MODE_PRIORITIES);
1684
1685		elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_PARAM,
1686				   ((0x0101 <<
1687				     EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
1688				    (0x00ff <<
1689				     EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
1690		val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
1691	}
1692	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_RX_MODE, val);
1693
1694	/* Set Loopback */
1695	val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
1696	if (lb)
1697		val |= 0x810;
1698	else
1699		val &= ~0x810;
1700	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE, val);
1701
1702	/* Enable emac */
1703	REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port * 4, 1);
1704
1705	/* Enable emac for jumbo packets */
1706	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_RX_MTU_SIZE,
1707			   (EMAC_RX_MTU_SIZE_JUMBO_ENA |
1708			    (ELINK_ETH_MAX_JUMBO_PACKET_SIZE +
1709			     ELINK_ETH_OVREHEAD)));
1710
1711	/* Strip CRC */
1712	REG_WR(sc, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port * 4, 0x1);
1713
1714	/* Disable the NIG in/out to the bmac */
1715	REG_WR(sc, NIG_REG_BMAC0_IN_EN + port * 4, 0x0);
1716	REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + port * 4, 0x0);
1717	REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port * 4, 0x0);
1718
1719	/* Enable the NIG in/out to the emac */
1720	REG_WR(sc, NIG_REG_EMAC0_IN_EN + port * 4, 0x1);
1721	val = 0;
1722	if ((params->feature_config_flags &
1723	     ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
1724	    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
1725		val = 1;
1726
1727	REG_WR(sc, NIG_REG_EMAC0_PAUSE_OUT_EN + port * 4, val);
1728	REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port * 4, 0x1);
1729
1730#ifdef ELINK_INCLUDE_EMUL
1731	if (CHIP_REV_IS_EMUL(sc)) {
1732		/* Take the BigMac out of reset */
1733		REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1734		       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1735
1736		/* Enable access for bmac registers */
1737		REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port * 4, 0x1);
1738	} else
1739#endif
1740		REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port * 4, 0x0);
1741
1742	vars->mac_type = ELINK_MAC_TYPE_EMAC;
1743	return ELINK_STATUS_OK;
1744}
1745
1746static void elink_update_pfc_bmac1(struct elink_params *params,
1747				   struct elink_vars *vars)
1748{
1749	uint32_t wb_data[2];
1750	struct bnx2x_softc *sc = params->sc;
1751	uint32_t bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1752	    NIG_REG_INGRESS_BMAC0_MEM;
1753
1754	uint32_t val = 0x14;
1755	if ((!(params->feature_config_flags &
1756	       ELINK_FEATURE_CONFIG_PFC_ENABLED)) &&
1757	    (vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
1758		/* Enable BigMAC to react on received Pause packets */
1759		val |= (1 << 5);
1760	wb_data[0] = val;
1761	wb_data[1] = 0;
1762	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
1763
1764	/* TX control */
1765	val = 0xc0;
1766	if (!(params->feature_config_flags &
1767	      ELINK_FEATURE_CONFIG_PFC_ENABLED) &&
1768	    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
1769		val |= 0x800000;
1770	wb_data[0] = val;
1771	wb_data[1] = 0;
1772	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
1773}
1774
1775static void elink_update_pfc_bmac2(struct elink_params *params,
1776				   struct elink_vars *vars, uint8_t is_lb)
1777{
1778	/* Set rx control: Strip CRC and enable BigMAC to relay
1779	 * control packets to the system as well
1780	 */
1781	uint32_t wb_data[2];
1782	struct bnx2x_softc *sc = params->sc;
1783	uint32_t bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1784	    NIG_REG_INGRESS_BMAC0_MEM;
1785	uint32_t val = 0x14;
1786
1787	if ((!(params->feature_config_flags &
1788	       ELINK_FEATURE_CONFIG_PFC_ENABLED)) &&
1789	    (vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
1790		/* Enable BigMAC to react on received Pause packets */
1791		val |= (1 << 5);
1792	wb_data[0] = val;
1793	wb_data[1] = 0;
1794	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
1795	DELAY(30);
1796
1797	/* Tx control */
1798	val = 0xc0;
1799	if (!(params->feature_config_flags &
1800	      ELINK_FEATURE_CONFIG_PFC_ENABLED) &&
1801	    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
1802		val |= 0x800000;
1803	wb_data[0] = val;
1804	wb_data[1] = 0;
1805	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
1806
1807	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED) {
1808		PMD_DRV_LOG(DEBUG, "PFC is enabled");
1809		/* Enable PFC RX & TX & STATS and set 8 COS  */
1810		wb_data[0] = 0x0;
1811		wb_data[0] |= (1 << 0);	/* RX */
1812		wb_data[0] |= (1 << 1);	/* TX */
1813		wb_data[0] |= (1 << 2);	/* Force initial Xon */
1814		wb_data[0] |= (1 << 3);	/* 8 cos */
1815		wb_data[0] |= (1 << 5);	/* STATS */
1816		wb_data[1] = 0;
1817		REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
1818			    wb_data, 2);
1819		/* Clear the force Xon */
1820		wb_data[0] &= ~(1 << 2);
1821	} else {
1822		PMD_DRV_LOG(DEBUG, "PFC is disabled");
1823		/* Disable PFC RX & TX & STATS and set 8 COS */
1824		wb_data[0] = 0x8;
1825		wb_data[1] = 0;
1826	}
1827
1828	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
1829
1830	/* Set Time (based unit is 512 bit time) between automatic
1831	 * re-sending of PP packets amd enable automatic re-send of
1832	 * Per-Priroity Packet as long as pp_gen is asserted and
1833	 * pp_disable is low.
1834	 */
1835	val = 0x8000;
1836	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
1837		val |= (1 << 16);	/* enable automatic re-send */
1838
1839	wb_data[0] = val;
1840	wb_data[1] = 0;
1841	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
1842		    wb_data, 2);
1843
1844	/* mac control */
1845	val = 0x3;		/* Enable RX and TX */
1846	if (is_lb) {
1847		val |= 0x4;	/* Local loopback */
1848		PMD_DRV_LOG(DEBUG, "enable bmac loopback");
1849	}
1850	/* When PFC enabled, Pass pause frames towards the NIG. */
1851	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
1852		val |= ((1 << 6) | (1 << 5));
1853
1854	wb_data[0] = val;
1855	wb_data[1] = 0;
1856	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
1857}
1858
1859/******************************************************************************
1860* Description:
1861*  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
1862*  not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
1863******************************************************************************/
1864static elink_status_t elink_pfc_nig_rx_priority_mask(struct bnx2x_softc *sc,
1865						     uint8_t cos_entry,
1866						     uint32_t priority_mask,
1867						     uint8_t port)
1868{
1869	uint32_t nig_reg_rx_priority_mask_add = 0;
1870
1871	switch (cos_entry) {
1872	case 0:
1873		nig_reg_rx_priority_mask_add = (port) ?
1874		    NIG_REG_P1_RX_COS0_PRIORITY_MASK :
1875		    NIG_REG_P0_RX_COS0_PRIORITY_MASK;
1876		break;
1877	case 1:
1878		nig_reg_rx_priority_mask_add = (port) ?
1879		    NIG_REG_P1_RX_COS1_PRIORITY_MASK :
1880		    NIG_REG_P0_RX_COS1_PRIORITY_MASK;
1881		break;
1882	case 2:
1883		nig_reg_rx_priority_mask_add = (port) ?
1884		    NIG_REG_P1_RX_COS2_PRIORITY_MASK :
1885		    NIG_REG_P0_RX_COS2_PRIORITY_MASK;
1886		break;
1887	case 3:
1888		if (port)
1889			return ELINK_STATUS_ERROR;
1890		nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
1891		break;
1892	case 4:
1893		if (port)
1894			return ELINK_STATUS_ERROR;
1895		nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
1896		break;
1897	case 5:
1898		if (port)
1899			return ELINK_STATUS_ERROR;
1900		nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
1901		break;
1902	}
1903
1904	REG_WR(sc, nig_reg_rx_priority_mask_add, priority_mask);
1905
1906	return ELINK_STATUS_OK;
1907}
1908
1909static void elink_update_mng(struct elink_params *params, uint32_t link_status)
1910{
1911	struct bnx2x_softc *sc = params->sc;
1912
1913	REG_WR(sc, params->shmem_base +
1914	       offsetof(struct shmem_region,
1915			port_mb[params->port].link_status), link_status);
1916}
1917
1918static void elink_update_link_attr(struct elink_params *params,
1919				   uint32_t link_attr)
1920{
1921	struct bnx2x_softc *sc = params->sc;
1922
1923	if (SHMEM2_HAS(sc, link_attr_sync))
1924		REG_WR(sc, params->shmem2_base +
1925		       offsetof(struct shmem2_region,
1926				link_attr_sync[params->port]), link_attr);
1927}
1928
1929static void elink_update_pfc_nig(struct elink_params *params,
1930				 struct elink_nig_brb_pfc_port_params
1931				 *nig_params)
1932{
1933	uint32_t xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en =
1934	    0;
1935	uint32_t llfc_enable = 0, xcm_out_en = 0, hwpfc_enable = 0;
1936	uint32_t pkt_priority_to_cos = 0;
1937	struct bnx2x_softc *sc = params->sc;
1938	uint8_t port = params->port;
1939
1940	int set_pfc = params->feature_config_flags &
1941	    ELINK_FEATURE_CONFIG_PFC_ENABLED;
1942	PMD_DRV_LOG(DEBUG, "updating pfc nig parameters");
1943
1944	/* When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
1945	 * MAC control frames (that are not pause packets)
1946	 * will be forwarded to the XCM.
1947	 */
1948	xcm_mask = REG_RD(sc, port ? NIG_REG_LLH1_XCM_MASK :
1949			  NIG_REG_LLH0_XCM_MASK);
1950	/* NIG params will override non PFC params, since it's possible to
1951	 * do transition from PFC to SAFC
1952	 */
1953	if (set_pfc) {
1954		pause_enable = 0;
1955		llfc_out_en = 0;
1956		llfc_enable = 0;
1957		if (CHIP_IS_E3(sc))
1958			ppp_enable = 0;
1959		else
1960			ppp_enable = 1;
1961		xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
1962			      NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
1963		xcm_out_en = 0;
1964		hwpfc_enable = 1;
1965	} else {
1966		if (nig_params) {
1967			llfc_out_en = nig_params->llfc_out_en;
1968			llfc_enable = nig_params->llfc_enable;
1969			pause_enable = nig_params->pause_enable;
1970		} else		/* Default non PFC mode - PAUSE */
1971			pause_enable = 1;
1972
1973		xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
1974			     NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
1975		xcm_out_en = 1;
1976	}
1977
1978	if (CHIP_IS_E3(sc))
1979		REG_WR(sc, port ? NIG_REG_BRB1_PAUSE_IN_EN :
1980		       NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
1981	REG_WR(sc, port ? NIG_REG_LLFC_OUT_EN_1 :
1982	       NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
1983	REG_WR(sc, port ? NIG_REG_LLFC_ENABLE_1 :
1984	       NIG_REG_LLFC_ENABLE_0, llfc_enable);
1985	REG_WR(sc, port ? NIG_REG_PAUSE_ENABLE_1 :
1986	       NIG_REG_PAUSE_ENABLE_0, pause_enable);
1987
1988	REG_WR(sc, port ? NIG_REG_PPP_ENABLE_1 :
1989	       NIG_REG_PPP_ENABLE_0, ppp_enable);
1990
1991	REG_WR(sc, port ? NIG_REG_LLH1_XCM_MASK :
1992	       NIG_REG_LLH0_XCM_MASK, xcm_mask);
1993
1994	REG_WR(sc, port ? NIG_REG_LLFC_EGRESS_SRC_ENABLE_1 :
1995	       NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
1996
1997	/* Output enable for RX_XCM # IF */
1998	REG_WR(sc, port ? NIG_REG_XCM1_OUT_EN :
1999	       NIG_REG_XCM0_OUT_EN, xcm_out_en);
2000
2001	/* HW PFC TX enable */
2002	REG_WR(sc, port ? NIG_REG_P1_HWPFC_ENABLE :
2003	       NIG_REG_P0_HWPFC_ENABLE, hwpfc_enable);
2004
2005	if (nig_params) {
2006		uint8_t i = 0;
2007		pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
2008
2009		for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
2010			elink_pfc_nig_rx_priority_mask(sc, i,
2011						       nig_params->
2012						       rx_cos_priority_mask[i],
2013						       port);
2014
2015		REG_WR(sc, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
2016		       NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
2017		       nig_params->llfc_high_priority_classes);
2018
2019		REG_WR(sc, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
2020		       NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
2021		       nig_params->llfc_low_priority_classes);
2022	}
2023	REG_WR(sc, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
2024	       NIG_REG_P0_PKT_PRIORITY_TO_COS, pkt_priority_to_cos);
2025}
2026
2027elink_status_t elink_update_pfc(struct elink_params *params,
2028				struct elink_vars *vars,
2029				struct elink_nig_brb_pfc_port_params
2030				*pfc_params)
2031{
2032	/* The PFC and pause are orthogonal to one another, meaning when
2033	 * PFC is enabled, the pause are disabled, and when PFC is
2034	 * disabled, pause are set according to the pause result.
2035	 */
2036	uint32_t val;
2037	struct bnx2x_softc *sc = params->sc;
2038	elink_status_t elink_status = ELINK_STATUS_OK;
2039	uint8_t bmac_loopback = (params->loopback_mode == ELINK_LOOPBACK_BMAC);
2040
2041	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
2042		vars->link_status |= LINK_STATUS_PFC_ENABLED;
2043	else
2044		vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
2045
2046	elink_update_mng(params, vars->link_status);
2047
2048	/* Update NIG params */
2049	elink_update_pfc_nig(params, pfc_params);
2050
2051	if (!vars->link_up)
2052		return elink_status;
2053
2054	PMD_DRV_LOG(DEBUG, "About to update PFC in BMAC");
2055
2056	if (CHIP_IS_E3(sc)) {
2057		if (vars->mac_type == ELINK_MAC_TYPE_XMAC)
2058			elink_update_pfc_xmac(params, vars);
2059	} else {
2060		val = REG_RD(sc, MISC_REG_RESET_REG_2);
2061		if ((val &
2062		     (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
2063		    == 0) {
2064			PMD_DRV_LOG(DEBUG, "About to update PFC in EMAC");
2065			elink_emac_enable(params, vars, 0);
2066			return elink_status;
2067		}
2068		if (CHIP_IS_E2(sc))
2069			elink_update_pfc_bmac2(params, vars, bmac_loopback);
2070		else
2071			elink_update_pfc_bmac1(params, vars);
2072
2073		val = 0;
2074		if ((params->feature_config_flags &
2075		     ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
2076		    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2077			val = 1;
2078		REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port * 4, val);
2079	}
2080	return elink_status;
2081}
2082
2083static elink_status_t elink_bmac1_enable(struct elink_params *params,
2084					 struct elink_vars *vars, uint8_t is_lb)
2085{
2086	struct bnx2x_softc *sc = params->sc;
2087	uint8_t port = params->port;
2088	uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2089	    NIG_REG_INGRESS_BMAC0_MEM;
2090	uint32_t wb_data[2];
2091	uint32_t val;
2092
2093	PMD_DRV_LOG(DEBUG, "Enabling BigMAC1");
2094
2095	/* XGXS control */
2096	wb_data[0] = 0x3c;
2097	wb_data[1] = 0;
2098	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
2099		    wb_data, 2);
2100
2101	/* TX MAC SA */
2102	wb_data[0] = ((params->mac_addr[2] << 24) |
2103		      (params->mac_addr[3] << 16) |
2104		      (params->mac_addr[4] << 8) | params->mac_addr[5]);
2105	wb_data[1] = ((params->mac_addr[0] << 8) | params->mac_addr[1]);
2106	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
2107
2108	/* MAC control */
2109	val = 0x3;
2110	if (is_lb) {
2111		val |= 0x4;
2112		PMD_DRV_LOG(DEBUG, "enable bmac loopback");
2113	}
2114	wb_data[0] = val;
2115	wb_data[1] = 0;
2116	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
2117
2118	/* Set rx mtu */
2119	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
2120	wb_data[1] = 0;
2121	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
2122
2123	elink_update_pfc_bmac1(params, vars);
2124
2125	/* Set tx mtu */
2126	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
2127	wb_data[1] = 0;
2128	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
2129
2130	/* Set cnt max size */
2131	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
2132	wb_data[1] = 0;
2133	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2134
2135	/* Configure SAFC */
2136	wb_data[0] = 0x1000200;
2137	wb_data[1] = 0;
2138	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
2139		    wb_data, 2);
2140#ifdef ELINK_INCLUDE_EMUL
2141	/* Fix for emulation */
2142	if (CHIP_REV_IS_EMUL(sc)) {
2143		wb_data[0] = 0xf000;
2144		wb_data[1] = 0;
2145		REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
2146			    wb_data, 2);
2147	}
2148#endif
2149
2150	return ELINK_STATUS_OK;
2151}
2152
2153static elink_status_t elink_bmac2_enable(struct elink_params *params,
2154					 struct elink_vars *vars, uint8_t is_lb)
2155{
2156	struct bnx2x_softc *sc = params->sc;
2157	uint8_t port = params->port;
2158	uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2159	    NIG_REG_INGRESS_BMAC0_MEM;
2160	uint32_t wb_data[2];
2161
2162	PMD_DRV_LOG(DEBUG, "Enabling BigMAC2");
2163
2164	wb_data[0] = 0;
2165	wb_data[1] = 0;
2166	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2167	DELAY(30);
2168
2169	/* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
2170	wb_data[0] = 0x3c;
2171	wb_data[1] = 0;
2172	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
2173		    wb_data, 2);
2174
2175	DELAY(30);
2176
2177	/* TX MAC SA */
2178	wb_data[0] = ((params->mac_addr[2] << 24) |
2179		      (params->mac_addr[3] << 16) |
2180		      (params->mac_addr[4] << 8) | params->mac_addr[5]);
2181	wb_data[1] = ((params->mac_addr[0] << 8) | params->mac_addr[1]);
2182	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
2183		    wb_data, 2);
2184
2185	DELAY(30);
2186
2187	/* Configure SAFC */
2188	wb_data[0] = 0x1000200;
2189	wb_data[1] = 0;
2190	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
2191		    wb_data, 2);
2192	DELAY(30);
2193
2194	/* Set RX MTU */
2195	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
2196	wb_data[1] = 0;
2197	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
2198	DELAY(30);
2199
2200	/* Set TX MTU */
2201	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
2202	wb_data[1] = 0;
2203	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
2204	DELAY(30);
2205	/* Set cnt max size */
2206	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD - 2;
2207	wb_data[1] = 0;
2208	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2209	DELAY(30);
2210	elink_update_pfc_bmac2(params, vars, is_lb);
2211
2212	return ELINK_STATUS_OK;
2213}
2214
2215static elink_status_t elink_bmac_enable(struct elink_params *params,
2216					struct elink_vars *vars,
2217					uint8_t is_lb, uint8_t reset_bmac)
2218{
2219	elink_status_t rc = ELINK_STATUS_OK;
2220	uint8_t port = params->port;
2221	struct bnx2x_softc *sc = params->sc;
2222	uint32_t val;
2223	/* Reset and unreset the BigMac */
2224	if (reset_bmac) {
2225		REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2226		       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2227		DELAY(1000 * 1);
2228	}
2229
2230	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2231	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2232
2233	/* Enable access for bmac registers */
2234	REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port * 4, 0x1);
2235
2236	/* Enable BMAC according to BMAC type */
2237	if (CHIP_IS_E2(sc))
2238		rc = elink_bmac2_enable(params, vars, is_lb);
2239	else
2240		rc = elink_bmac1_enable(params, vars, is_lb);
2241	REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 0x1);
2242	REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, 0x0);
2243	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + port * 4, 0x0);
2244	val = 0;
2245	if ((params->feature_config_flags &
2246	     ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
2247	    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2248		val = 1;
2249	REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + port * 4, val);
2250	REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port * 4, 0x0);
2251	REG_WR(sc, NIG_REG_EMAC0_IN_EN + port * 4, 0x0);
2252	REG_WR(sc, NIG_REG_EMAC0_PAUSE_OUT_EN + port * 4, 0x0);
2253	REG_WR(sc, NIG_REG_BMAC0_IN_EN + port * 4, 0x1);
2254	REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port * 4, 0x1);
2255
2256	vars->mac_type = ELINK_MAC_TYPE_BMAC;
2257	return rc;
2258}
2259
2260static void elink_set_bmac_rx(struct bnx2x_softc *sc, uint8_t port, uint8_t en)
2261{
2262	uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2263	    NIG_REG_INGRESS_BMAC0_MEM;
2264	uint32_t wb_data[2];
2265	uint32_t nig_bmac_enable =
2266	    REG_RD(sc, NIG_REG_BMAC0_REGS_OUT_EN + port * 4);
2267
2268	if (CHIP_IS_E2(sc))
2269		bmac_addr += BIGMAC2_REGISTER_BMAC_CONTROL;
2270	else
2271		bmac_addr += BIGMAC_REGISTER_BMAC_CONTROL;
2272	/* Only if the bmac is out of reset */
2273	if (REG_RD(sc, MISC_REG_RESET_REG_2) &
2274	    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) && nig_bmac_enable) {
2275		/* Clear Rx Enable bit in BMAC_CONTROL register */
2276		REG_RD_DMAE(sc, bmac_addr, wb_data, 2);
2277		if (en)
2278			wb_data[0] |= ELINK_BMAC_CONTROL_RX_ENABLE;
2279		else
2280			wb_data[0] &= ~ELINK_BMAC_CONTROL_RX_ENABLE;
2281		REG_WR_DMAE(sc, bmac_addr, wb_data, 2);
2282		DELAY(1000 * 1);
2283	}
2284}
2285
2286static elink_status_t elink_pbf_update(struct elink_params *params,
2287				       uint32_t flow_ctrl, uint32_t line_speed)
2288{
2289	struct bnx2x_softc *sc = params->sc;
2290	uint8_t port = params->port;
2291	uint32_t init_crd, crd;
2292	uint32_t count = 1000;
2293
2294	/* Disable port */
2295	REG_WR(sc, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port * 4, 0x1);
2296
2297	/* Wait for init credit */
2298	init_crd = REG_RD(sc, PBF_REG_P0_INIT_CRD + port * 4);
2299	crd = REG_RD(sc, PBF_REG_P0_CREDIT + port * 8);
2300	PMD_DRV_LOG(DEBUG, "init_crd 0x%x  crd 0x%x", init_crd, crd);
2301
2302	while ((init_crd != crd) && count) {
2303		DELAY(1000 * 5);
2304		crd = REG_RD(sc, PBF_REG_P0_CREDIT + port * 8);
2305		count--;
2306	}
2307	crd = REG_RD(sc, PBF_REG_P0_CREDIT + port * 8);
2308	if (init_crd != crd) {
2309		PMD_DRV_LOG(DEBUG, "BUG! init_crd 0x%x != crd 0x%x",
2310			    init_crd, crd);
2311		return ELINK_STATUS_ERROR;
2312	}
2313
2314	if (flow_ctrl & ELINK_FLOW_CTRL_RX ||
2315	    line_speed == ELINK_SPEED_10 ||
2316	    line_speed == ELINK_SPEED_100 ||
2317	    line_speed == ELINK_SPEED_1000 || line_speed == ELINK_SPEED_2500) {
2318		REG_WR(sc, PBF_REG_P0_PAUSE_ENABLE + port * 4, 1);
2319		/* Update threshold */
2320		REG_WR(sc, PBF_REG_P0_ARB_THRSH + port * 4, 0);
2321		/* Update init credit */
2322		init_crd = 778;	/* (800-18-4) */
2323
2324	} else {
2325		uint32_t thresh = (ELINK_ETH_MAX_JUMBO_PACKET_SIZE +
2326				   ELINK_ETH_OVREHEAD) / 16;
2327		REG_WR(sc, PBF_REG_P0_PAUSE_ENABLE + port * 4, 0);
2328		/* Update threshold */
2329		REG_WR(sc, PBF_REG_P0_ARB_THRSH + port * 4, thresh);
2330		/* Update init credit */
2331		switch (line_speed) {
2332		case ELINK_SPEED_10000:
2333			init_crd = thresh + 553 - 22;
2334			break;
2335		default:
2336			PMD_DRV_LOG(DEBUG, "Invalid line_speed 0x%x",
2337				    line_speed);
2338			return ELINK_STATUS_ERROR;
2339		}
2340	}
2341	REG_WR(sc, PBF_REG_P0_INIT_CRD + port * 4, init_crd);
2342	PMD_DRV_LOG(DEBUG, "PBF updated to speed %d credit %d",
2343		    line_speed, init_crd);
2344
2345	/* Probe the credit changes */
2346	REG_WR(sc, PBF_REG_INIT_P0 + port * 4, 0x1);
2347	DELAY(1000 * 5);
2348	REG_WR(sc, PBF_REG_INIT_P0 + port * 4, 0x0);
2349
2350	/* Enable port */
2351	REG_WR(sc, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port * 4, 0x0);
2352	return ELINK_STATUS_OK;
2353}
2354
2355/**
2356 * elink_get_emac_base - retrive emac base address
2357 *
2358 * @bp:			driver handle
2359 * @mdc_mdio_access:	access type
2360 * @port:		port id
2361 *
2362 * This function selects the MDC/MDIO access (through emac0 or
2363 * emac1) depend on the mdc_mdio_access, port, port swapped. Each
2364 * phy has a default access mode, which could also be overridden
2365 * by nvram configuration. This parameter, whether this is the
2366 * default phy configuration, or the nvram overrun
2367 * configuration, is passed here as mdc_mdio_access and selects
2368 * the emac_base for the CL45 read/writes operations
2369 */
2370static uint32_t elink_get_emac_base(struct bnx2x_softc *sc,
2371				    uint32_t mdc_mdio_access, uint8_t port)
2372{
2373	uint32_t emac_base = 0;
2374	switch (mdc_mdio_access) {
2375	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
2376		break;
2377	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
2378		if (REG_RD(sc, NIG_REG_PORT_SWAP))
2379			emac_base = GRCBASE_EMAC1;
2380		else
2381			emac_base = GRCBASE_EMAC0;
2382		break;
2383	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
2384		if (REG_RD(sc, NIG_REG_PORT_SWAP))
2385			emac_base = GRCBASE_EMAC0;
2386		else
2387			emac_base = GRCBASE_EMAC1;
2388		break;
2389	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
2390		emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2391		break;
2392	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
2393		emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
2394		break;
2395	default:
2396		break;
2397	}
2398	return emac_base;
2399
2400}
2401
2402/******************************************************************/
2403/*			CL22 access functions			  */
2404/******************************************************************/
2405static elink_status_t elink_cl22_write(struct bnx2x_softc *sc,
2406				       struct elink_phy *phy,
2407				       uint16_t reg, uint16_t val)
2408{
2409	uint32_t tmp, mode;
2410	uint8_t i;
2411	elink_status_t rc = ELINK_STATUS_OK;
2412	/* Switch to CL22 */
2413	mode = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2414	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2415	       mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2416
2417	/* Address */
2418	tmp = ((phy->addr << 21) | (reg << 16) | val |
2419	       EMAC_MDIO_COMM_COMMAND_WRITE_22 | EMAC_MDIO_COMM_START_BUSY);
2420	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2421
2422	for (i = 0; i < 50; i++) {
2423		DELAY(10);
2424
2425		tmp = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2426		if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2427			DELAY(5);
2428			break;
2429		}
2430	}
2431	if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2432		PMD_DRV_LOG(DEBUG, "write phy register failed");
2433		rc = ELINK_STATUS_TIMEOUT;
2434	}
2435	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2436	return rc;
2437}
2438
2439static elink_status_t elink_cl22_read(struct bnx2x_softc *sc,
2440				      struct elink_phy *phy,
2441				      uint16_t reg, uint16_t * ret_val)
2442{
2443	uint32_t val, mode;
2444	uint16_t i;
2445	elink_status_t rc = ELINK_STATUS_OK;
2446
2447	/* Switch to CL22 */
2448	mode = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2449	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2450	       mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2451
2452	/* Address */
2453	val = ((phy->addr << 21) | (reg << 16) |
2454	       EMAC_MDIO_COMM_COMMAND_READ_22 | EMAC_MDIO_COMM_START_BUSY);
2455	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2456
2457	for (i = 0; i < 50; i++) {
2458		DELAY(10);
2459
2460		val = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2461		if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2462			*ret_val = (uint16_t) (val & EMAC_MDIO_COMM_DATA);
2463			DELAY(5);
2464			break;
2465		}
2466	}
2467	if (val & EMAC_MDIO_COMM_START_BUSY) {
2468		PMD_DRV_LOG(DEBUG, "read phy register failed");
2469
2470		*ret_val = 0;
2471		rc = ELINK_STATUS_TIMEOUT;
2472	}
2473	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2474	return rc;
2475}
2476
2477/******************************************************************/
2478/*			CL45 access functions			  */
2479/******************************************************************/
2480static elink_status_t elink_cl45_read(struct bnx2x_softc *sc,
2481				      struct elink_phy *phy, uint8_t devad,
2482				      uint16_t reg, uint16_t * ret_val)
2483{
2484	uint32_t val;
2485	uint16_t i;
2486	elink_status_t rc = ELINK_STATUS_OK;
2487	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_G) {
2488		elink_set_mdio_clk(sc, phy->mdio_ctrl);
2489	}
2490
2491	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
2492		elink_bits_en(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2493			      EMAC_MDIO_STATUS_10MB);
2494	/* Address */
2495	val = ((phy->addr << 21) | (devad << 16) | reg |
2496	       EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY);
2497	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2498
2499	for (i = 0; i < 50; i++) {
2500		DELAY(10);
2501
2502		val = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2503		if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2504			DELAY(5);
2505			break;
2506		}
2507	}
2508	if (val & EMAC_MDIO_COMM_START_BUSY) {
2509		PMD_DRV_LOG(DEBUG, "read phy register failed");
2510		elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT);	// "MDC/MDIO access timeout"
2511
2512		*ret_val = 0;
2513		rc = ELINK_STATUS_TIMEOUT;
2514	} else {
2515		/* Data */
2516		val = ((phy->addr << 21) | (devad << 16) |
2517		       EMAC_MDIO_COMM_COMMAND_READ_45 |
2518		       EMAC_MDIO_COMM_START_BUSY);
2519		REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2520
2521		for (i = 0; i < 50; i++) {
2522			DELAY(10);
2523
2524			val = REG_RD(sc, phy->mdio_ctrl +
2525				     EMAC_REG_EMAC_MDIO_COMM);
2526			if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2527				*ret_val =
2528				    (uint16_t) (val & EMAC_MDIO_COMM_DATA);
2529				break;
2530			}
2531		}
2532		if (val & EMAC_MDIO_COMM_START_BUSY) {
2533			PMD_DRV_LOG(DEBUG, "read phy register failed");
2534			elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT);	// "MDC/MDIO access timeout"
2535
2536			*ret_val = 0;
2537			rc = ELINK_STATUS_TIMEOUT;
2538		}
2539	}
2540	/* Work around for E3 A0 */
2541	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA) {
2542		phy->flags ^= ELINK_FLAGS_DUMMY_READ;
2543		if (phy->flags & ELINK_FLAGS_DUMMY_READ) {
2544			uint16_t temp_val;
2545			elink_cl45_read(sc, phy, devad, 0xf, &temp_val);
2546		}
2547	}
2548
2549	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
2550		elink_bits_dis(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2551			       EMAC_MDIO_STATUS_10MB);
2552	return rc;
2553}
2554
2555static elink_status_t elink_cl45_write(struct bnx2x_softc *sc,
2556				       struct elink_phy *phy, uint8_t devad,
2557				       uint16_t reg, uint16_t val)
2558{
2559	uint32_t tmp;
2560	uint8_t i;
2561	elink_status_t rc = ELINK_STATUS_OK;
2562	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_G) {
2563		elink_set_mdio_clk(sc, phy->mdio_ctrl);
2564	}
2565
2566	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
2567		elink_bits_en(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2568			      EMAC_MDIO_STATUS_10MB);
2569
2570	/* Address */
2571	tmp = ((phy->addr << 21) | (devad << 16) | reg |
2572	       EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY);
2573	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2574
2575	for (i = 0; i < 50; i++) {
2576		DELAY(10);
2577
2578		tmp = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2579		if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2580			DELAY(5);
2581			break;
2582		}
2583	}
2584	if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2585		PMD_DRV_LOG(DEBUG, "write phy register failed");
2586		elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT);	// "MDC/MDIO access timeout"
2587
2588		rc = ELINK_STATUS_TIMEOUT;
2589	} else {
2590		/* Data */
2591		tmp = ((phy->addr << 21) | (devad << 16) | val |
2592		       EMAC_MDIO_COMM_COMMAND_WRITE_45 |
2593		       EMAC_MDIO_COMM_START_BUSY);
2594		REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2595
2596		for (i = 0; i < 50; i++) {
2597			DELAY(10);
2598
2599			tmp = REG_RD(sc, phy->mdio_ctrl +
2600				     EMAC_REG_EMAC_MDIO_COMM);
2601			if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2602				DELAY(5);
2603				break;
2604			}
2605		}
2606		if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2607			PMD_DRV_LOG(DEBUG, "write phy register failed");
2608			elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT);	// "MDC/MDIO access timeout"
2609
2610			rc = ELINK_STATUS_TIMEOUT;
2611		}
2612	}
2613	/* Work around for E3 A0 */
2614	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA) {
2615		phy->flags ^= ELINK_FLAGS_DUMMY_READ;
2616		if (phy->flags & ELINK_FLAGS_DUMMY_READ) {
2617			uint16_t temp_val;
2618			elink_cl45_read(sc, phy, devad, 0xf, &temp_val);
2619		}
2620	}
2621	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
2622		elink_bits_dis(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2623			       EMAC_MDIO_STATUS_10MB);
2624	return rc;
2625}
2626
2627/******************************************************************/
2628/*			EEE section				   */
2629/******************************************************************/
2630static uint8_t elink_eee_has_cap(struct elink_params *params)
2631{
2632	struct bnx2x_softc *sc = params->sc;
2633
2634	if (REG_RD(sc, params->shmem2_base) <=
2635	    offsetof(struct shmem2_region, eee_status[params->port]))
2636		 return 0;
2637
2638	return 1;
2639}
2640
2641static elink_status_t elink_eee_nvram_to_time(uint32_t nvram_mode,
2642					      uint32_t * idle_timer)
2643{
2644	switch (nvram_mode) {
2645	case PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED:
2646		*idle_timer = ELINK_EEE_MODE_NVRAM_BALANCED_TIME;
2647		break;
2648	case PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE:
2649		*idle_timer = ELINK_EEE_MODE_NVRAM_AGGRESSIVE_TIME;
2650		break;
2651	case PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY:
2652		*idle_timer = ELINK_EEE_MODE_NVRAM_LATENCY_TIME;
2653		break;
2654	default:
2655		*idle_timer = 0;
2656		break;
2657	}
2658
2659	return ELINK_STATUS_OK;
2660}
2661
2662static elink_status_t elink_eee_time_to_nvram(uint32_t idle_timer,
2663					      uint32_t * nvram_mode)
2664{
2665	switch (idle_timer) {
2666	case ELINK_EEE_MODE_NVRAM_BALANCED_TIME:
2667		*nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED;
2668		break;
2669	case ELINK_EEE_MODE_NVRAM_AGGRESSIVE_TIME:
2670		*nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE;
2671		break;
2672	case ELINK_EEE_MODE_NVRAM_LATENCY_TIME:
2673		*nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY;
2674		break;
2675	default:
2676		*nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED;
2677		break;
2678	}
2679
2680	return ELINK_STATUS_OK;
2681}
2682
2683static uint32_t elink_eee_calc_timer(struct elink_params *params)
2684{
2685	uint32_t eee_mode, eee_idle;
2686	struct bnx2x_softc *sc = params->sc;
2687
2688	if (params->eee_mode & ELINK_EEE_MODE_OVERRIDE_NVRAM) {
2689		if (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME) {
2690			/* time value in eee_mode --> used directly */
2691			eee_idle = params->eee_mode & ELINK_EEE_MODE_TIMER_MASK;
2692		} else {
2693			/* hsi value in eee_mode --> time */
2694			if (elink_eee_nvram_to_time(params->eee_mode &
2695						    ELINK_EEE_MODE_NVRAM_MASK,
2696						    &eee_idle))
2697				return 0;
2698		}
2699	} else {
2700		/* hsi values in nvram --> time */
2701		eee_mode = ((REG_RD(sc, params->shmem_base +
2702				    offsetof(struct shmem_region,
2703					     dev_info.port_feature_config
2704					     [params->
2705					      port].eee_power_mode)) &
2706			     PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >>
2707			    PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT);
2708
2709		if (elink_eee_nvram_to_time(eee_mode, &eee_idle))
2710			return 0;
2711	}
2712
2713	return eee_idle;
2714}
2715
2716static elink_status_t elink_eee_set_timers(struct elink_params *params,
2717					   struct elink_vars *vars)
2718{
2719	uint32_t eee_idle = 0, eee_mode;
2720	struct bnx2x_softc *sc = params->sc;
2721
2722	eee_idle = elink_eee_calc_timer(params);
2723
2724	if (eee_idle) {
2725		REG_WR(sc, MISC_REG_CPMU_LP_IDLE_THR_P0 + (params->port << 2),
2726		       eee_idle);
2727	} else if ((params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI) &&
2728		   (params->eee_mode & ELINK_EEE_MODE_OVERRIDE_NVRAM) &&
2729		   (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME)) {
2730		PMD_DRV_LOG(DEBUG, "Error: Tx LPI is enabled with timer 0");
2731		return ELINK_STATUS_ERROR;
2732	}
2733
2734	vars->eee_status &= ~(SHMEM_EEE_TIMER_MASK | SHMEM_EEE_TIME_OUTPUT_BIT);
2735	if (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME) {
2736		/* eee_idle in 1u --> eee_status in 16u */
2737		eee_idle >>= 4;
2738		vars->eee_status |= (eee_idle & SHMEM_EEE_TIMER_MASK) |
2739		    SHMEM_EEE_TIME_OUTPUT_BIT;
2740	} else {
2741		if (elink_eee_time_to_nvram(eee_idle, &eee_mode))
2742			return ELINK_STATUS_ERROR;
2743		vars->eee_status |= eee_mode;
2744	}
2745
2746	return ELINK_STATUS_OK;
2747}
2748
2749static elink_status_t elink_eee_initial_config(struct elink_params *params,
2750					       struct elink_vars *vars,
2751					       uint8_t mode)
2752{
2753	vars->eee_status |= ((uint32_t) mode) << SHMEM_EEE_SUPPORTED_SHIFT;
2754
2755	/* Propogate params' bits --> vars (for migration exposure) */
2756	if (params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)
2757		vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT;
2758	else
2759		vars->eee_status &= ~SHMEM_EEE_LPI_REQUESTED_BIT;
2760
2761	if (params->eee_mode & ELINK_EEE_MODE_ADV_LPI)
2762		vars->eee_status |= SHMEM_EEE_REQUESTED_BIT;
2763	else
2764		vars->eee_status &= ~SHMEM_EEE_REQUESTED_BIT;
2765
2766	return elink_eee_set_timers(params, vars);
2767}
2768
2769static elink_status_t elink_eee_disable(struct elink_phy *phy,
2770					struct elink_params *params,
2771					struct elink_vars *vars)
2772{
2773	struct bnx2x_softc *sc = params->sc;
2774
2775	/* Make Certain LPI is disabled */
2776	REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), 0);
2777
2778	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0x0);
2779
2780	vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
2781
2782	return ELINK_STATUS_OK;
2783}
2784
2785static elink_status_t elink_eee_advertise(struct elink_phy *phy,
2786					  struct elink_params *params,
2787					  struct elink_vars *vars,
2788					  uint8_t modes)
2789{
2790	struct bnx2x_softc *sc = params->sc;
2791	uint16_t val = 0;
2792
2793	/* Mask events preventing LPI generation */
2794	REG_WR(sc, MISC_REG_CPMU_LP_MASK_EXT_P0 + (params->port << 2), 0xfc20);
2795
2796	if (modes & SHMEM_EEE_10G_ADV) {
2797		PMD_DRV_LOG(DEBUG, "Advertise 10GBase-T EEE");
2798		val |= 0x8;
2799	}
2800	if (modes & SHMEM_EEE_1G_ADV) {
2801		PMD_DRV_LOG(DEBUG, "Advertise 1GBase-T EEE");
2802		val |= 0x4;
2803	}
2804
2805	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, val);
2806
2807	vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
2808	vars->eee_status |= (modes << SHMEM_EEE_ADV_STATUS_SHIFT);
2809
2810	return ELINK_STATUS_OK;
2811}
2812
2813static void elink_update_mng_eee(struct elink_params *params,
2814				 uint32_t eee_status)
2815{
2816	struct bnx2x_softc *sc = params->sc;
2817
2818	if (elink_eee_has_cap(params))
2819		REG_WR(sc, params->shmem2_base +
2820		       offsetof(struct shmem2_region,
2821				eee_status[params->port]), eee_status);
2822}
2823
2824static void elink_eee_an_resolve(struct elink_phy *phy,
2825				 struct elink_params *params,
2826				 struct elink_vars *vars)
2827{
2828	struct bnx2x_softc *sc = params->sc;
2829	uint16_t adv = 0, lp = 0;
2830	uint32_t lp_adv = 0;
2831	uint8_t neg = 0;
2832
2833	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, &adv);
2834	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LP_EEE_ADV, &lp);
2835
2836	if (lp & 0x2) {
2837		lp_adv |= SHMEM_EEE_100M_ADV;
2838		if (adv & 0x2) {
2839			if (vars->line_speed == ELINK_SPEED_100)
2840				neg = 1;
2841			PMD_DRV_LOG(DEBUG, "EEE negotiated - 100M");
2842		}
2843	}
2844	if (lp & 0x14) {
2845		lp_adv |= SHMEM_EEE_1G_ADV;
2846		if (adv & 0x14) {
2847			if (vars->line_speed == ELINK_SPEED_1000)
2848				neg = 1;
2849			PMD_DRV_LOG(DEBUG, "EEE negotiated - 1G");
2850		}
2851	}
2852	if (lp & 0x68) {
2853		lp_adv |= SHMEM_EEE_10G_ADV;
2854		if (adv & 0x68) {
2855			if (vars->line_speed == ELINK_SPEED_10000)
2856				neg = 1;
2857			PMD_DRV_LOG(DEBUG, "EEE negotiated - 10G");
2858		}
2859	}
2860
2861	vars->eee_status &= ~SHMEM_EEE_LP_ADV_STATUS_MASK;
2862	vars->eee_status |= (lp_adv << SHMEM_EEE_LP_ADV_STATUS_SHIFT);
2863
2864	if (neg) {
2865		PMD_DRV_LOG(DEBUG, "EEE is active");
2866		vars->eee_status |= SHMEM_EEE_ACTIVE_BIT;
2867	}
2868}
2869
2870/******************************************************************/
2871/*			BSC access functions from E3	          */
2872/******************************************************************/
2873static void elink_bsc_module_sel(struct elink_params *params)
2874{
2875	int idx;
2876	uint32_t board_cfg, sfp_ctrl;
2877	uint32_t i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
2878	struct bnx2x_softc *sc = params->sc;
2879	uint8_t port = params->port;
2880	/* Read I2C output PINs */
2881	board_cfg = REG_RD(sc, params->shmem_base +
2882			   offsetof(struct shmem_region,
2883				    dev_info.shared_hw_config.board));
2884	i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
2885	i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
2886	    SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
2887
2888	/* Read I2C output value */
2889	sfp_ctrl = REG_RD(sc, params->shmem_base +
2890			  offsetof(struct shmem_region,
2891				   dev_info.port_hw_config[port].
2892				   e3_cmn_pin_cfg));
2893	i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
2894	i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
2895	PMD_DRV_LOG(DEBUG, "Setting BSC switch");
2896	for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
2897		elink_set_cfg_pin(sc, i2c_pins[idx], i2c_val[idx]);
2898}
2899
2900static elink_status_t elink_bsc_read(struct elink_params *params,
2901				     struct bnx2x_softc *sc,
2902				     uint8_t sl_devid,
2903				     uint16_t sl_addr,
2904				     uint8_t lc_addr,
2905				     uint8_t xfer_cnt, uint32_t * data_array)
2906{
2907	uint32_t val, i;
2908	elink_status_t rc = ELINK_STATUS_OK;
2909
2910	if (xfer_cnt > 16) {
2911		PMD_DRV_LOG(DEBUG, "invalid xfer_cnt %d. Max is 16 bytes",
2912			    xfer_cnt);
2913		return ELINK_STATUS_ERROR;
2914	}
2915	if (params)
2916		elink_bsc_module_sel(params);
2917
2918	xfer_cnt = 16 - lc_addr;
2919
2920	/* Enable the engine */
2921	val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
2922	val |= MCPR_IMC_COMMAND_ENABLE;
2923	REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
2924
2925	/* Program slave device ID */
2926	val = (sl_devid << 16) | sl_addr;
2927	REG_WR(sc, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
2928
2929	/* Start xfer with 0 byte to update the address pointer ??? */
2930	val = (MCPR_IMC_COMMAND_ENABLE) |
2931	    (MCPR_IMC_COMMAND_WRITE_OP <<
2932	     MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
2933	    (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
2934	REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
2935
2936	/* Poll for completion */
2937	i = 0;
2938	val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
2939	while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
2940		DELAY(10);
2941		val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
2942		if (i++ > 1000) {
2943			PMD_DRV_LOG(DEBUG, "wr 0 byte timed out after %d try",
2944				    i);
2945			rc = ELINK_STATUS_TIMEOUT;
2946			break;
2947		}
2948	}
2949	if (rc == ELINK_STATUS_TIMEOUT)
2950		return rc;
2951
2952	/* Start xfer with read op */
2953	val = (MCPR_IMC_COMMAND_ENABLE) |
2954	    (MCPR_IMC_COMMAND_READ_OP <<
2955	     MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
2956	    (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
2957	    (xfer_cnt);
2958	REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
2959
2960	/* Poll for completion */
2961	i = 0;
2962	val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
2963	while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
2964		DELAY(10);
2965		val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
2966		if (i++ > 1000) {
2967			PMD_DRV_LOG(DEBUG, "rd op timed out after %d try", i);
2968			rc = ELINK_STATUS_TIMEOUT;
2969			break;
2970		}
2971	}
2972	if (rc == ELINK_STATUS_TIMEOUT)
2973		return rc;
2974
2975	for (i = (lc_addr >> 2); i < 4; i++) {
2976		data_array[i] = REG_RD(sc, (MCP_REG_MCPR_IMC_DATAREG0 + i * 4));
2977#ifdef __BIG_ENDIAN
2978		data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
2979		    ((data_array[i] & 0x0000ff00) << 8) |
2980		    ((data_array[i] & 0x00ff0000) >> 8) |
2981		    ((data_array[i] & 0xff000000) >> 24);
2982#endif
2983	}
2984	return rc;
2985}
2986
2987static void elink_cl45_read_or_write(struct bnx2x_softc *sc,
2988				     struct elink_phy *phy, uint8_t devad,
2989				     uint16_t reg, uint16_t or_val)
2990{
2991	uint16_t val;
2992	elink_cl45_read(sc, phy, devad, reg, &val);
2993	elink_cl45_write(sc, phy, devad, reg, val | or_val);
2994}
2995
2996static void elink_cl45_read_and_write(struct bnx2x_softc *sc,
2997				      struct elink_phy *phy,
2998				      uint8_t devad, uint16_t reg,
2999				      uint16_t and_val)
3000{
3001	uint16_t val;
3002	elink_cl45_read(sc, phy, devad, reg, &val);
3003	elink_cl45_write(sc, phy, devad, reg, val & and_val);
3004}
3005
3006static uint8_t elink_get_warpcore_lane(struct elink_params *params)
3007{
3008	uint8_t lane = 0;
3009	struct bnx2x_softc *sc = params->sc;
3010	uint32_t path_swap, path_swap_ovr;
3011	uint8_t path, port;
3012
3013	path = SC_PATH(sc);
3014	port = params->port;
3015
3016	if (elink_is_4_port_mode(sc)) {
3017		uint32_t port_swap, port_swap_ovr;
3018
3019		/* Figure out path swap value */
3020		path_swap_ovr = REG_RD(sc, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
3021		if (path_swap_ovr & 0x1)
3022			path_swap = (path_swap_ovr & 0x2);
3023		else
3024			path_swap = REG_RD(sc, MISC_REG_FOUR_PORT_PATH_SWAP);
3025
3026		if (path_swap)
3027			path = path ^ 1;
3028
3029		/* Figure out port swap value */
3030		port_swap_ovr = REG_RD(sc, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
3031		if (port_swap_ovr & 0x1)
3032			port_swap = (port_swap_ovr & 0x2);
3033		else
3034			port_swap = REG_RD(sc, MISC_REG_FOUR_PORT_PORT_SWAP);
3035
3036		if (port_swap)
3037			port = port ^ 1;
3038
3039		lane = (port << 1) + path;
3040	} else {		/* Two port mode - no port swap */
3041
3042		/* Figure out path swap value */
3043		path_swap_ovr = REG_RD(sc, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
3044		if (path_swap_ovr & 0x1) {
3045			path_swap = (path_swap_ovr & 0x2);
3046		} else {
3047			path_swap = REG_RD(sc, MISC_REG_TWO_PORT_PATH_SWAP);
3048		}
3049		if (path_swap)
3050			path = path ^ 1;
3051
3052		lane = path << 1;
3053	}
3054	return lane;
3055}
3056
3057static void elink_set_aer_mmd(struct elink_params *params,
3058			      struct elink_phy *phy)
3059{
3060	uint32_t ser_lane;
3061	uint16_t offset, aer_val;
3062	struct bnx2x_softc *sc = params->sc;
3063	ser_lane = ((params->lane_config &
3064		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3065		    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3066
3067	offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
3068	    (phy->addr + ser_lane) : 0;
3069
3070	if (USES_WARPCORE(sc)) {
3071		aer_val = elink_get_warpcore_lane(params);
3072		/* In Dual-lane mode, two lanes are joined together,
3073		 * so in order to configure them, the AER broadcast method is
3074		 * used here.
3075		 * 0x200 is the broadcast address for lanes 0,1
3076		 * 0x201 is the broadcast address for lanes 2,3
3077		 */
3078		if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
3079			aer_val = (aer_val >> 1) | 0x200;
3080	} else if (CHIP_IS_E2(sc))
3081		aer_val = 0x3800 + offset - 1;
3082	else
3083		aer_val = 0x3800 + offset;
3084
3085	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
3086			  MDIO_AER_BLOCK_AER_REG, aer_val);
3087
3088}
3089
3090/******************************************************************/
3091/*			Internal phy section			  */
3092/******************************************************************/
3093
3094static void elink_set_serdes_access(struct bnx2x_softc *sc, uint8_t port)
3095{
3096	uint32_t emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3097
3098	/* Set Clause 22 */
3099	REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_ST + port * 0x10, 1);
3100	REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
3101	DELAY(500);
3102	REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
3103	DELAY(500);
3104	/* Set Clause 45 */
3105	REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_ST + port * 0x10, 0);
3106}
3107
3108static void elink_serdes_deassert(struct bnx2x_softc *sc, uint8_t port)
3109{
3110	uint32_t val;
3111
3112	PMD_DRV_LOG(DEBUG, "elink_serdes_deassert");
3113
3114	val = ELINK_SERDES_RESET_BITS << (port * 16);
3115
3116	/* Reset and unreset the SerDes/XGXS */
3117	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3118	DELAY(500);
3119	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3120
3121	elink_set_serdes_access(sc, port);
3122
3123	REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_DEVAD + port * 0x10,
3124	       ELINK_DEFAULT_PHY_DEV_ADDR);
3125}
3126
3127static void elink_xgxs_specific_func(struct elink_phy *phy,
3128				     struct elink_params *params,
3129				     uint32_t action)
3130{
3131	struct bnx2x_softc *sc = params->sc;
3132	switch (action) {
3133	case ELINK_PHY_INIT:
3134		/* Set correct devad */
3135		REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_ST + params->port * 0x18, 0);
3136		REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port * 0x18,
3137		       phy->def_md_devad);
3138		break;
3139	}
3140}
3141
3142static void elink_xgxs_deassert(struct elink_params *params)
3143{
3144	struct bnx2x_softc *sc = params->sc;
3145	uint8_t port;
3146	uint32_t val;
3147	PMD_DRV_LOG(DEBUG, "elink_xgxs_deassert");
3148	port = params->port;
3149
3150	val = ELINK_XGXS_RESET_BITS << (port * 16);
3151
3152	/* Reset and unreset the SerDes/XGXS */
3153	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3154	DELAY(500);
3155	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3156	elink_xgxs_specific_func(&params->phy[ELINK_INT_PHY], params,
3157				 ELINK_PHY_INIT);
3158}
3159
3160static void elink_calc_ieee_aneg_adv(struct elink_phy *phy,
3161				     struct elink_params *params,
3162				     uint16_t * ieee_fc)
3163{
3164	*ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
3165	/* Resolve pause mode and advertisement Please refer to Table
3166	 * 28B-3 of the 802.3ab-1999 spec
3167	 */
3168
3169	switch (phy->req_flow_ctrl) {
3170	case ELINK_FLOW_CTRL_AUTO:
3171		switch (params->req_fc_auto_adv) {
3172		case ELINK_FLOW_CTRL_BOTH:
3173			*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3174			break;
3175		case ELINK_FLOW_CTRL_RX:
3176		case ELINK_FLOW_CTRL_TX:
3177			*ieee_fc |=
3178			    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3179			break;
3180		default:
3181			break;
3182		}
3183		break;
3184	case ELINK_FLOW_CTRL_TX:
3185		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3186		break;
3187
3188	case ELINK_FLOW_CTRL_RX:
3189	case ELINK_FLOW_CTRL_BOTH:
3190		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3191		break;
3192
3193	case ELINK_FLOW_CTRL_NONE:
3194	default:
3195		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
3196		break;
3197	}
3198	PMD_DRV_LOG(DEBUG, "ieee_fc = 0x%x", *ieee_fc);
3199}
3200
3201static void set_phy_vars(struct elink_params *params, struct elink_vars *vars)
3202{
3203	uint8_t actual_phy_idx, phy_index, link_cfg_idx;
3204	uint8_t phy_config_swapped = params->multi_phy_config &
3205	    PORT_HW_CFG_PHY_SWAPPED_ENABLED;
3206	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
3207	     phy_index++) {
3208		link_cfg_idx = ELINK_LINK_CONFIG_IDX(phy_index);
3209		actual_phy_idx = phy_index;
3210		if (phy_config_swapped) {
3211			if (phy_index == ELINK_EXT_PHY1)
3212				actual_phy_idx = ELINK_EXT_PHY2;
3213			else if (phy_index == ELINK_EXT_PHY2)
3214				actual_phy_idx = ELINK_EXT_PHY1;
3215		}
3216		params->phy[actual_phy_idx].req_flow_ctrl =
3217		    params->req_flow_ctrl[link_cfg_idx];
3218
3219		params->phy[actual_phy_idx].req_line_speed =
3220		    params->req_line_speed[link_cfg_idx];
3221
3222		params->phy[actual_phy_idx].speed_cap_mask =
3223		    params->speed_cap_mask[link_cfg_idx];
3224
3225		params->phy[actual_phy_idx].req_duplex =
3226		    params->req_duplex[link_cfg_idx];
3227
3228		if (params->req_line_speed[link_cfg_idx] ==
3229		    ELINK_SPEED_AUTO_NEG)
3230			vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
3231
3232		PMD_DRV_LOG(DEBUG, "req_flow_ctrl %x, req_line_speed %x,"
3233			    " speed_cap_mask %x",
3234			    params->phy[actual_phy_idx].req_flow_ctrl,
3235			    params->phy[actual_phy_idx].req_line_speed,
3236			    params->phy[actual_phy_idx].speed_cap_mask);
3237	}
3238}
3239
3240static void elink_ext_phy_set_pause(struct elink_params *params,
3241				    struct elink_phy *phy,
3242				    struct elink_vars *vars)
3243{
3244	uint16_t val;
3245	struct bnx2x_softc *sc = params->sc;
3246	/* Read modify write pause advertizing */
3247	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
3248
3249	val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3250
3251	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3252	elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
3253	if ((vars->ieee_fc &
3254	     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3255	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3256		val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3257	}
3258	if ((vars->ieee_fc &
3259	     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3260	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3261		val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
3262	}
3263	PMD_DRV_LOG(DEBUG, "Ext phy AN advertize 0x%x", val);
3264	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3265}
3266
3267static void elink_pause_resolve(struct elink_vars *vars, uint32_t pause_result)
3268{				/*  LD      LP   */
3269	switch (pause_result) {	/* ASYM P ASYM P */
3270	case 0xb:		/*   1  0   1  1 */
3271		vars->flow_ctrl = ELINK_FLOW_CTRL_TX;
3272		break;
3273
3274	case 0xe:		/*   1  1   1  0 */
3275		vars->flow_ctrl = ELINK_FLOW_CTRL_RX;
3276		break;
3277
3278	case 0x5:		/*   0  1   0  1 */
3279	case 0x7:		/*   0  1   1  1 */
3280	case 0xd:		/*   1  1   0  1 */
3281	case 0xf:		/*   1  1   1  1 */
3282		vars->flow_ctrl = ELINK_FLOW_CTRL_BOTH;
3283		break;
3284
3285	default:
3286		break;
3287	}
3288	if (pause_result & (1 << 0))
3289		vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
3290	if (pause_result & (1 << 1))
3291		vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
3292
3293}
3294
3295static void elink_ext_phy_update_adv_fc(struct elink_phy *phy,
3296					struct elink_params *params,
3297					struct elink_vars *vars)
3298{
3299	uint16_t ld_pause;	/* local */
3300	uint16_t lp_pause;	/* link partner */
3301	uint16_t pause_result;
3302	struct bnx2x_softc *sc = params->sc;
3303	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X54618SE) {
3304		elink_cl22_read(sc, phy, 0x4, &ld_pause);
3305		elink_cl22_read(sc, phy, 0x5, &lp_pause);
3306	} else if (CHIP_IS_E3(sc) && ELINK_SINGLE_MEDIA_DIRECT(params)) {
3307		uint8_t lane = elink_get_warpcore_lane(params);
3308		uint16_t gp_status, gp_mask;
3309		elink_cl45_read(sc, phy,
3310				MDIO_AN_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_4,
3311				&gp_status);
3312		gp_mask = (MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL |
3313			   MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP) <<
3314		    lane;
3315		if ((gp_status & gp_mask) == gp_mask) {
3316			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
3317					MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3318			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
3319					MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3320		} else {
3321			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
3322					MDIO_AN_REG_CL37_FC_LD, &ld_pause);
3323			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
3324					MDIO_AN_REG_CL37_FC_LP, &lp_pause);
3325			ld_pause = ((ld_pause &
3326				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
3327				    << 3);
3328			lp_pause = ((lp_pause &
3329				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
3330				    << 3);
3331		}
3332	} else {
3333		elink_cl45_read(sc, phy,
3334				MDIO_AN_DEVAD,
3335				MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3336		elink_cl45_read(sc, phy,
3337				MDIO_AN_DEVAD,
3338				MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3339	}
3340	pause_result = (ld_pause & MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
3341	pause_result |= (lp_pause & MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
3342	PMD_DRV_LOG(DEBUG, "Ext PHY pause result 0x%x", pause_result);
3343	elink_pause_resolve(vars, pause_result);
3344
3345}
3346
3347static uint8_t elink_ext_phy_resolve_fc(struct elink_phy *phy,
3348					struct elink_params *params,
3349					struct elink_vars *vars)
3350{
3351	uint8_t ret = 0;
3352	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
3353	if (phy->req_flow_ctrl != ELINK_FLOW_CTRL_AUTO) {
3354		/* Update the advertised flow-controled of LD/LP in AN */
3355		if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
3356			elink_ext_phy_update_adv_fc(phy, params, vars);
3357		/* But set the flow-control result as the requested one */
3358		vars->flow_ctrl = phy->req_flow_ctrl;
3359	} else if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
3360		vars->flow_ctrl = params->req_fc_auto_adv;
3361	else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
3362		ret = 1;
3363		elink_ext_phy_update_adv_fc(phy, params, vars);
3364	}
3365	return ret;
3366}
3367
3368/******************************************************************/
3369/*			Warpcore section			  */
3370/******************************************************************/
3371/* The init_internal_warpcore should mirror the xgxs,
3372 * i.e. reset the lane (if needed), set aer for the
3373 * init configuration, and set/clear SGMII flag. Internal
3374 * phy init is done purely in phy_init stage.
3375 */
3376#define WC_TX_DRIVER(post2, idriver, ipre) \
3377	((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \
3378	 (idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \
3379	 (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))
3380
3381#define WC_TX_FIR(post, main, pre) \
3382	((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \
3383	 (main << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | \
3384	 (pre << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET))
3385
3386static void elink_warpcore_enable_AN_KR2(struct elink_phy *phy,
3387					 struct elink_params *params,
3388					 struct elink_vars *vars)
3389{
3390	struct bnx2x_softc *sc = params->sc;
3391	uint16_t i;
3392	static struct elink_reg_set reg_set[] = {
3393		/* Step 1 - Program the TX/RX alignment markers */
3394		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0xa157},
3395		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xcbe2},
3396		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0x7537},
3397		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0xa157},
3398		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xcbe2},
3399		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0x7537},
3400		/* Step 2 - Configure the NP registers */
3401		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000a},
3402		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6400},
3403		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0620},
3404		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0157},
3405		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x6464},
3406		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x3150},
3407		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x3150},
3408		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0157},
3409		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0620}
3410	};
3411	PMD_DRV_LOG(DEBUG, "Enabling 20G-KR2");
3412
3413	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3414				 MDIO_WC_REG_CL49_USERB0_CTRL, (3 << 6));
3415
3416	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
3417		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
3418				 reg_set[i].val);
3419
3420	/* Start KR2 work-around timer which handles BNX2X8073 link-parner */
3421	vars->link_attr_sync |= LINK_ATTR_SYNC_KR2_ENABLE;
3422	elink_update_link_attr(params, vars->link_attr_sync);
3423}
3424
3425static void elink_disable_kr2(struct elink_params *params,
3426			      struct elink_vars *vars, struct elink_phy *phy)
3427{
3428	struct bnx2x_softc *sc = params->sc;
3429	uint32_t i;
3430	static struct elink_reg_set reg_set[] = {
3431		/* Step 1 - Program the TX/RX alignment markers */
3432		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0x7690},
3433		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xe647},
3434		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0xc4f0},
3435		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0x7690},
3436		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xe647},
3437		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0xc4f0},
3438		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000c},
3439		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6000},
3440		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0000},
3441		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0002},
3442		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x0000},
3443		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x0af7},
3444		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x0af7},
3445		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0002},
3446		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0000}
3447	};
3448	PMD_DRV_LOG(DEBUG, "Disabling 20G-KR2");
3449
3450	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
3451		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
3452				 reg_set[i].val);
3453	vars->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE;
3454	elink_update_link_attr(params, vars->link_attr_sync);
3455
3456	vars->check_kr2_recovery_cnt = ELINK_CHECK_KR2_RECOVERY_CNT;
3457}
3458
3459static void elink_warpcore_set_lpi_passthrough(struct elink_phy *phy,
3460					       struct elink_params *params)
3461{
3462	struct bnx2x_softc *sc = params->sc;
3463
3464	PMD_DRV_LOG(DEBUG, "Configure WC for LPI pass through");
3465	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3466			 MDIO_WC_REG_EEE_COMBO_CONTROL0, 0x7c);
3467	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3468				 MDIO_WC_REG_DIGITAL4_MISC5, 0xc000);
3469}
3470
3471static void elink_warpcore_restart_AN_KR(struct elink_phy *phy,
3472					 struct elink_params *params)
3473{
3474	/* Restart autoneg on the leading lane only */
3475	struct bnx2x_softc *sc = params->sc;
3476	uint16_t lane = elink_get_warpcore_lane(params);
3477	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
3478			  MDIO_AER_BLOCK_AER_REG, lane);
3479	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
3480			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
3481
3482	/* Restore AER */
3483	elink_set_aer_mmd(params, phy);
3484}
3485
3486static void elink_warpcore_enable_AN_KR(struct elink_phy *phy,
3487					struct elink_params *params,
3488					struct elink_vars *vars)
3489{
3490	uint16_t lane, i, cl72_ctrl, an_adv = 0;
3491	struct bnx2x_softc *sc = params->sc;
3492	static struct elink_reg_set reg_set[] = {
3493		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
3494		{MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0},
3495		{MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415},
3496		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190},
3497		/* Disable Autoneg: re-enable it after adv is done. */
3498		{MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0},
3499		{MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2},
3500		{MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0},
3501	};
3502	PMD_DRV_LOG(DEBUG, "Enable Auto Negotiation for KR");
3503	/* Set to default registers that may be overriden by 10G force */
3504	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
3505		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
3506				 reg_set[i].val);
3507
3508	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
3509			MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl);
3510	cl72_ctrl &= 0x08ff;
3511	cl72_ctrl |= 0x3800;
3512	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3513			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl);
3514
3515	/* Check adding advertisement for 1G KX */
3516	if (((vars->line_speed == ELINK_SPEED_AUTO_NEG) &&
3517	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
3518	    (vars->line_speed == ELINK_SPEED_1000)) {
3519		uint16_t addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2;
3520		an_adv |= (1 << 5);
3521
3522		/* Enable CL37 1G Parallel Detect */
3523		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD, addr, 0x1);
3524		PMD_DRV_LOG(DEBUG, "Advertize 1G");
3525	}
3526	if (((vars->line_speed == ELINK_SPEED_AUTO_NEG) &&
3527	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
3528	    (vars->line_speed == ELINK_SPEED_10000)) {
3529		/* Check adding advertisement for 10G KR */
3530		an_adv |= (1 << 7);
3531		/* Enable 10G Parallel Detect */
3532		CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
3533				  MDIO_AER_BLOCK_AER_REG, 0);
3534
3535		elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
3536				 MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
3537		elink_set_aer_mmd(params, phy);
3538		PMD_DRV_LOG(DEBUG, "Advertize 10G");
3539	}
3540
3541	/* Set Transmit PMD settings */
3542	lane = elink_get_warpcore_lane(params);
3543	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3544			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * lane,
3545			 WC_TX_DRIVER(0x02, 0x06, 0x09));
3546	/* Configure the next lane if dual mode */
3547	if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
3548		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3549				 MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * (lane + 1),
3550				 WC_TX_DRIVER(0x02, 0x06, 0x09));
3551	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3552			 MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL, 0x03f0);
3553	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3554			 MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL, 0x03f0);
3555
3556	/* Advertised speeds */
3557	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
3558			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, an_adv);
3559
3560	/* Advertised and set FEC (Forward Error Correction) */
3561	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
3562			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2,
3563			 (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY |
3564			  MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ));
3565
3566	/* Enable CL37 BAM */
3567	if (REG_RD(sc, params->shmem_base +
3568		   offsetof(struct shmem_region,
3569			    dev_info.port_hw_config[params->port].
3570			    default_cfg)) &
3571	    PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
3572		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3573					 MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL,
3574					 1);
3575		PMD_DRV_LOG(DEBUG, "Enable CL37 BAM on KR");
3576	}
3577
3578	/* Advertise pause */
3579	elink_ext_phy_set_pause(params, phy, vars);
3580	vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
3581	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3582				 MDIO_WC_REG_DIGITAL5_MISC7, 0x100);
3583
3584	/* Over 1G - AN local device user page 1 */
3585	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3586			 MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
3587
3588	if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
3589	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) ||
3590	    (phy->req_line_speed == ELINK_SPEED_20000)) {
3591
3592		CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
3593				  MDIO_AER_BLOCK_AER_REG, lane);
3594
3595		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3596					 MDIO_WC_REG_RX1_PCI_CTRL +
3597					 (0x10 * lane), (1 << 11));
3598
3599		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3600				 MDIO_WC_REG_XGXS_X2_CONTROL3, 0x7);
3601		elink_set_aer_mmd(params, phy);
3602
3603		elink_warpcore_enable_AN_KR2(phy, params, vars);
3604	} else {
3605		elink_disable_kr2(params, vars, phy);
3606	}
3607
3608	/* Enable Autoneg: only on the main lane */
3609	elink_warpcore_restart_AN_KR(phy, params);
3610}
3611
3612static void elink_warpcore_set_10G_KR(struct elink_phy *phy,
3613				      struct elink_params *params)
3614{
3615	struct bnx2x_softc *sc = params->sc;
3616	uint16_t val16, i, lane;
3617	static struct elink_reg_set reg_set[] = {
3618		/* Disable Autoneg */
3619		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
3620		{MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3621		 0x3f00},
3622		{MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0},
3623		{MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0},
3624		{MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1},
3625		{MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa},
3626		/* Leave cl72 training enable, needed for KR */
3627		{MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2}
3628	};
3629
3630	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
3631		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
3632				 reg_set[i].val);
3633
3634	lane = elink_get_warpcore_lane(params);
3635	/* Global registers */
3636	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
3637			  MDIO_AER_BLOCK_AER_REG, 0);
3638	/* Disable CL36 PCS Tx */
3639	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
3640			MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
3641	val16 &= ~(0x0011 << lane);
3642	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3643			 MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
3644
3645	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
3646			MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
3647	val16 |= (0x0303 << (lane << 1));
3648	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3649			 MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
3650	/* Restore AER */
3651	elink_set_aer_mmd(params, phy);
3652	/* Set speed via PMA/PMD register */
3653	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD,
3654			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
3655
3656	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD,
3657			 MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
3658
3659	/* Enable encoded forced speed */
3660	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3661			 MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
3662
3663	/* Turn TX scramble payload only the 64/66 scrambler */
3664	elink_cl45_write(sc, phy, MDIO_WC_DEVAD, MDIO_WC_REG_TX66_CONTROL, 0x9);
3665
3666	/* Turn RX scramble payload only the 64/66 scrambler */
3667	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3668				 MDIO_WC_REG_RX66_CONTROL, 0xF9);
3669
3670	/* Set and clear loopback to cause a reset to 64/66 decoder */
3671	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3672			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
3673	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3674			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3675
3676}
3677
3678static void elink_warpcore_set_10G_XFI(struct elink_phy *phy,
3679				       struct elink_params *params,
3680				       uint8_t is_xfi)
3681{
3682	struct bnx2x_softc *sc = params->sc;
3683	uint16_t misc1_val, tap_val, tx_driver_val, lane, val;
3684	uint32_t cfg_tap_val, tx_drv_brdct, tx_equal;
3685
3686	/* Hold rxSeqStart */
3687	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3688				 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x8000);
3689
3690	/* Hold tx_fifo_reset */
3691	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3692				 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x1);
3693
3694	/* Disable CL73 AN */
3695	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
3696
3697	/* Disable 100FX Enable and Auto-Detect */
3698	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
3699				  MDIO_WC_REG_FX100_CTRL1, 0xFFFA);
3700
3701	/* Disable 100FX Idle detect */
3702	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3703				 MDIO_WC_REG_FX100_CTRL3, 0x0080);
3704
3705	/* Set Block address to Remote PHY & Clear forced_speed[5] */
3706	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
3707				  MDIO_WC_REG_DIGITAL4_MISC3, 0xFF7F);
3708
3709	/* Turn off auto-detect & fiber mode */
3710	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
3711				  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3712				  0xFFEE);
3713
3714	/* Set filter_force_link, disable_false_link and parallel_detect */
3715	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
3716			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
3717	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3718			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3719			 ((val | 0x0006) & 0xFFFE));
3720
3721	/* Set XFI / SFI */
3722	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
3723			MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
3724
3725	misc1_val &= ~(0x1f);
3726
3727	if (is_xfi) {
3728		misc1_val |= 0x5;
3729		tap_val = WC_TX_FIR(0x08, 0x37, 0x00);
3730		tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03);
3731	} else {
3732		cfg_tap_val = REG_RD(sc, params->shmem_base +
3733				     offsetof(struct shmem_region,
3734					      dev_info.port_hw_config[params->
3735								      port].sfi_tap_values));
3736
3737		tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK;
3738
3739		tx_drv_brdct = (cfg_tap_val &
3740				PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >>
3741		    PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT;
3742
3743		misc1_val |= 0x9;
3744
3745		/* TAP values are controlled by nvram, if value there isn't 0 */
3746		if (tx_equal)
3747			tap_val = (uint16_t) tx_equal;
3748		else
3749			tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02);
3750
3751		if (tx_drv_brdct)
3752			tx_driver_val =
3753			    WC_TX_DRIVER(0x03, (uint16_t) tx_drv_brdct, 0x06);
3754		else
3755			tx_driver_val = WC_TX_DRIVER(0x03, 0x02, 0x06);
3756	}
3757	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3758			 MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
3759
3760	/* Set Transmit PMD settings */
3761	lane = elink_get_warpcore_lane(params);
3762	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3763			 MDIO_WC_REG_TX_FIR_TAP,
3764			 tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
3765	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3766			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * lane,
3767			 tx_driver_val);
3768
3769	/* Enable fiber mode, enable and invert sig_det */
3770	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3771				 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0xd);
3772
3773	/* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
3774	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3775				 MDIO_WC_REG_DIGITAL4_MISC3, 0x8080);
3776
3777	elink_warpcore_set_lpi_passthrough(phy, params);
3778
3779	/* 10G XFI Full Duplex */
3780	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3781			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
3782
3783	/* Release tx_fifo_reset */
3784	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
3785				  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3,
3786				  0xFFFE);
3787	/* Release rxSeqStart */
3788	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
3789				  MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x7FFF);
3790}
3791
3792static void elink_warpcore_set_20G_force_KR2(struct elink_phy *phy,
3793					     struct elink_params *params)
3794{
3795	uint16_t val;
3796	struct bnx2x_softc *sc = params->sc;
3797	/* Set global registers, so set AER lane to 0 */
3798	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
3799			  MDIO_AER_BLOCK_AER_REG, 0);
3800
3801	/* Disable sequencer */
3802	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
3803				  MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, ~(1 << 13));
3804
3805	elink_set_aer_mmd(params, phy);
3806
3807	elink_cl45_read_and_write(sc, phy, MDIO_PMA_DEVAD,
3808				  MDIO_WC_REG_PMD_KR_CONTROL, ~(1 << 1));
3809	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
3810	/* Turn off CL73 */
3811	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
3812			MDIO_WC_REG_CL73_USERB0_CTRL, &val);
3813	val &= ~(1 << 5);
3814	val |= (1 << 6);
3815	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3816			 MDIO_WC_REG_CL73_USERB0_CTRL, val);
3817
3818	/* Set 20G KR2 force speed */
3819	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3820				 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x1f);
3821
3822	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3823				 MDIO_WC_REG_DIGITAL4_MISC3, (1 << 7));
3824
3825	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
3826			MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &val);
3827	val &= ~(3 << 14);
3828	val |= (1 << 15);
3829	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3830			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, val);
3831	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3832			 MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0x835A);
3833
3834	/* Enable sequencer (over lane 0) */
3835	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
3836			  MDIO_AER_BLOCK_AER_REG, 0);
3837
3838	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3839				 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, (1 << 13));
3840
3841	elink_set_aer_mmd(params, phy);
3842}
3843
3844static void elink_warpcore_set_20G_DXGXS(struct bnx2x_softc *sc,
3845					 struct elink_phy *phy, uint16_t lane)
3846{
3847	/* Rx0 anaRxControl1G */
3848	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3849			 MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
3850
3851	/* Rx2 anaRxControl1G */
3852	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3853			 MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
3854
3855	elink_cl45_write(sc, phy, MDIO_WC_DEVAD, MDIO_WC_REG_RX66_SCW0, 0xE070);
3856
3857	elink_cl45_write(sc, phy, MDIO_WC_DEVAD, MDIO_WC_REG_RX66_SCW1, 0xC0D0);
3858
3859	elink_cl45_write(sc, phy, MDIO_WC_DEVAD, MDIO_WC_REG_RX66_SCW2, 0xA0B0);
3860
3861	elink_cl45_write(sc, phy, MDIO_WC_DEVAD, MDIO_WC_REG_RX66_SCW3, 0x8090);
3862
3863	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3864			 MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
3865
3866	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3867			 MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
3868
3869	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3870			 MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
3871
3872	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3873			 MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
3874
3875	/* Serdes Digital Misc1 */
3876	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3877			 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
3878
3879	/* Serdes Digital4 Misc3 */
3880	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3881			 MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
3882
3883	/* Set Transmit PMD settings */
3884	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3885			 MDIO_WC_REG_TX_FIR_TAP,
3886			 (WC_TX_FIR(0x12, 0x2d, 0x00) |
3887			  MDIO_WC_REG_TX_FIR_TAP_ENABLE));
3888	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3889			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * lane,
3890			 WC_TX_DRIVER(0x02, 0x02, 0x02));
3891}
3892
3893static void elink_warpcore_set_sgmii_speed(struct elink_phy *phy,
3894					   struct elink_params *params,
3895					   uint8_t fiber_mode,
3896					   uint8_t always_autoneg)
3897{
3898	struct bnx2x_softc *sc = params->sc;
3899	uint16_t val16, digctrl_kx1, digctrl_kx2;
3900
3901	/* Clear XFI clock comp in non-10G single lane mode. */
3902	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
3903				  MDIO_WC_REG_RX66_CONTROL, ~(3 << 13));
3904
3905	elink_warpcore_set_lpi_passthrough(phy, params);
3906
3907	if (always_autoneg || phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
3908		/* SGMII Autoneg */
3909		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
3910					 MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
3911					 0x1000);
3912		PMD_DRV_LOG(DEBUG, "set SGMII AUTONEG");
3913	} else {
3914		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
3915				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3916		val16 &= 0xcebf;
3917		switch (phy->req_line_speed) {
3918		case ELINK_SPEED_10:
3919			break;
3920		case ELINK_SPEED_100:
3921			val16 |= 0x2000;
3922			break;
3923		case ELINK_SPEED_1000:
3924			val16 |= 0x0040;
3925			break;
3926		default:
3927			PMD_DRV_LOG(DEBUG,
3928				    "Speed not supported: 0x%x",
3929				    phy->req_line_speed);
3930			return;
3931		}
3932
3933		if (phy->req_duplex == DUPLEX_FULL)
3934			val16 |= 0x0100;
3935
3936		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3937				 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
3938
3939		PMD_DRV_LOG(DEBUG, "set SGMII force speed %d",
3940			    phy->req_line_speed);
3941		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
3942				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3943		PMD_DRV_LOG(DEBUG, "  (readback) %x", val16);
3944	}
3945
3946	/* SGMII Slave mode and disable signal detect */
3947	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
3948			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
3949	if (fiber_mode)
3950		digctrl_kx1 = 1;
3951	else
3952		digctrl_kx1 &= 0xff4a;
3953
3954	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3955			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, digctrl_kx1);
3956
3957	/* Turn off parallel detect */
3958	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
3959			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
3960	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3961			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3962			 (digctrl_kx2 & ~(1 << 2)));
3963
3964	/* Re-enable parallel detect */
3965	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3966			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3967			 (digctrl_kx2 | (1 << 2)));
3968
3969	/* Enable autodet */
3970	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3971			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3972			 (digctrl_kx1 | 0x10));
3973}
3974
3975static void elink_warpcore_reset_lane(struct bnx2x_softc *sc,
3976				      struct elink_phy *phy, uint8_t reset)
3977{
3978	uint16_t val;
3979	/* Take lane out of reset after configuration is finished */
3980	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
3981			MDIO_WC_REG_DIGITAL5_MISC6, &val);
3982	if (reset)
3983		val |= 0xC000;
3984	else
3985		val &= 0x3FFF;
3986	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
3987			 MDIO_WC_REG_DIGITAL5_MISC6, val);
3988	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
3989			MDIO_WC_REG_DIGITAL5_MISC6, &val);
3990}
3991
3992/* Clear SFI/XFI link settings registers */
3993static void elink_warpcore_clear_regs(struct elink_phy *phy,
3994				      struct elink_params *params,
3995				      uint16_t lane)
3996{
3997	struct bnx2x_softc *sc = params->sc;
3998	uint16_t i;
3999	static struct elink_reg_set wc_regs[] = {
4000		{MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0},
4001		{MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL1, 0x014a},
4002		{MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL3, 0x0800},
4003		{MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL4_MISC3, 0x8008},
4004		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4005		 0x0195},
4006		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4007		 0x0007},
4008		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3,
4009		 0x0002},
4010		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000},
4011		{MDIO_WC_DEVAD, MDIO_WC_REG_TX_FIR_TAP, 0x0000},
4012		{MDIO_WC_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040},
4013		{MDIO_WC_DEVAD, MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140}
4014	};
4015	/* Set XFI clock comp as default. */
4016	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4017				 MDIO_WC_REG_RX66_CONTROL, (3 << 13));
4018
4019	for (i = 0; i < ARRAY_SIZE(wc_regs); i++)
4020		elink_cl45_write(sc, phy, wc_regs[i].devad, wc_regs[i].reg,
4021				 wc_regs[i].val);
4022
4023	lane = elink_get_warpcore_lane(params);
4024	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4025			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * lane, 0x0990);
4026
4027}
4028
4029static elink_status_t elink_get_mod_abs_int_cfg(struct bnx2x_softc *sc,
4030						uint32_t shmem_base,
4031						uint8_t port,
4032						uint8_t * gpio_num,
4033						uint8_t * gpio_port)
4034{
4035	uint32_t cfg_pin;
4036	*gpio_num = 0;
4037	*gpio_port = 0;
4038	if (CHIP_IS_E3(sc)) {
4039		cfg_pin = (REG_RD(sc, shmem_base +
4040				  offsetof(struct shmem_region,
4041					   dev_info.port_hw_config[port].
4042					   e3_sfp_ctrl)) &
4043			   PORT_HW_CFG_E3_MOD_ABS_MASK) >>
4044		    PORT_HW_CFG_E3_MOD_ABS_SHIFT;
4045
4046		/* Should not happen. This function called upon interrupt
4047		 * triggered by GPIO ( since EPIO can only generate interrupts
4048		 * to MCP).
4049		 * So if this function was called and none of the GPIOs was set,
4050		 * it means the shit hit the fan.
4051		 */
4052		if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
4053		    (cfg_pin > PIN_CFG_GPIO3_P1)) {
4054			PMD_DRV_LOG(DEBUG,
4055				    "No cfg pin %x for module detect indication",
4056				    cfg_pin);
4057			return ELINK_STATUS_ERROR;
4058		}
4059
4060		*gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
4061		*gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
4062	} else {
4063		*gpio_num = MISC_REGISTERS_GPIO_3;
4064		*gpio_port = port;
4065	}
4066
4067	return ELINK_STATUS_OK;
4068}
4069
4070static int elink_is_sfp_module_plugged(struct elink_params *params)
4071{
4072	struct bnx2x_softc *sc = params->sc;
4073	uint8_t gpio_num, gpio_port;
4074	uint32_t gpio_val;
4075	if (elink_get_mod_abs_int_cfg(sc,
4076				      params->shmem_base, params->port,
4077				      &gpio_num, &gpio_port) != ELINK_STATUS_OK)
4078		return 0;
4079	gpio_val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
4080
4081	/* Call the handling function in case module is detected */
4082	if (gpio_val == 0)
4083		return 1;
4084	else
4085		return 0;
4086}
4087
4088static int elink_warpcore_get_sigdet(struct elink_phy *phy,
4089				     struct elink_params *params)
4090{
4091	uint16_t gp2_status_reg0, lane;
4092	struct bnx2x_softc *sc = params->sc;
4093
4094	lane = elink_get_warpcore_lane(params);
4095
4096	elink_cl45_read(sc, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
4097			&gp2_status_reg0);
4098
4099	return (gp2_status_reg0 >> (8 + lane)) & 0x1;
4100}
4101
4102static void elink_warpcore_config_runtime(struct elink_phy *phy,
4103					  struct elink_params *params,
4104					  struct elink_vars *vars)
4105{
4106	struct bnx2x_softc *sc = params->sc;
4107	uint32_t serdes_net_if;
4108	uint16_t gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
4109
4110	vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
4111
4112	if (!vars->turn_to_run_wc_rt)
4113		return;
4114
4115	if (vars->rx_tx_asic_rst) {
4116		uint16_t lane = elink_get_warpcore_lane(params);
4117		serdes_net_if = (REG_RD(sc, params->shmem_base +
4118					offsetof(struct shmem_region,
4119						 dev_info.port_hw_config
4120						 [params->port].
4121						 default_cfg)) &
4122				 PORT_HW_CFG_NET_SERDES_IF_MASK);
4123
4124		switch (serdes_net_if) {
4125		case PORT_HW_CFG_NET_SERDES_IF_KR:
4126			/* Do we get link yet? */
4127			elink_cl45_read(sc, phy, MDIO_WC_DEVAD, 0x81d1,
4128					&gp_status1);
4129			lnkup = (gp_status1 >> (8 + lane)) & 0x1;	/* 1G */
4130			/*10G KR */
4131			lnkup_kr = (gp_status1 >> (12 + lane)) & 0x1;
4132
4133			if (lnkup_kr || lnkup) {
4134				vars->rx_tx_asic_rst = 0;
4135			} else {
4136				/* Reset the lane to see if link comes up. */
4137				elink_warpcore_reset_lane(sc, phy, 1);
4138				elink_warpcore_reset_lane(sc, phy, 0);
4139
4140				/* Restart Autoneg */
4141				elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4142						 MDIO_WC_REG_IEEE0BLK_MIICNTL,
4143						 0x1200);
4144
4145				vars->rx_tx_asic_rst--;
4146				PMD_DRV_LOG(DEBUG, "0x%x retry left",
4147					    vars->rx_tx_asic_rst);
4148			}
4149			break;
4150
4151		default:
4152			break;
4153		}
4154
4155	}
4156	/*params->rx_tx_asic_rst */
4157}
4158
4159static void elink_warpcore_config_sfi(struct elink_phy *phy,
4160				      struct elink_params *params)
4161{
4162	uint16_t lane = elink_get_warpcore_lane(params);
4163
4164	elink_warpcore_clear_regs(phy, params, lane);
4165	if ((params->req_line_speed[ELINK_LINK_CONFIG_IDX(ELINK_INT_PHY)] ==
4166	     ELINK_SPEED_10000) &&
4167	    (phy->media_type != ELINK_ETH_PHY_SFP_1G_FIBER)) {
4168		PMD_DRV_LOG(DEBUG, "Setting 10G SFI");
4169		elink_warpcore_set_10G_XFI(phy, params, 0);
4170	} else {
4171		PMD_DRV_LOG(DEBUG, "Setting 1G Fiber");
4172		elink_warpcore_set_sgmii_speed(phy, params, 1, 0);
4173	}
4174}
4175
4176static void elink_sfp_e3_set_transmitter(struct elink_params *params,
4177					 struct elink_phy *phy, uint8_t tx_en)
4178{
4179	struct bnx2x_softc *sc = params->sc;
4180	uint32_t cfg_pin;
4181	uint8_t port = params->port;
4182
4183	cfg_pin = REG_RD(sc, params->shmem_base +
4184			 offsetof(struct shmem_region,
4185				  dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4186	    PORT_HW_CFG_E3_TX_LASER_MASK;
4187	/* Set the !tx_en since this pin is DISABLE_TX_LASER */
4188	PMD_DRV_LOG(DEBUG, "Setting WC TX to %d", tx_en);
4189
4190	/* For 20G, the expected pin to be used is 3 pins after the current */
4191	elink_set_cfg_pin(sc, cfg_pin, tx_en ^ 1);
4192	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
4193		elink_set_cfg_pin(sc, cfg_pin + 3, tx_en ^ 1);
4194}
4195
4196static void elink_warpcore_config_init(struct elink_phy *phy,
4197				       struct elink_params *params,
4198				       struct elink_vars *vars)
4199{
4200	struct bnx2x_softc *sc = params->sc;
4201	uint32_t serdes_net_if;
4202	uint8_t fiber_mode;
4203	uint16_t lane = elink_get_warpcore_lane(params);
4204	serdes_net_if = (REG_RD(sc, params->shmem_base +
4205				offsetof(struct shmem_region,
4206					 dev_info.port_hw_config[params->port].
4207					 default_cfg)) &
4208			 PORT_HW_CFG_NET_SERDES_IF_MASK);
4209	PMD_DRV_LOG(DEBUG,
4210		    "Begin Warpcore init, link_speed %d, "
4211		    "serdes_net_if = 0x%x", vars->line_speed, serdes_net_if);
4212	elink_set_aer_mmd(params, phy);
4213	elink_warpcore_reset_lane(sc, phy, 1);
4214	vars->phy_flags |= PHY_XGXS_FLAG;
4215	if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
4216	    (phy->req_line_speed &&
4217	     ((phy->req_line_speed == ELINK_SPEED_100) ||
4218	      (phy->req_line_speed == ELINK_SPEED_10)))) {
4219		vars->phy_flags |= PHY_SGMII_FLAG;
4220		PMD_DRV_LOG(DEBUG, "Setting SGMII mode");
4221		elink_warpcore_clear_regs(phy, params, lane);
4222		elink_warpcore_set_sgmii_speed(phy, params, 0, 1);
4223	} else {
4224		switch (serdes_net_if) {
4225		case PORT_HW_CFG_NET_SERDES_IF_KR:
4226			/* Enable KR Auto Neg */
4227			if (params->loopback_mode != ELINK_LOOPBACK_EXT)
4228				elink_warpcore_enable_AN_KR(phy, params, vars);
4229			else {
4230				PMD_DRV_LOG(DEBUG, "Setting KR 10G-Force");
4231				elink_warpcore_set_10G_KR(phy, params);
4232			}
4233			break;
4234
4235		case PORT_HW_CFG_NET_SERDES_IF_XFI:
4236			elink_warpcore_clear_regs(phy, params, lane);
4237			if (vars->line_speed == ELINK_SPEED_10000) {
4238				PMD_DRV_LOG(DEBUG, "Setting 10G XFI");
4239				elink_warpcore_set_10G_XFI(phy, params, 1);
4240			} else {
4241				if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
4242					PMD_DRV_LOG(DEBUG, "1G Fiber");
4243					fiber_mode = 1;
4244				} else {
4245					PMD_DRV_LOG(DEBUG, "10/100/1G SGMII");
4246					fiber_mode = 0;
4247				}
4248				elink_warpcore_set_sgmii_speed(phy,
4249							       params,
4250							       fiber_mode, 0);
4251			}
4252
4253			break;
4254
4255		case PORT_HW_CFG_NET_SERDES_IF_SFI:
4256			/* Issue Module detection if module is plugged, or
4257			 * enabled transmitter to avoid current leakage in case
4258			 * no module is connected
4259			 */
4260			if ((params->loopback_mode == ELINK_LOOPBACK_NONE) ||
4261			    (params->loopback_mode == ELINK_LOOPBACK_EXT)) {
4262				if (elink_is_sfp_module_plugged(params))
4263					elink_sfp_module_detection(phy, params);
4264				else
4265					elink_sfp_e3_set_transmitter(params,
4266								     phy, 1);
4267			}
4268
4269			elink_warpcore_config_sfi(phy, params);
4270			break;
4271
4272		case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
4273			if (vars->line_speed != ELINK_SPEED_20000) {
4274				PMD_DRV_LOG(DEBUG, "Speed not supported yet");
4275				return;
4276			}
4277			PMD_DRV_LOG(DEBUG, "Setting 20G DXGXS");
4278			elink_warpcore_set_20G_DXGXS(sc, phy, lane);
4279			/* Issue Module detection */
4280
4281			elink_sfp_module_detection(phy, params);
4282			break;
4283		case PORT_HW_CFG_NET_SERDES_IF_KR2:
4284			if (!params->loopback_mode) {
4285				elink_warpcore_enable_AN_KR(phy, params, vars);
4286			} else {
4287				PMD_DRV_LOG(DEBUG, "Setting KR 20G-Force");
4288				elink_warpcore_set_20G_force_KR2(phy, params);
4289			}
4290			break;
4291		default:
4292			PMD_DRV_LOG(DEBUG,
4293				    "Unsupported Serdes Net Interface 0x%x",
4294				    serdes_net_if);
4295			return;
4296		}
4297	}
4298
4299	/* Take lane out of reset after configuration is finished */
4300	elink_warpcore_reset_lane(sc, phy, 0);
4301	PMD_DRV_LOG(DEBUG, "Exit config init");
4302}
4303
4304static void elink_warpcore_link_reset(struct elink_phy *phy,
4305				      struct elink_params *params)
4306{
4307	struct bnx2x_softc *sc = params->sc;
4308	uint16_t val16, lane;
4309	elink_sfp_e3_set_transmitter(params, phy, 0);
4310	elink_set_mdio_emac_per_phy(sc, params);
4311	elink_set_aer_mmd(params, phy);
4312	/* Global register */
4313	elink_warpcore_reset_lane(sc, phy, 1);
4314
4315	/* Clear loopback settings (if any) */
4316	/* 10G & 20G */
4317	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4318				  MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0xBFFF);
4319
4320	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4321				  MDIO_WC_REG_IEEE0BLK_MIICNTL, 0xfffe);
4322
4323	/* Update those 1-copy registers */
4324	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4325			  MDIO_AER_BLOCK_AER_REG, 0);
4326	/* Enable 1G MDIO (1-copy) */
4327	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4328				  MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, ~0x10);
4329
4330	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4331				  MDIO_WC_REG_XGXSBLK1_LANECTRL2, 0xff00);
4332	lane = elink_get_warpcore_lane(params);
4333	/* Disable CL36 PCS Tx */
4334	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4335			MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
4336	val16 |= (0x11 << lane);
4337	if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
4338		val16 |= (0x22 << lane);
4339	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4340			 MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
4341
4342	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4343			MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
4344	val16 &= ~(0x0303 << (lane << 1));
4345	val16 |= (0x0101 << (lane << 1));
4346	if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE) {
4347		val16 &= ~(0x0c0c << (lane << 1));
4348		val16 |= (0x0404 << (lane << 1));
4349	}
4350
4351	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4352			 MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
4353	/* Restore AER */
4354	elink_set_aer_mmd(params, phy);
4355
4356}
4357
4358static void elink_set_warpcore_loopback(struct elink_phy *phy,
4359					struct elink_params *params)
4360{
4361	struct bnx2x_softc *sc = params->sc;
4362	uint16_t val16;
4363	uint32_t lane;
4364	PMD_DRV_LOG(DEBUG, "Setting Warpcore loopback type %x, speed %d",
4365		    params->loopback_mode, phy->req_line_speed);
4366
4367	if (phy->req_line_speed < ELINK_SPEED_10000 ||
4368	    phy->supported & ELINK_SUPPORTED_20000baseKR2_Full) {
4369		/* 10/100/1000/20G-KR2 */
4370
4371		/* Update those 1-copy registers */
4372		CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4373				  MDIO_AER_BLOCK_AER_REG, 0);
4374		/* Enable 1G MDIO (1-copy) */
4375		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4376					 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4377					 0x10);
4378		/* Set 1G loopback based on lane (1-copy) */
4379		lane = elink_get_warpcore_lane(params);
4380		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4381				MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4382		val16 |= (1 << lane);
4383		if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
4384			val16 |= (2 << lane);
4385		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4386				 MDIO_WC_REG_XGXSBLK1_LANECTRL2, val16);
4387
4388		/* Switch back to 4-copy registers */
4389		elink_set_aer_mmd(params, phy);
4390	} else {
4391		/* 10G / 20G-DXGXS */
4392		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4393					 MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
4394					 0x4000);
4395		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4396					 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1);
4397	}
4398}
4399
4400static void elink_sync_link(struct elink_params *params,
4401			    struct elink_vars *vars)
4402{
4403	struct bnx2x_softc *sc = params->sc;
4404	uint8_t link_10g_plus;
4405	if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4406		vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
4407	vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
4408	if (vars->link_up) {
4409		PMD_DRV_LOG(DEBUG, "phy link up");
4410
4411		vars->phy_link_up = 1;
4412		vars->duplex = DUPLEX_FULL;
4413		switch (vars->link_status & LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
4414		case ELINK_LINK_10THD:
4415			vars->duplex = DUPLEX_HALF;
4416			/* Fall thru */
4417		case ELINK_LINK_10TFD:
4418			vars->line_speed = ELINK_SPEED_10;
4419			break;
4420
4421		case ELINK_LINK_100TXHD:
4422			vars->duplex = DUPLEX_HALF;
4423			/* Fall thru */
4424		case ELINK_LINK_100T4:
4425		case ELINK_LINK_100TXFD:
4426			vars->line_speed = ELINK_SPEED_100;
4427			break;
4428
4429		case ELINK_LINK_1000THD:
4430			vars->duplex = DUPLEX_HALF;
4431			/* Fall thru */
4432		case ELINK_LINK_1000TFD:
4433			vars->line_speed = ELINK_SPEED_1000;
4434			break;
4435
4436		case ELINK_LINK_2500THD:
4437			vars->duplex = DUPLEX_HALF;
4438			/* Fall thru */
4439		case ELINK_LINK_2500TFD:
4440			vars->line_speed = ELINK_SPEED_2500;
4441			break;
4442
4443		case ELINK_LINK_10GTFD:
4444			vars->line_speed = ELINK_SPEED_10000;
4445			break;
4446		case ELINK_LINK_20GTFD:
4447			vars->line_speed = ELINK_SPEED_20000;
4448			break;
4449		default:
4450			break;
4451		}
4452		vars->flow_ctrl = 0;
4453		if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
4454			vars->flow_ctrl |= ELINK_FLOW_CTRL_TX;
4455
4456		if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
4457			vars->flow_ctrl |= ELINK_FLOW_CTRL_RX;
4458
4459		if (!vars->flow_ctrl)
4460			vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
4461
4462		if (vars->line_speed &&
4463		    ((vars->line_speed == ELINK_SPEED_10) ||
4464		     (vars->line_speed == ELINK_SPEED_100))) {
4465			vars->phy_flags |= PHY_SGMII_FLAG;
4466		} else {
4467			vars->phy_flags &= ~PHY_SGMII_FLAG;
4468		}
4469		if (vars->line_speed &&
4470		    USES_WARPCORE(sc) && (vars->line_speed == ELINK_SPEED_1000))
4471			vars->phy_flags |= PHY_SGMII_FLAG;
4472		/* Anything 10 and over uses the bmac */
4473		link_10g_plus = (vars->line_speed >= ELINK_SPEED_10000);
4474
4475		if (link_10g_plus) {
4476			if (USES_WARPCORE(sc))
4477				vars->mac_type = ELINK_MAC_TYPE_XMAC;
4478			else
4479				vars->mac_type = ELINK_MAC_TYPE_BMAC;
4480		} else {
4481			if (USES_WARPCORE(sc))
4482				vars->mac_type = ELINK_MAC_TYPE_UMAC;
4483			else
4484				vars->mac_type = ELINK_MAC_TYPE_EMAC;
4485		}
4486	} else {		/* Link down */
4487		PMD_DRV_LOG(DEBUG, "phy link down");
4488
4489		vars->phy_link_up = 0;
4490
4491		vars->line_speed = 0;
4492		vars->duplex = DUPLEX_FULL;
4493		vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
4494
4495		/* Indicate no mac active */
4496		vars->mac_type = ELINK_MAC_TYPE_NONE;
4497		if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4498			vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
4499		if (vars->link_status & LINK_STATUS_SFP_TX_FAULT)
4500			vars->phy_flags |= PHY_SFP_TX_FAULT_FLAG;
4501	}
4502}
4503
4504void elink_link_status_update(struct elink_params *params,
4505			      struct elink_vars *vars)
4506{
4507	struct bnx2x_softc *sc = params->sc;
4508	uint8_t port = params->port;
4509	uint32_t sync_offset, media_types;
4510	/* Update PHY configuration */
4511	set_phy_vars(params, vars);
4512
4513	vars->link_status = REG_RD(sc, params->shmem_base +
4514				   offsetof(struct shmem_region,
4515					    port_mb[port].link_status));
4516
4517	/* Force link UP in non LOOPBACK_EXT loopback mode(s) */
4518	if (params->loopback_mode != ELINK_LOOPBACK_NONE &&
4519	    params->loopback_mode != ELINK_LOOPBACK_EXT)
4520		vars->link_status |= LINK_STATUS_LINK_UP;
4521
4522	if (elink_eee_has_cap(params))
4523		vars->eee_status = REG_RD(sc, params->shmem2_base +
4524					  offsetof(struct shmem2_region,
4525						   eee_status[params->port]));
4526
4527	vars->phy_flags = PHY_XGXS_FLAG;
4528	elink_sync_link(params, vars);
4529	/* Sync media type */
4530	sync_offset = params->shmem_base +
4531	    offsetof(struct shmem_region,
4532		     dev_info.port_hw_config[port].media_type);
4533	media_types = REG_RD(sc, sync_offset);
4534
4535	params->phy[ELINK_INT_PHY].media_type =
4536	    (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
4537	    PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
4538	params->phy[ELINK_EXT_PHY1].media_type =
4539	    (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
4540	    PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
4541	params->phy[ELINK_EXT_PHY2].media_type =
4542	    (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
4543	    PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
4544	PMD_DRV_LOG(DEBUG, "media_types = 0x%x", media_types);
4545
4546	/* Sync AEU offset */
4547	sync_offset = params->shmem_base +
4548	    offsetof(struct shmem_region,
4549		     dev_info.port_hw_config[port].aeu_int_mask);
4550
4551	vars->aeu_int_mask = REG_RD(sc, sync_offset);
4552
4553	/* Sync PFC status */
4554	if (vars->link_status & LINK_STATUS_PFC_ENABLED)
4555		params->feature_config_flags |=
4556		    ELINK_FEATURE_CONFIG_PFC_ENABLED;
4557	else
4558		params->feature_config_flags &=
4559		    ~ELINK_FEATURE_CONFIG_PFC_ENABLED;
4560
4561	if (SHMEM2_HAS(sc, link_attr_sync))
4562		vars->link_attr_sync = SHMEM2_RD(sc,
4563						 link_attr_sync[params->port]);
4564
4565	PMD_DRV_LOG(DEBUG, "link_status 0x%x  phy_link_up %x int_mask 0x%x",
4566		    vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
4567	PMD_DRV_LOG(DEBUG, "line_speed %x  duplex %x  flow_ctrl 0x%x",
4568		    vars->line_speed, vars->duplex, vars->flow_ctrl);
4569}
4570
4571static void elink_set_master_ln(struct elink_params *params,
4572				struct elink_phy *phy)
4573{
4574	struct bnx2x_softc *sc = params->sc;
4575	uint16_t new_master_ln, ser_lane;
4576	ser_lane = ((params->lane_config &
4577		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4578		    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4579
4580	/* Set the master_ln for AN */
4581	CL22_RD_OVER_CL45(sc, phy,
4582			  MDIO_REG_BANK_XGXS_BLOCK2,
4583			  MDIO_XGXS_BLOCK2_TEST_MODE_LANE, &new_master_ln);
4584
4585	CL22_WR_OVER_CL45(sc, phy,
4586			  MDIO_REG_BANK_XGXS_BLOCK2,
4587			  MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4588			  (new_master_ln | ser_lane));
4589}
4590
4591static elink_status_t elink_reset_unicore(struct elink_params *params,
4592					  struct elink_phy *phy,
4593					  uint8_t set_serdes)
4594{
4595	struct bnx2x_softc *sc = params->sc;
4596	uint16_t mii_control;
4597	uint16_t i;
4598	CL22_RD_OVER_CL45(sc, phy,
4599			  MDIO_REG_BANK_COMBO_IEEE0,
4600			  MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
4601
4602	/* Reset the unicore */
4603	CL22_WR_OVER_CL45(sc, phy,
4604			  MDIO_REG_BANK_COMBO_IEEE0,
4605			  MDIO_COMBO_IEEE0_MII_CONTROL,
4606			  (mii_control | MDIO_COMBO_IEEO_MII_CONTROL_RESET));
4607	if (set_serdes)
4608		elink_set_serdes_access(sc, params->port);
4609
4610	/* Wait for the reset to self clear */
4611	for (i = 0; i < ELINK_MDIO_ACCESS_TIMEOUT; i++) {
4612		DELAY(5);
4613
4614		/* The reset erased the previous bank value */
4615		CL22_RD_OVER_CL45(sc, phy,
4616				  MDIO_REG_BANK_COMBO_IEEE0,
4617				  MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
4618
4619		if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
4620			DELAY(5);
4621			return ELINK_STATUS_OK;
4622		}
4623	}
4624
4625	elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED, params->port);	// "Warning: PHY was not initialized,"
4626	// " Port %d",
4627
4628	PMD_DRV_LOG(DEBUG, "BUG! XGXS is still in reset!");
4629	return ELINK_STATUS_ERROR;
4630
4631}
4632
4633static void elink_set_swap_lanes(struct elink_params *params,
4634				 struct elink_phy *phy)
4635{
4636	struct bnx2x_softc *sc = params->sc;
4637	/* Each two bits represents a lane number:
4638	 * No swap is 0123 => 0x1b no need to enable the swap
4639	 */
4640	uint16_t rx_lane_swap, tx_lane_swap;
4641
4642	rx_lane_swap = ((params->lane_config &
4643			 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
4644			PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
4645	tx_lane_swap = ((params->lane_config &
4646			 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
4647			PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
4648
4649	if (rx_lane_swap != 0x1b) {
4650		CL22_WR_OVER_CL45(sc, phy,
4651				  MDIO_REG_BANK_XGXS_BLOCK2,
4652				  MDIO_XGXS_BLOCK2_RX_LN_SWAP,
4653				  (rx_lane_swap |
4654				   MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
4655				   MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
4656	} else {
4657		CL22_WR_OVER_CL45(sc, phy,
4658				  MDIO_REG_BANK_XGXS_BLOCK2,
4659				  MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
4660	}
4661
4662	if (tx_lane_swap != 0x1b) {
4663		CL22_WR_OVER_CL45(sc, phy,
4664				  MDIO_REG_BANK_XGXS_BLOCK2,
4665				  MDIO_XGXS_BLOCK2_TX_LN_SWAP,
4666				  (tx_lane_swap |
4667				   MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
4668	} else {
4669		CL22_WR_OVER_CL45(sc, phy,
4670				  MDIO_REG_BANK_XGXS_BLOCK2,
4671				  MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
4672	}
4673}
4674
4675static void elink_set_parallel_detection(struct elink_phy *phy,
4676					 struct elink_params *params)
4677{
4678	struct bnx2x_softc *sc = params->sc;
4679	uint16_t control2;
4680	CL22_RD_OVER_CL45(sc, phy,
4681			  MDIO_REG_BANK_SERDES_DIGITAL,
4682			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, &control2);
4683	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4684		control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4685	else
4686		control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4687	PMD_DRV_LOG(DEBUG, "phy->speed_cap_mask = 0x%x, control2 = 0x%x",
4688		    phy->speed_cap_mask, control2);
4689	CL22_WR_OVER_CL45(sc, phy,
4690			  MDIO_REG_BANK_SERDES_DIGITAL,
4691			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, control2);
4692
4693	if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
4694	    (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
4695		PMD_DRV_LOG(DEBUG, "XGXS");
4696
4697		CL22_WR_OVER_CL45(sc, phy,
4698				  MDIO_REG_BANK_10G_PARALLEL_DETECT,
4699				  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
4700				  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
4701
4702		CL22_RD_OVER_CL45(sc, phy,
4703				  MDIO_REG_BANK_10G_PARALLEL_DETECT,
4704				  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4705				  &control2);
4706
4707		control2 |=
4708		    MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
4709
4710		CL22_WR_OVER_CL45(sc, phy,
4711				  MDIO_REG_BANK_10G_PARALLEL_DETECT,
4712				  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4713				  control2);
4714
4715		/* Disable parallel detection of HiG */
4716		CL22_WR_OVER_CL45(sc, phy,
4717				  MDIO_REG_BANK_XGXS_BLOCK2,
4718				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
4719				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
4720				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
4721	}
4722}
4723
4724static void elink_set_autoneg(struct elink_phy *phy,
4725			      struct elink_params *params,
4726			      struct elink_vars *vars, uint8_t enable_cl73)
4727{
4728	struct bnx2x_softc *sc = params->sc;
4729	uint16_t reg_val;
4730
4731	/* CL37 Autoneg */
4732	CL22_RD_OVER_CL45(sc, phy,
4733			  MDIO_REG_BANK_COMBO_IEEE0,
4734			  MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4735
4736	/* CL37 Autoneg Enabled */
4737	if (vars->line_speed == ELINK_SPEED_AUTO_NEG)
4738		reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
4739	else			/* CL37 Autoneg Disabled */
4740		reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4741			     MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
4742
4743	CL22_WR_OVER_CL45(sc, phy,
4744			  MDIO_REG_BANK_COMBO_IEEE0,
4745			  MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4746
4747	/* Enable/Disable Autodetection */
4748
4749	CL22_RD_OVER_CL45(sc, phy,
4750			  MDIO_REG_BANK_SERDES_DIGITAL,
4751			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
4752	reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
4753		     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
4754	reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
4755	if (vars->line_speed == ELINK_SPEED_AUTO_NEG)
4756		reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4757	else
4758		reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4759
4760	CL22_WR_OVER_CL45(sc, phy,
4761			  MDIO_REG_BANK_SERDES_DIGITAL,
4762			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
4763
4764	/* Enable TetonII and BAM autoneg */
4765	CL22_RD_OVER_CL45(sc, phy,
4766			  MDIO_REG_BANK_BAM_NEXT_PAGE,
4767			  MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, &reg_val);
4768	if (vars->line_speed == ELINK_SPEED_AUTO_NEG) {
4769		/* Enable BAM aneg Mode and TetonII aneg Mode */
4770		reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4771			    MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4772	} else {
4773		/* TetonII and BAM Autoneg Disabled */
4774		reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4775			     MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4776	}
4777	CL22_WR_OVER_CL45(sc, phy,
4778			  MDIO_REG_BANK_BAM_NEXT_PAGE,
4779			  MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, reg_val);
4780
4781	if (enable_cl73) {
4782		/* Enable Cl73 FSM status bits */
4783		CL22_WR_OVER_CL45(sc, phy,
4784				  MDIO_REG_BANK_CL73_USERB0,
4785				  MDIO_CL73_USERB0_CL73_UCTRL, 0xe);
4786
4787		/* Enable BAM Station Manager */
4788		CL22_WR_OVER_CL45(sc, phy,
4789				  MDIO_REG_BANK_CL73_USERB0,
4790				  MDIO_CL73_USERB0_CL73_BAM_CTRL1,
4791				  MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
4792				  MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN
4793				  |
4794				  MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
4795
4796		/* Advertise CL73 link speeds */
4797		CL22_RD_OVER_CL45(sc, phy,
4798				  MDIO_REG_BANK_CL73_IEEEB1,
4799				  MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
4800		if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4801			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
4802		if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4803			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
4804
4805		CL22_WR_OVER_CL45(sc, phy,
4806				  MDIO_REG_BANK_CL73_IEEEB1,
4807				  MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
4808
4809		/* CL73 Autoneg Enabled */
4810		reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
4811
4812	} else			/* CL73 Autoneg Disabled */
4813		reg_val = 0;
4814
4815	CL22_WR_OVER_CL45(sc, phy,
4816			  MDIO_REG_BANK_CL73_IEEEB0,
4817			  MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
4818}
4819
4820/* Program SerDes, forced speed */
4821static void elink_program_serdes(struct elink_phy *phy,
4822				 struct elink_params *params,
4823				 struct elink_vars *vars)
4824{
4825	struct bnx2x_softc *sc = params->sc;
4826	uint16_t reg_val;
4827
4828	/* Program duplex, disable autoneg and sgmii */
4829	CL22_RD_OVER_CL45(sc, phy,
4830			  MDIO_REG_BANK_COMBO_IEEE0,
4831			  MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4832	reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
4833		     MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4834		     MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
4835	if (phy->req_duplex == DUPLEX_FULL)
4836		reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
4837	CL22_WR_OVER_CL45(sc, phy,
4838			  MDIO_REG_BANK_COMBO_IEEE0,
4839			  MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4840
4841	/* Program speed
4842	 *  - needed only if the speed is greater than 1G (2.5G or 10G)
4843	 */
4844	CL22_RD_OVER_CL45(sc, phy,
4845			  MDIO_REG_BANK_SERDES_DIGITAL,
4846			  MDIO_SERDES_DIGITAL_MISC1, &reg_val);
4847	/* Clearing the speed value before setting the right speed */
4848	PMD_DRV_LOG(DEBUG, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x", reg_val);
4849
4850	reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
4851		     MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
4852
4853	if (!((vars->line_speed == ELINK_SPEED_1000) ||
4854	      (vars->line_speed == ELINK_SPEED_100) ||
4855	      (vars->line_speed == ELINK_SPEED_10))) {
4856
4857		reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
4858			    MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
4859		if (vars->line_speed == ELINK_SPEED_10000)
4860			reg_val |=
4861			    MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
4862	}
4863
4864	CL22_WR_OVER_CL45(sc, phy,
4865			  MDIO_REG_BANK_SERDES_DIGITAL,
4866			  MDIO_SERDES_DIGITAL_MISC1, reg_val);
4867
4868}
4869
4870static void elink_set_brcm_cl37_advertisement(struct elink_phy *phy,
4871					      struct elink_params *params)
4872{
4873	struct bnx2x_softc *sc = params->sc;
4874	uint16_t val = 0;
4875
4876	/* Set extended capabilities */
4877	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
4878		val |= MDIO_OVER_1G_UP1_2_5G;
4879	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4880		val |= MDIO_OVER_1G_UP1_10G;
4881	CL22_WR_OVER_CL45(sc, phy,
4882			  MDIO_REG_BANK_OVER_1G, MDIO_OVER_1G_UP1, val);
4883
4884	CL22_WR_OVER_CL45(sc, phy,
4885			  MDIO_REG_BANK_OVER_1G, MDIO_OVER_1G_UP3, 0x400);
4886}
4887
4888static void elink_set_ieee_aneg_advertisement(struct elink_phy *phy,
4889					      struct elink_params *params,
4890					      uint16_t ieee_fc)
4891{
4892	struct bnx2x_softc *sc = params->sc;
4893	uint16_t val;
4894	/* For AN, we are always publishing full duplex */
4895
4896	CL22_WR_OVER_CL45(sc, phy,
4897			  MDIO_REG_BANK_COMBO_IEEE0,
4898			  MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
4899	CL22_RD_OVER_CL45(sc, phy,
4900			  MDIO_REG_BANK_CL73_IEEEB1,
4901			  MDIO_CL73_IEEEB1_AN_ADV1, &val);
4902	val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
4903	val |= ((ieee_fc << 3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
4904	CL22_WR_OVER_CL45(sc, phy,
4905			  MDIO_REG_BANK_CL73_IEEEB1,
4906			  MDIO_CL73_IEEEB1_AN_ADV1, val);
4907}
4908
4909static void elink_restart_autoneg(struct elink_phy *phy,
4910				  struct elink_params *params,
4911				  uint8_t enable_cl73)
4912{
4913	struct bnx2x_softc *sc = params->sc;
4914	uint16_t mii_control;
4915
4916	PMD_DRV_LOG(DEBUG, "elink_restart_autoneg");
4917	/* Enable and restart BAM/CL37 aneg */
4918
4919	if (enable_cl73) {
4920		CL22_RD_OVER_CL45(sc, phy,
4921				  MDIO_REG_BANK_CL73_IEEEB0,
4922				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
4923				  &mii_control);
4924
4925		CL22_WR_OVER_CL45(sc, phy,
4926				  MDIO_REG_BANK_CL73_IEEEB0,
4927				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
4928				  (mii_control |
4929				   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
4930				   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
4931	} else {
4932
4933		CL22_RD_OVER_CL45(sc, phy,
4934				  MDIO_REG_BANK_COMBO_IEEE0,
4935				  MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
4936		PMD_DRV_LOG(DEBUG,
4937			    "elink_restart_autoneg mii_control before = 0x%x",
4938			    mii_control);
4939		CL22_WR_OVER_CL45(sc, phy,
4940				  MDIO_REG_BANK_COMBO_IEEE0,
4941				  MDIO_COMBO_IEEE0_MII_CONTROL,
4942				  (mii_control |
4943				   MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4944				   MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
4945	}
4946}
4947
4948static void elink_initialize_sgmii_process(struct elink_phy *phy,
4949					   struct elink_params *params,
4950					   struct elink_vars *vars)
4951{
4952	struct bnx2x_softc *sc = params->sc;
4953	uint16_t control1;
4954
4955	/* In SGMII mode, the unicore is always slave */
4956
4957	CL22_RD_OVER_CL45(sc, phy,
4958			  MDIO_REG_BANK_SERDES_DIGITAL,
4959			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &control1);
4960	control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
4961	/* Set sgmii mode (and not fiber) */
4962	control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
4963		      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
4964		      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
4965	CL22_WR_OVER_CL45(sc, phy,
4966			  MDIO_REG_BANK_SERDES_DIGITAL,
4967			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, control1);
4968
4969	/* If forced speed */
4970	if (!(vars->line_speed == ELINK_SPEED_AUTO_NEG)) {
4971		/* Set speed, disable autoneg */
4972		uint16_t mii_control;
4973
4974		CL22_RD_OVER_CL45(sc, phy,
4975				  MDIO_REG_BANK_COMBO_IEEE0,
4976				  MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
4977		mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4978				 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK |
4979				 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
4980
4981		switch (vars->line_speed) {
4982		case ELINK_SPEED_100:
4983			mii_control |=
4984			    MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
4985			break;
4986		case ELINK_SPEED_1000:
4987			mii_control |=
4988			    MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
4989			break;
4990		case ELINK_SPEED_10:
4991			/* There is nothing to set for 10M */
4992			break;
4993		default:
4994			/* Invalid speed for SGMII */
4995			PMD_DRV_LOG(DEBUG, "Invalid line_speed 0x%x",
4996				    vars->line_speed);
4997			break;
4998		}
4999
5000		/* Setting the full duplex */
5001		if (phy->req_duplex == DUPLEX_FULL)
5002			mii_control |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
5003		CL22_WR_OVER_CL45(sc, phy,
5004				  MDIO_REG_BANK_COMBO_IEEE0,
5005				  MDIO_COMBO_IEEE0_MII_CONTROL, mii_control);
5006
5007	} else {		/* AN mode */
5008		/* Enable and restart AN */
5009		elink_restart_autoneg(phy, params, 0);
5010	}
5011}
5012
5013/* Link management
5014 */
5015static elink_status_t elink_direct_parallel_detect_used(struct elink_phy *phy,
5016							struct elink_params
5017							*params)
5018{
5019	struct bnx2x_softc *sc = params->sc;
5020	uint16_t pd_10g, status2_1000x;
5021	if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
5022		return ELINK_STATUS_OK;
5023	CL22_RD_OVER_CL45(sc, phy,
5024			  MDIO_REG_BANK_SERDES_DIGITAL,
5025			  MDIO_SERDES_DIGITAL_A_1000X_STATUS2, &status2_1000x);
5026	CL22_RD_OVER_CL45(sc, phy,
5027			  MDIO_REG_BANK_SERDES_DIGITAL,
5028			  MDIO_SERDES_DIGITAL_A_1000X_STATUS2, &status2_1000x);
5029	if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
5030		PMD_DRV_LOG(DEBUG, "1G parallel detect link on port %d",
5031			    params->port);
5032		return ELINK_STATUS_ERROR;
5033	}
5034
5035	CL22_RD_OVER_CL45(sc, phy,
5036			  MDIO_REG_BANK_10G_PARALLEL_DETECT,
5037			  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS, &pd_10g);
5038
5039	if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
5040		PMD_DRV_LOG(DEBUG, "10G parallel detect link on port %d",
5041			    params->port);
5042		return ELINK_STATUS_ERROR;
5043	}
5044	return ELINK_STATUS_OK;
5045}
5046
5047static void elink_update_adv_fc(struct elink_phy *phy,
5048				struct elink_params *params,
5049				struct elink_vars *vars, uint32_t gp_status)
5050{
5051	uint16_t ld_pause;	/* local driver */
5052	uint16_t lp_pause;	/* link partner */
5053	uint16_t pause_result;
5054	struct bnx2x_softc *sc = params->sc;
5055	if ((gp_status &
5056	     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5057	      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
5058	    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5059	     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
5060
5061		CL22_RD_OVER_CL45(sc, phy,
5062				  MDIO_REG_BANK_CL73_IEEEB1,
5063				  MDIO_CL73_IEEEB1_AN_ADV1, &ld_pause);
5064		CL22_RD_OVER_CL45(sc, phy,
5065				  MDIO_REG_BANK_CL73_IEEEB1,
5066				  MDIO_CL73_IEEEB1_AN_LP_ADV1, &lp_pause);
5067		pause_result = (ld_pause &
5068				MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) >> 8;
5069		pause_result |= (lp_pause &
5070				 MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK) >> 10;
5071		PMD_DRV_LOG(DEBUG, "pause_result CL73 0x%x", pause_result);
5072	} else {
5073		CL22_RD_OVER_CL45(sc, phy,
5074				  MDIO_REG_BANK_COMBO_IEEE0,
5075				  MDIO_COMBO_IEEE0_AUTO_NEG_ADV, &ld_pause);
5076		CL22_RD_OVER_CL45(sc, phy,
5077				  MDIO_REG_BANK_COMBO_IEEE0,
5078				  MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
5079				  &lp_pause);
5080		pause_result = (ld_pause &
5081				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) >> 5;
5082		pause_result |= (lp_pause &
5083				 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) >> 7;
5084		PMD_DRV_LOG(DEBUG, "pause_result CL37 0x%x", pause_result);
5085	}
5086	elink_pause_resolve(vars, pause_result);
5087
5088}
5089
5090static void elink_flow_ctrl_resolve(struct elink_phy *phy,
5091				    struct elink_params *params,
5092				    struct elink_vars *vars, uint32_t gp_status)
5093{
5094	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
5095
5096	/* Resolve from gp_status in case of AN complete and not sgmii */
5097	if (phy->req_flow_ctrl != ELINK_FLOW_CTRL_AUTO) {
5098		/* Update the advertised flow-controled of LD/LP in AN */
5099		if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
5100			elink_update_adv_fc(phy, params, vars, gp_status);
5101		/* But set the flow-control result as the requested one */
5102		vars->flow_ctrl = phy->req_flow_ctrl;
5103	} else if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
5104		vars->flow_ctrl = params->req_fc_auto_adv;
5105	else if ((gp_status & ELINK_MDIO_AN_CL73_OR_37_COMPLETE) &&
5106		 (!(vars->phy_flags & PHY_SGMII_FLAG))) {
5107		if (elink_direct_parallel_detect_used(phy, params)) {
5108			vars->flow_ctrl = params->req_fc_auto_adv;
5109			return;
5110		}
5111		elink_update_adv_fc(phy, params, vars, gp_status);
5112	}
5113	PMD_DRV_LOG(DEBUG, "flow_ctrl 0x%x", vars->flow_ctrl);
5114}
5115
5116static void elink_check_fallback_to_cl37(struct elink_phy *phy,
5117					 struct elink_params *params)
5118{
5119	struct bnx2x_softc *sc = params->sc;
5120	uint16_t rx_status, ustat_val, cl37_fsm_received;
5121	PMD_DRV_LOG(DEBUG, "elink_check_fallback_to_cl37");
5122	/* Step 1: Make sure signal is detected */
5123	CL22_RD_OVER_CL45(sc, phy,
5124			  MDIO_REG_BANK_RX0, MDIO_RX0_RX_STATUS, &rx_status);
5125	if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
5126	    (MDIO_RX0_RX_STATUS_SIGDET)) {
5127		PMD_DRV_LOG(DEBUG, "Signal is not detected. Restoring CL73."
5128			    "rx_status(0x80b0) = 0x%x", rx_status);
5129		CL22_WR_OVER_CL45(sc, phy,
5130				  MDIO_REG_BANK_CL73_IEEEB0,
5131				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5132				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
5133		return;
5134	}
5135	/* Step 2: Check CL73 state machine */
5136	CL22_RD_OVER_CL45(sc, phy,
5137			  MDIO_REG_BANK_CL73_USERB0,
5138			  MDIO_CL73_USERB0_CL73_USTAT1, &ustat_val);
5139	if ((ustat_val &
5140	     (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5141	      MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
5142	    (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5143	     MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
5144		PMD_DRV_LOG(DEBUG, "CL73 state-machine is not stable. "
5145			    "ustat_val(0x8371) = 0x%x", ustat_val);
5146		return;
5147	}
5148	/* Step 3: Check CL37 Message Pages received to indicate LP
5149	 * supports only CL37
5150	 */
5151	CL22_RD_OVER_CL45(sc, phy,
5152			  MDIO_REG_BANK_REMOTE_PHY,
5153			  MDIO_REMOTE_PHY_MISC_RX_STATUS, &cl37_fsm_received);
5154	if ((cl37_fsm_received &
5155	     (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5156	      MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
5157	    (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5158	     MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
5159		PMD_DRV_LOG(DEBUG, "No CL37 FSM were received. "
5160			    "misc_rx_status(0x8330) = 0x%x", cl37_fsm_received);
5161		return;
5162	}
5163	/* The combined cl37/cl73 fsm state information indicating that
5164	 * we are connected to a device which does not support cl73, but
5165	 * does support cl37 BAM. In this case we disable cl73 and
5166	 * restart cl37 auto-neg
5167	 */
5168
5169	/* Disable CL73 */
5170	CL22_WR_OVER_CL45(sc, phy,
5171			  MDIO_REG_BANK_CL73_IEEEB0,
5172			  MDIO_CL73_IEEEB0_CL73_AN_CONTROL, 0);
5173	/* Restart CL37 autoneg */
5174	elink_restart_autoneg(phy, params, 0);
5175	PMD_DRV_LOG(DEBUG, "Disabling CL73, and restarting CL37 autoneg");
5176}
5177
5178static void elink_xgxs_an_resolve(struct elink_phy *phy,
5179				  struct elink_params *params,
5180				  struct elink_vars *vars, uint32_t gp_status)
5181{
5182	if (gp_status & ELINK_MDIO_AN_CL73_OR_37_COMPLETE)
5183		vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5184
5185	if (elink_direct_parallel_detect_used(phy, params))
5186		vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
5187}
5188
5189static elink_status_t elink_get_link_speed_duplex(struct elink_phy *phy,
5190						  struct elink_params *params __rte_unused,
5191						  struct elink_vars *vars,
5192						  uint16_t is_link_up,
5193						  uint16_t speed_mask,
5194						  uint16_t is_duplex)
5195{
5196	if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
5197		vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
5198	if (is_link_up) {
5199		PMD_DRV_LOG(DEBUG, "phy link up");
5200
5201		vars->phy_link_up = 1;
5202		vars->link_status |= LINK_STATUS_LINK_UP;
5203
5204		switch (speed_mask) {
5205		case ELINK_GP_STATUS_10M:
5206			vars->line_speed = ELINK_SPEED_10;
5207			if (is_duplex == DUPLEX_FULL)
5208				vars->link_status |= ELINK_LINK_10TFD;
5209			else
5210				vars->link_status |= ELINK_LINK_10THD;
5211			break;
5212
5213		case ELINK_GP_STATUS_100M:
5214			vars->line_speed = ELINK_SPEED_100;
5215			if (is_duplex == DUPLEX_FULL)
5216				vars->link_status |= ELINK_LINK_100TXFD;
5217			else
5218				vars->link_status |= ELINK_LINK_100TXHD;
5219			break;
5220
5221		case ELINK_GP_STATUS_1G:
5222		case ELINK_GP_STATUS_1G_KX:
5223			vars->line_speed = ELINK_SPEED_1000;
5224			if (is_duplex == DUPLEX_FULL)
5225				vars->link_status |= ELINK_LINK_1000TFD;
5226			else
5227				vars->link_status |= ELINK_LINK_1000THD;
5228			break;
5229
5230		case ELINK_GP_STATUS_2_5G:
5231			vars->line_speed = ELINK_SPEED_2500;
5232			if (is_duplex == DUPLEX_FULL)
5233				vars->link_status |= ELINK_LINK_2500TFD;
5234			else
5235				vars->link_status |= ELINK_LINK_2500THD;
5236			break;
5237
5238		case ELINK_GP_STATUS_5G:
5239		case ELINK_GP_STATUS_6G:
5240			PMD_DRV_LOG(DEBUG,
5241				    "link speed unsupported  gp_status 0x%x",
5242				    speed_mask);
5243			return ELINK_STATUS_ERROR;
5244
5245		case ELINK_GP_STATUS_10G_KX4:
5246		case ELINK_GP_STATUS_10G_HIG:
5247		case ELINK_GP_STATUS_10G_CX4:
5248		case ELINK_GP_STATUS_10G_KR:
5249		case ELINK_GP_STATUS_10G_SFI:
5250		case ELINK_GP_STATUS_10G_XFI:
5251			vars->line_speed = ELINK_SPEED_10000;
5252			vars->link_status |= ELINK_LINK_10GTFD;
5253			break;
5254		case ELINK_GP_STATUS_20G_DXGXS:
5255		case ELINK_GP_STATUS_20G_KR2:
5256			vars->line_speed = ELINK_SPEED_20000;
5257			vars->link_status |= ELINK_LINK_20GTFD;
5258			break;
5259		default:
5260			PMD_DRV_LOG(DEBUG,
5261				    "link speed unsupported gp_status 0x%x",
5262				    speed_mask);
5263			return ELINK_STATUS_ERROR;
5264		}
5265	} else {		/* link_down */
5266		PMD_DRV_LOG(DEBUG, "phy link down");
5267
5268		vars->phy_link_up = 0;
5269
5270		vars->duplex = DUPLEX_FULL;
5271		vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
5272		vars->mac_type = ELINK_MAC_TYPE_NONE;
5273	}
5274	PMD_DRV_LOG(DEBUG, " phy_link_up %x line_speed %d",
5275		    vars->phy_link_up, vars->line_speed);
5276	return ELINK_STATUS_OK;
5277}
5278
5279static elink_status_t elink_link_settings_status(struct elink_phy *phy,
5280						 struct elink_params *params,
5281						 struct elink_vars *vars)
5282{
5283	struct bnx2x_softc *sc = params->sc;
5284
5285	uint16_t gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
5286	elink_status_t rc = ELINK_STATUS_OK;
5287
5288	/* Read gp_status */
5289	CL22_RD_OVER_CL45(sc, phy,
5290			  MDIO_REG_BANK_GP_STATUS,
5291			  MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status);
5292	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
5293		duplex = DUPLEX_FULL;
5294	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
5295		link_up = 1;
5296	speed_mask = gp_status & ELINK_GP_STATUS_SPEED_MASK;
5297	PMD_DRV_LOG(DEBUG, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x",
5298		    gp_status, link_up, speed_mask);
5299	rc = elink_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
5300					 duplex);
5301	if (rc == ELINK_STATUS_ERROR)
5302		return rc;
5303
5304	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
5305		if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
5306			vars->duplex = duplex;
5307			elink_flow_ctrl_resolve(phy, params, vars, gp_status);
5308			if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
5309				elink_xgxs_an_resolve(phy, params, vars,
5310						      gp_status);
5311		}
5312	} else {		/* Link_down */
5313		if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
5314		    ELINK_SINGLE_MEDIA_DIRECT(params)) {
5315			/* Check signal is detected */
5316			elink_check_fallback_to_cl37(phy, params);
5317		}
5318	}
5319
5320	/* Read LP advertised speeds */
5321	if (ELINK_SINGLE_MEDIA_DIRECT(params) &&
5322	    (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)) {
5323		uint16_t val;
5324
5325		CL22_RD_OVER_CL45(sc, phy, MDIO_REG_BANK_CL73_IEEEB1,
5326				  MDIO_CL73_IEEEB1_AN_LP_ADV2, &val);
5327
5328		if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
5329			vars->link_status |=
5330			    LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
5331		if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
5332			   MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
5333			vars->link_status |=
5334			    LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
5335
5336		CL22_RD_OVER_CL45(sc, phy, MDIO_REG_BANK_OVER_1G,
5337				  MDIO_OVER_1G_LP_UP1, &val);
5338
5339		if (val & MDIO_OVER_1G_UP1_2_5G)
5340			vars->link_status |=
5341			    LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
5342		if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
5343			vars->link_status |=
5344			    LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
5345	}
5346
5347	PMD_DRV_LOG(DEBUG, "duplex %x  flow_ctrl 0x%x link_status 0x%x",
5348		    vars->duplex, vars->flow_ctrl, vars->link_status);
5349	return rc;
5350}
5351
5352static elink_status_t elink_warpcore_read_status(struct elink_phy *phy,
5353						 struct elink_params *params,
5354						 struct elink_vars *vars)
5355{
5356	struct bnx2x_softc *sc = params->sc;
5357	uint8_t lane;
5358	uint16_t gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
5359	elink_status_t rc = ELINK_STATUS_OK;
5360	lane = elink_get_warpcore_lane(params);
5361	/* Read gp_status */
5362	if ((params->loopback_mode) && (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)) {
5363		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5364				MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up);
5365		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5366				MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up);
5367		link_up &= 0x1;
5368	} else if ((phy->req_line_speed > ELINK_SPEED_10000) &&
5369		   (phy->supported & ELINK_SUPPORTED_20000baseMLD2_Full)) {
5370		uint16_t temp_link_up;
5371		elink_cl45_read(sc, phy, MDIO_WC_DEVAD, 1, &temp_link_up);
5372		elink_cl45_read(sc, phy, MDIO_WC_DEVAD, 1, &link_up);
5373		PMD_DRV_LOG(DEBUG, "PCS RX link status = 0x%x-->0x%x",
5374			    temp_link_up, link_up);
5375		link_up &= (1 << 2);
5376		if (link_up)
5377			elink_ext_phy_resolve_fc(phy, params, vars);
5378	} else {
5379		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5380				MDIO_WC_REG_GP2_STATUS_GP_2_1, &gp_status1);
5381		PMD_DRV_LOG(DEBUG, "0x81d1 = 0x%x", gp_status1);
5382		/* Check for either KR, 1G, or AN up. */
5383		link_up = ((gp_status1 >> 8) |
5384			   (gp_status1 >> 12) | (gp_status1)) & (1 << lane);
5385		if (phy->supported & ELINK_SUPPORTED_20000baseKR2_Full) {
5386			uint16_t an_link;
5387			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
5388					MDIO_AN_REG_STATUS, &an_link);
5389			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
5390					MDIO_AN_REG_STATUS, &an_link);
5391			link_up |= (an_link & (1 << 2));
5392		}
5393		if (link_up && ELINK_SINGLE_MEDIA_DIRECT(params)) {
5394			uint16_t pd, gp_status4;
5395			if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
5396				/* Check Autoneg complete */
5397				elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5398						MDIO_WC_REG_GP2_STATUS_GP_2_4,
5399						&gp_status4);
5400				if (gp_status4 & ((1 << 12) << lane))
5401					vars->link_status |=
5402					    LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5403
5404				/* Check parallel detect used */
5405				elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5406						MDIO_WC_REG_PAR_DET_10G_STATUS,
5407						&pd);
5408				if (pd & (1 << 15))
5409					vars->link_status |=
5410					    LINK_STATUS_PARALLEL_DETECTION_USED;
5411			}
5412			elink_ext_phy_resolve_fc(phy, params, vars);
5413			vars->duplex = duplex;
5414		}
5415	}
5416
5417	if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) &&
5418	    ELINK_SINGLE_MEDIA_DIRECT(params)) {
5419		uint16_t val;
5420
5421		elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
5422				MDIO_AN_REG_LP_AUTO_NEG2, &val);
5423
5424		if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
5425			vars->link_status |=
5426			    LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
5427		if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
5428			   MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
5429			vars->link_status |=
5430			    LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
5431
5432		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5433				MDIO_WC_REG_DIGITAL3_LP_UP1, &val);
5434
5435		if (val & MDIO_OVER_1G_UP1_2_5G)
5436			vars->link_status |=
5437			    LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
5438		if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
5439			vars->link_status |=
5440			    LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
5441
5442	}
5443
5444	if (lane < 2) {
5445		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5446				MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
5447	} else {
5448		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5449				MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
5450	}
5451	PMD_DRV_LOG(DEBUG, "lane %d gp_speed 0x%x", lane, gp_speed);
5452
5453	if ((lane & 1) == 0)
5454		gp_speed <<= 8;
5455	gp_speed &= 0x3f00;
5456	link_up = ! !link_up;
5457
5458	/* Reset the TX FIFO to fix SGMII issue */
5459	rc = elink_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
5460					 duplex);
5461
5462	/* In case of KR link down, start up the recovering procedure */
5463	if ((!link_up) && (phy->media_type == ELINK_ETH_PHY_KR) &&
5464	    (!(phy->flags & ELINK_FLAGS_WC_DUAL_MODE)))
5465		vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
5466
5467	PMD_DRV_LOG(DEBUG, "duplex %x  flow_ctrl 0x%x link_status 0x%x",
5468		    vars->duplex, vars->flow_ctrl, vars->link_status);
5469	return rc;
5470}
5471
5472static void elink_set_gmii_tx_driver(struct elink_params *params)
5473{
5474	struct bnx2x_softc *sc = params->sc;
5475	struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
5476	uint16_t lp_up2;
5477	uint16_t tx_driver;
5478	uint16_t bank;
5479
5480	/* Read precomp */
5481	CL22_RD_OVER_CL45(sc, phy,
5482			  MDIO_REG_BANK_OVER_1G, MDIO_OVER_1G_LP_UP2, &lp_up2);
5483
5484	/* Bits [10:7] at lp_up2, positioned at [15:12] */
5485	lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
5486		   MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
5487		  MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
5488
5489	if (lp_up2 == 0)
5490		return;
5491
5492	for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
5493	     bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
5494		CL22_RD_OVER_CL45(sc, phy,
5495				  bank, MDIO_TX0_TX_DRIVER, &tx_driver);
5496
5497		/* Replace tx_driver bits [15:12] */
5498		if (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
5499			tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
5500			tx_driver |= lp_up2;
5501			CL22_WR_OVER_CL45(sc, phy,
5502					  bank, MDIO_TX0_TX_DRIVER, tx_driver);
5503		}
5504	}
5505}
5506
5507static elink_status_t elink_emac_program(struct elink_params *params,
5508					 struct elink_vars *vars)
5509{
5510	struct bnx2x_softc *sc = params->sc;
5511	uint8_t port = params->port;
5512	uint16_t mode = 0;
5513
5514	PMD_DRV_LOG(DEBUG, "setting link speed & duplex");
5515	elink_bits_dis(sc, GRCBASE_EMAC0 + port * 0x400 +
5516		       EMAC_REG_EMAC_MODE,
5517		       (EMAC_MODE_25G_MODE |
5518			EMAC_MODE_PORT_MII_10M | EMAC_MODE_HALF_DUPLEX));
5519	switch (vars->line_speed) {
5520	case ELINK_SPEED_10:
5521		mode |= EMAC_MODE_PORT_MII_10M;
5522		break;
5523
5524	case ELINK_SPEED_100:
5525		mode |= EMAC_MODE_PORT_MII;
5526		break;
5527
5528	case ELINK_SPEED_1000:
5529		mode |= EMAC_MODE_PORT_GMII;
5530		break;
5531
5532	case ELINK_SPEED_2500:
5533		mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
5534		break;
5535
5536	default:
5537		/* 10G not valid for EMAC */
5538		PMD_DRV_LOG(DEBUG, "Invalid line_speed 0x%x", vars->line_speed);
5539		return ELINK_STATUS_ERROR;
5540	}
5541
5542	if (vars->duplex == DUPLEX_HALF)
5543		mode |= EMAC_MODE_HALF_DUPLEX;
5544	elink_bits_en(sc,
5545		      GRCBASE_EMAC0 + port * 0x400 + EMAC_REG_EMAC_MODE, mode);
5546
5547	elink_set_led(params, vars, ELINK_LED_MODE_OPER, vars->line_speed);
5548	return ELINK_STATUS_OK;
5549}
5550
5551static void elink_set_preemphasis(struct elink_phy *phy,
5552				  struct elink_params *params)
5553{
5554
5555	uint16_t bank, i = 0;
5556	struct bnx2x_softc *sc = params->sc;
5557
5558	for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
5559	     bank += (MDIO_REG_BANK_RX1 - MDIO_REG_BANK_RX0), i++) {
5560		CL22_WR_OVER_CL45(sc, phy,
5561				  bank,
5562				  MDIO_RX0_RX_EQ_BOOST, phy->rx_preemphasis[i]);
5563	}
5564
5565	for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
5566	     bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
5567		CL22_WR_OVER_CL45(sc, phy,
5568				  bank,
5569				  MDIO_TX0_TX_DRIVER, phy->tx_preemphasis[i]);
5570	}
5571}
5572
5573static void elink_xgxs_config_init(struct elink_phy *phy,
5574				   struct elink_params *params,
5575				   struct elink_vars *vars)
5576{
5577	uint8_t enable_cl73 = (ELINK_SINGLE_MEDIA_DIRECT(params) ||
5578			       (params->loopback_mode == ELINK_LOOPBACK_XGXS));
5579
5580	if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
5581		if (ELINK_SINGLE_MEDIA_DIRECT(params) &&
5582		    (params->feature_config_flags &
5583		     ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
5584			elink_set_preemphasis(phy, params);
5585
5586		/* Forced speed requested? */
5587		if (vars->line_speed != ELINK_SPEED_AUTO_NEG ||
5588		    (ELINK_SINGLE_MEDIA_DIRECT(params) &&
5589		     params->loopback_mode == ELINK_LOOPBACK_EXT)) {
5590			PMD_DRV_LOG(DEBUG, "not SGMII, no AN");
5591
5592			/* Disable autoneg */
5593			elink_set_autoneg(phy, params, vars, 0);
5594
5595			/* Program speed and duplex */
5596			elink_program_serdes(phy, params, vars);
5597
5598		} else {	/* AN_mode */
5599			PMD_DRV_LOG(DEBUG, "not SGMII, AN");
5600
5601			/* AN enabled */
5602			elink_set_brcm_cl37_advertisement(phy, params);
5603
5604			/* Program duplex & pause advertisement (for aneg) */
5605			elink_set_ieee_aneg_advertisement(phy, params,
5606							  vars->ieee_fc);
5607
5608			/* Enable autoneg */
5609			elink_set_autoneg(phy, params, vars, enable_cl73);
5610
5611			/* Enable and restart AN */
5612			elink_restart_autoneg(phy, params, enable_cl73);
5613		}
5614
5615	} else {		/* SGMII mode */
5616		PMD_DRV_LOG(DEBUG, "SGMII");