xref: /freebsd/sys/dev/bxe/bxe_elink.c (revision 123af6ec70016f5556da5972d4d63c7d175c06d3)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2007-2017 QLogic Corporation. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26  * THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31 
32 #include "bxe.h"
33 #include "bxe_elink.h"
34 #include "ecore_mfw_req.h"
35 #include "ecore_fw_defs.h"
36 #include "ecore_hsi.h"
37 #include "ecore_reg.h"
38 
39 
40 #define MDIO_REG_BANK_CL73_IEEEB0			0x0
41 	#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL		0x0
42 		#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN	0x0200
43 		#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN		0x1000
44 		#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_MAIN_RST	0x8000
45 
46 #define MDIO_REG_BANK_CL73_IEEEB1			0x10
47 	#define MDIO_CL73_IEEEB1_AN_ADV1			0x00
48 		#define	MDIO_CL73_IEEEB1_AN_ADV1_PAUSE			0x0400
49 		#define	MDIO_CL73_IEEEB1_AN_ADV1_ASYMMETRIC 		0x0800
50 		#define	MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH		0x0C00
51 		#define	MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK		0x0C00
52 	#define MDIO_CL73_IEEEB1_AN_ADV2				0x01
53 		#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M		0x0000
54 		#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX		0x0020
55 		#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4		0x0040
56 		#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR		0x0080
57 	#define	MDIO_CL73_IEEEB1_AN_LP_ADV1			0x03
58 		#define	MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE		0x0400
59 		#define	MDIO_CL73_IEEEB1_AN_LP_ADV1_ASYMMETRIC 		0x0800
60 		#define	MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_BOTH		0x0C00
61 		#define	MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK		0x0C00
62 	#define	MDIO_CL73_IEEEB1_AN_LP_ADV2			0x04
63 
64 #define	MDIO_REG_BANK_RX0				0x80b0
65 	#define	MDIO_RX0_RX_STATUS				0x10
66 		#define	MDIO_RX0_RX_STATUS_SIGDET			0x8000
67 		#define	MDIO_RX0_RX_STATUS_RX_SEQ_DONE			0x1000
68 	#define	MDIO_RX0_RX_EQ_BOOST				0x1c
69 		#define	MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
70 		#define	MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL		0x10
71 
72 #define	MDIO_REG_BANK_RX1				0x80c0
73 	#define	MDIO_RX1_RX_EQ_BOOST				0x1c
74 		#define	MDIO_RX1_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
75 		#define	MDIO_RX1_RX_EQ_BOOST_OFFSET_CTRL		0x10
76 
77 #define	MDIO_REG_BANK_RX2				0x80d0
78 	#define	MDIO_RX2_RX_EQ_BOOST				0x1c
79 		#define	MDIO_RX2_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
80 		#define	MDIO_RX2_RX_EQ_BOOST_OFFSET_CTRL		0x10
81 
82 #define	MDIO_REG_BANK_RX3				0x80e0
83 	#define	MDIO_RX3_RX_EQ_BOOST				0x1c
84 		#define	MDIO_RX3_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
85 		#define	MDIO_RX3_RX_EQ_BOOST_OFFSET_CTRL		0x10
86 
87 #define	MDIO_REG_BANK_RX_ALL				0x80f0
88 	#define	MDIO_RX_ALL_RX_EQ_BOOST				0x1c
89 		#define	MDIO_RX_ALL_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
90 		#define	MDIO_RX_ALL_RX_EQ_BOOST_OFFSET_CTRL	0x10
91 
92 #define	MDIO_REG_BANK_TX0				0x8060
93 	#define	MDIO_TX0_TX_DRIVER				0x17
94 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
95 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
96 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_MASK			0x0f00
97 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
98 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
99 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
100 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
101 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
102 		#define	MDIO_TX0_TX_DRIVER_ICBUF1T			1
103 
104 #define	MDIO_REG_BANK_TX1				0x8070
105 	#define	MDIO_TX1_TX_DRIVER				0x17
106 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
107 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
108 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_MASK			0x0f00
109 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
110 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
111 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
112 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
113 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
114 		#define	MDIO_TX0_TX_DRIVER_ICBUF1T			1
115 
116 #define	MDIO_REG_BANK_TX2				0x8080
117 	#define	MDIO_TX2_TX_DRIVER				0x17
118 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
119 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
120 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_MASK			0x0f00
121 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
122 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
123 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
124 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
125 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
126 		#define	MDIO_TX0_TX_DRIVER_ICBUF1T			1
127 
128 #define	MDIO_REG_BANK_TX3				0x8090
129 	#define	MDIO_TX3_TX_DRIVER				0x17
130 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
131 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
132 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_MASK			0x0f00
133 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
134 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
135 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
136 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
137 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
138 		#define	MDIO_TX0_TX_DRIVER_ICBUF1T			1
139 
140 #define	MDIO_REG_BANK_XGXS_BLOCK0			0x8000
141 	#define	MDIO_BLOCK0_XGXS_CONTROL			0x10
142 
143 #define	MDIO_REG_BANK_XGXS_BLOCK1			0x8010
144 	#define	MDIO_BLOCK1_LANE_CTRL0				0x15
145 	#define	MDIO_BLOCK1_LANE_CTRL1				0x16
146 	#define	MDIO_BLOCK1_LANE_CTRL2				0x17
147 	#define	MDIO_BLOCK1_LANE_PRBS				0x19
148 
149 #define	MDIO_REG_BANK_XGXS_BLOCK2			0x8100
150 	#define	MDIO_XGXS_BLOCK2_RX_LN_SWAP			0x10
151 		#define	MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE		0x8000
152 		#define	MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE	0x4000
153 		#define	MDIO_XGXS_BLOCK2_TX_LN_SWAP		0x11
154 		#define	MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE		0x8000
155 		#define	MDIO_XGXS_BLOCK2_UNICORE_MODE_10G	0x14
156 		#define	MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS	0x0001
157 		#define	MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS	0x0010
158 		#define	MDIO_XGXS_BLOCK2_TEST_MODE_LANE		0x15
159 
160 #define	MDIO_REG_BANK_GP_STATUS				0x8120
161 #define	MDIO_GP_STATUS_TOP_AN_STATUS1				0x1B
162 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE	0x0001
163 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE	0x0002
164 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS		0x0004
165 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS		0x0008
166 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE	0x0010
167 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_LP_NP_BAM_ABLE	0x0020
168 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE	0x0040
169 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE	0x0080
170 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK		0x3f00
171 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M		0x0000
172 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M		0x0100
173 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G		0x0200
174 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G		0x0300
175 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G		0x0400
176 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G		0x0500
177 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG	0x0600
178 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4	0x0700
179 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG	0x0800
180 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G	0x0900
181 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G		0x0A00
182 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G		0x0B00
183 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G		0x0C00
184 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX	0x0D00
185 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4	0x0E00
186 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR	0x0F00
187 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI	0x1B00
188 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS	0x1E00
189 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI	0x1F00
190 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_KR2	0x3900
191 
192 
193 #define	MDIO_REG_BANK_10G_PARALLEL_DETECT		0x8130
194 #define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS		0x10
195 #define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK		0x8000
196 #define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL		0x11
197 #define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN	0x1
198 #define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK		0x13
199 #define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT		(0xb71<<1)
200 
201 #define	MDIO_REG_BANK_SERDES_DIGITAL			0x8300
202 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1			0x10
203 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE			0x0001
204 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_TBI_IF			0x0002
205 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN		0x0004
206 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT	0x0008
207 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET			0x0010
208 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE			0x0020
209 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL2			0x11
210 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN			0x0001
211 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_AN_FST_TMR			0x0040
212 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1			0x14
213 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SGMII			0x0001
214 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_LINK			0x0002
215 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_DUPLEX			0x0004
216 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_MASK			0x0018
217 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_SHIFT			3
218 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_2_5G			0x0018
219 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_1G			0x0010
220 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_100M			0x0008
221 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_10M			0x0000
222 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS2			0x15
223 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED			0x0002
224 #define	MDIO_SERDES_DIGITAL_MISC1				0x18
225 #define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_MASK			0xE000
226 #define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_25M			0x0000
227 #define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_100M			0x2000
228 #define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_125M			0x4000
229 #define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M			0x6000
230 #define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_187_5M			0x8000
231 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL			0x0010
232 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK			0x000f
233 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_2_5G			0x0000
234 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_5G			0x0001
235 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_6G			0x0002
236 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_HIG			0x0003
237 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4			0x0004
238 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12G			0x0005
239 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12_5G			0x0006
240 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G			0x0007
241 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_15G			0x0008
242 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_16G			0x0009
243 
244 #define	MDIO_REG_BANK_OVER_1G				0x8320
245 #define	MDIO_OVER_1G_DIGCTL_3_4					0x14
246 #define	MDIO_OVER_1G_DIGCTL_3_4_MP_ID_MASK				0xffe0
247 #define	MDIO_OVER_1G_DIGCTL_3_4_MP_ID_SHIFT				5
248 #define	MDIO_OVER_1G_UP1					0x19
249 #define	MDIO_OVER_1G_UP1_2_5G						0x0001
250 #define	MDIO_OVER_1G_UP1_5G						0x0002
251 #define	MDIO_OVER_1G_UP1_6G						0x0004
252 #define	MDIO_OVER_1G_UP1_10G						0x0010
253 #define	MDIO_OVER_1G_UP1_10GH						0x0008
254 #define	MDIO_OVER_1G_UP1_12G						0x0020
255 #define	MDIO_OVER_1G_UP1_12_5G						0x0040
256 #define	MDIO_OVER_1G_UP1_13G						0x0080
257 #define	MDIO_OVER_1G_UP1_15G						0x0100
258 #define	MDIO_OVER_1G_UP1_16G						0x0200
259 #define	MDIO_OVER_1G_UP2					0x1A
260 #define	MDIO_OVER_1G_UP2_IPREDRIVER_MASK				0x0007
261 #define	MDIO_OVER_1G_UP2_IDRIVER_MASK					0x0038
262 #define	MDIO_OVER_1G_UP2_PREEMPHASIS_MASK				0x03C0
263 #define	MDIO_OVER_1G_UP3					0x1B
264 #define	MDIO_OVER_1G_UP3_HIGIG2						0x0001
265 #define	MDIO_OVER_1G_LP_UP1					0x1C
266 #define	MDIO_OVER_1G_LP_UP2					0x1D
267 #define	MDIO_OVER_1G_LP_UP2_MR_ADV_OVER_1G_MASK				0x03ff
268 #define	MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK				0x0780
269 #define	MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT				7
270 #define	MDIO_OVER_1G_LP_UP3						0x1E
271 
272 #define	MDIO_REG_BANK_REMOTE_PHY			0x8330
273 #define	MDIO_REMOTE_PHY_MISC_RX_STATUS				0x10
274 #define	MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG	0x0010
275 #define	MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG	0x0600
276 
277 #define	MDIO_REG_BANK_BAM_NEXT_PAGE			0x8350
278 #define	MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL			0x10
279 #define	MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE			0x0001
280 #define	MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN			0x0002
281 
282 #define	MDIO_REG_BANK_CL73_USERB0		0x8370
283 #define	MDIO_CL73_USERB0_CL73_UCTRL				0x10
284 #define	MDIO_CL73_USERB0_CL73_UCTRL_USTAT1_MUXSEL			0x0002
285 #define	MDIO_CL73_USERB0_CL73_USTAT1				0x11
286 #define	MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK			0x0100
287 #define	MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37		0x0400
288 #define	MDIO_CL73_USERB0_CL73_BAM_CTRL1				0x12
289 #define	MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN				0x8000
290 #define	MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN		0x4000
291 #define	MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN		0x2000
292 #define	MDIO_CL73_USERB0_CL73_BAM_CTRL3				0x14
293 #define	MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR			0x0001
294 
295 #define	MDIO_REG_BANK_AER_BLOCK			0xFFD0
296 #define	MDIO_AER_BLOCK_AER_REG					0x1E
297 
298 #define	MDIO_REG_BANK_COMBO_IEEE0		0xFFE0
299 #define	MDIO_COMBO_IEEE0_MII_CONTROL				0x10
300 #define	MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK			0x2040
301 #define	MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_10			0x0000
302 #define	MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100			0x2000
303 #define	MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000			0x0040
304 #define	MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX				0x0100
305 #define	MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN				0x0200
306 #define	MDIO_COMBO_IEEO_MII_CONTROL_AN_EN				0x1000
307 #define	MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK				0x4000
308 #define	MDIO_COMBO_IEEO_MII_CONTROL_RESET				0x8000
309 #define	MDIO_COMBO_IEEE0_MII_STATUS				0x11
310 #define	MDIO_COMBO_IEEE0_MII_STATUS_LINK_PASS				0x0004
311 #define	MDIO_COMBO_IEEE0_MII_STATUS_AUTONEG_COMPLETE			0x0020
312 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV				0x14
313 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX			0x0020
314 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_HALF_DUPLEX			0x0040
315 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK			0x0180
316 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE			0x0000
317 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC			0x0080
318 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC			0x0100
319 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH			0x0180
320 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_NEXT_PAGE				0x8000
321 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1		0x15
322 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_NEXT_PAGE	0x8000
323 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_ACK		0x4000
324 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_MASK	0x0180
325 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_NONE	0x0000
326 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_BOTH	0x0180
327 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_HALF_DUP_CAP	0x0040
328 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_FULL_DUP_CAP	0x0020
329 /*WhenthelinkpartnerisinSGMIImode(bit0=1),then
330 bit15=link,bit12=duplex,bits11:10=speed,bit14=acknowledge.
331 Theotherbitsarereservedandshouldbezero*/
332 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_SGMII_MODE	0x0001
333 
334 
335 #define	MDIO_PMA_DEVAD			0x1
336 /*ieee*/
337 #define	MDIO_PMA_REG_CTRL		0x0
338 #define	MDIO_PMA_REG_STATUS		0x1
339 #define	MDIO_PMA_REG_10G_CTRL2		0x7
340 #define MDIO_PMA_REG_TX_DISABLE		0x0009
341 #define	MDIO_PMA_REG_RX_SD		0xa
342 /*bcm*/
343 #define	MDIO_PMA_REG_BCM_CTRL		0x0096
344 #define MDIO_PMA_REG_FEC_CTRL		0x00ab
345 #define	MDIO_PMA_LASI_RXCTRL		0x9000
346 #define	MDIO_PMA_LASI_TXCTRL		0x9001
347 #define	MDIO_PMA_LASI_CTRL		0x9002
348 #define	MDIO_PMA_LASI_RXSTAT		0x9003
349 #define	MDIO_PMA_LASI_TXSTAT		0x9004
350 #define	MDIO_PMA_LASI_STAT		0x9005
351 #define	MDIO_PMA_REG_PHY_IDENTIFIER	0xc800
352 #define	MDIO_PMA_REG_DIGITAL_CTRL	0xc808
353 #define	MDIO_PMA_REG_DIGITAL_STATUS	0xc809
354 #define	MDIO_PMA_REG_TX_POWER_DOWN	0xca02
355 #define	MDIO_PMA_REG_CMU_PLL_BYPASS	0xca09
356 #define	MDIO_PMA_REG_MISC_CTRL		0xca0a
357 #define	MDIO_PMA_REG_GEN_CTRL		0xca10
358 	#define	MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP	0x0188
359 	#define	MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET		0x018a
360 #define	MDIO_PMA_REG_M8051_MSGIN_REG	0xca12
361 #define	MDIO_PMA_REG_M8051_MSGOUT_REG	0xca13
362 #define	MDIO_PMA_REG_ROM_VER1		0xca19
363 #define	MDIO_PMA_REG_ROM_VER2		0xca1a
364 #define	MDIO_PMA_REG_EDC_FFE_MAIN	0xca1b
365 #define	MDIO_PMA_REG_PLL_BANDWIDTH	0xca1d
366 #define MDIO_PMA_REG_PLL_CTRL 		0xca1e
367 #define MDIO_PMA_REG_MISC_CTRL0 	0xca23
368 #define MDIO_PMA_REG_LRM_MODE	 	0xca3f
369 #define	MDIO_PMA_REG_CDR_BANDWIDTH 	0xca46
370 #define	MDIO_PMA_REG_MISC_CTRL1		0xca85
371 
372 #define MDIO_PMA_REG_SFP_TWO_WIRE_CTRL		0x8000
373 	#define MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK 	0x000c
374 		#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE 		0x0000
375 		#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE 	0x0004
376 		#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IN_PROGRESS 	0x0008
377 		#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_FAILED 	0x000c
378 #define MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT 	0x8002
379 #define MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR 	0x8003
380 #define MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF	0xc820
381 	#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK 0xff
382 #define MDIO_PMA_REG_8726_TX_CTRL1		0xca01
383 #define MDIO_PMA_REG_8726_TX_CTRL2		0xca05
384 
385 #define MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR	0x8005
386 #define MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF	0x8007
387 	#define MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK 0xff
388 #define MDIO_PMA_REG_8727_MISC_CTRL		0x8309
389 #define MDIO_PMA_REG_8727_TX_CTRL1		0xca02
390 #define MDIO_PMA_REG_8727_TX_CTRL2		0xca05
391 #define MDIO_PMA_REG_8727_PCS_OPT_CTRL		0xc808
392 #define MDIO_PMA_REG_8727_GPIO_CTRL		0xc80e
393 #define MDIO_PMA_REG_8727_PCS_GP		0xc842
394 #define MDIO_PMA_REG_8727_OPT_CFG_REG		0xc8e4
395 
396 #define MDIO_AN_REG_8727_MISC_CTRL		0x8309
397 #define	MDIO_PMA_REG_8073_CHIP_REV			0xc801
398 #define MDIO_PMA_REG_8073_SPEED_LINK_STATUS		0xc820
399 #define MDIO_PMA_REG_8073_XAUI_WA 			0xc841
400 #define MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL 		0xcd08
401 
402 #define MDIO_PMA_REG_7101_RESET		0xc000
403 #define	MDIO_PMA_REG_7107_LED_CNTL	0xc007
404 #define	MDIO_PMA_REG_7107_LINK_LED_CNTL	0xc009
405 #define	MDIO_PMA_REG_7101_VER1		0xc026
406 #define	MDIO_PMA_REG_7101_VER2		0xc027
407 
408 #define MDIO_PMA_REG_8481_PMD_SIGNAL	0xa811
409 #define MDIO_PMA_REG_8481_LED1_MASK	0xa82c
410 #define MDIO_PMA_REG_8481_LED2_MASK	0xa82f
411 #define MDIO_PMA_REG_8481_LED3_MASK	0xa832
412 #define MDIO_PMA_REG_8481_LED3_BLINK	0xa834
413 #define MDIO_PMA_REG_8481_LED5_MASK	                0xa838
414 #define MDIO_PMA_REG_8481_SIGNAL_MASK	0xa835
415 #define MDIO_PMA_REG_8481_LINK_SIGNAL	0xa83b
416 #define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK	0x800
417 #define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT	11
418 
419 
420 
421 #define	MDIO_WIS_DEVAD			0x2
422 /*bcm*/
423 #define	MDIO_WIS_REG_LASI_CNTL		0x9002
424 #define	MDIO_WIS_REG_LASI_STATUS	0x9005
425 
426 #define	MDIO_PCS_DEVAD			0x3
427 #define	MDIO_PCS_REG_STATUS		0x0020
428 #define MDIO_PCS_REG_LASI_STATUS	0x9005
429 #define MDIO_PCS_REG_7101_DSP_ACCESS	0xD000
430 #define MDIO_PCS_REG_7101_SPI_MUX 	0xD008
431 #define MDIO_PCS_REG_7101_SPI_CTRL_ADDR 0xE12A
432 	#define MDIO_PCS_REG_7101_SPI_RESET_BIT (5)
433 #define MDIO_PCS_REG_7101_SPI_FIFO_ADDR 0xE02A
434 	#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD (6)
435 	#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD   (0xC7)
436 	#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD (2)
437 #define MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR 0xE028
438 
439 
440 
441 #define	MDIO_XS_DEVAD			0x4
442 #define	MDIO_XS_REG_STATUS		0x0001
443 #define MDIO_XS_PLL_SEQUENCER 		0x8000
444 #define	MDIO_XS_SFX7101_XGXS_TEST1	0xc00a
445 
446 #define MDIO_XS_8706_REG_BANK_RX0	0x80bc
447 #define MDIO_XS_8706_REG_BANK_RX1	0x80cc
448 #define MDIO_XS_8706_REG_BANK_RX2	0x80dc
449 #define MDIO_XS_8706_REG_BANK_RX3	0x80ec
450 #define MDIO_XS_8706_REG_BANK_RXA	0x80fc
451 
452 #define MDIO_XS_REG_8073_RX_CTRL_PCIE	0x80FA
453 
454 #define	MDIO_AN_DEVAD			0x7
455 /*ieee*/
456 #define	MDIO_AN_REG_CTRL		0x0000
457 #define	MDIO_AN_REG_STATUS		0x0001
458 	#define	MDIO_AN_REG_STATUS_AN_COMPLETE		0x0020
459 #define	MDIO_AN_REG_ADV_PAUSE		0x0010
460 	#define	MDIO_AN_REG_ADV_PAUSE_PAUSE		0x0400
461 	#define	MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC	0x0800
462 	#define	MDIO_AN_REG_ADV_PAUSE_BOTH		0x0C00
463 	#define	MDIO_AN_REG_ADV_PAUSE_MASK		0x0C00
464 #define	MDIO_AN_REG_ADV			0x0011
465 #define MDIO_AN_REG_ADV2		0x0012
466 #define	MDIO_AN_REG_LP_AUTO_NEG		0x0013
467 #define	MDIO_AN_REG_LP_AUTO_NEG2	0x0014
468 #define	MDIO_AN_REG_MASTER_STATUS	0x0021
469 #define	MDIO_AN_REG_EEE_ADV		0x003c
470 #define	MDIO_AN_REG_LP_EEE_ADV		0x003d
471 /*bcm*/
472 #define	MDIO_AN_REG_LINK_STATUS		0x8304
473 #define	MDIO_AN_REG_CL37_CL73		0x8370
474 #define	MDIO_AN_REG_CL37_AN		0xffe0
475 #define	MDIO_AN_REG_CL37_FC_LD		0xffe4
476 #define 	MDIO_AN_REG_CL37_FC_LP		0xffe5
477 #define 	MDIO_AN_REG_1000T_STATUS	0xffea
478 
479 #define MDIO_AN_REG_8073_2_5G		0x8329
480 #define MDIO_AN_REG_8073_BAM		0x8350
481 
482 #define MDIO_AN_REG_8481_10GBASE_T_AN_CTRL	0x0020
483 #define MDIO_AN_REG_8481_LEGACY_MII_CTRL	0xffe0
484 	#define MDIO_AN_REG_8481_MII_CTRL_FORCE_1G	0x40
485 #define MDIO_AN_REG_8481_LEGACY_MII_STATUS	0xffe1
486 #define MDIO_AN_REG_848xx_ID_MSB		0xffe2
487 	#define BCM84858_PHY_ID					0x600d
488 #define MDIO_AN_REG_848xx_ID_LSB		0xffe3
489 #define MDIO_AN_REG_8481_LEGACY_AN_ADV		0xffe4
490 #define MDIO_AN_REG_8481_LEGACY_AN_EXPANSION	0xffe6
491 #define MDIO_AN_REG_8481_1000T_CTRL		0xffe9
492 #define MDIO_AN_REG_8481_1G_100T_EXT_CTRL	0xfff0
493 	#define MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF	0x0008
494 #define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW	0xfff5
495 #define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS	0xfff7
496 #define MDIO_AN_REG_8481_AUX_CTRL		0xfff8
497 #define MDIO_AN_REG_8481_LEGACY_SHADOW		0xfffc
498 
499 /* BCM84823 only */
500 #define	MDIO_CTL_DEVAD			0x1e
501 #define MDIO_CTL_REG_84823_MEDIA		0x401a
502 	#define MDIO_CTL_REG_84823_MEDIA_MAC_MASK		0x0018
503 	/* These pins configure the BCM84823 interface to MAC after reset. */
504 		#define MDIO_CTL_REG_84823_CTRL_MAC_XFI			0x0008
505 		#define MDIO_CTL_REG_84823_MEDIA_MAC_XAUI_M		0x0010
506 	/* These pins configure the BCM84823 interface to Line after reset. */
507 	#define MDIO_CTL_REG_84823_MEDIA_LINE_MASK		0x0060
508 		#define MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L		0x0020
509 		#define MDIO_CTL_REG_84823_MEDIA_LINE_XFI		0x0040
510 	/* When this pin is active high during reset, 10GBASE-T core is power
511 	 * down, When it is active low the 10GBASE-T is power up
512 	 */
513 	#define MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN	0x0080
514 	#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK		0x0100
515 		#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER	0x0000
516 		#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER		0x0100
517 	#define MDIO_CTL_REG_84823_MEDIA_FIBER_1G			0x1000
518 #define MDIO_CTL_REG_84823_USER_CTRL_REG			0x4005
519 	#define MDIO_CTL_REG_84823_USER_CTRL_CMS			0x0080
520 #define MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH		0xa82b
521 	#define MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ	0x2f
522 #define MDIO_PMA_REG_84823_CTL_LED_CTL_1			0xa8e3
523 #define MDIO_PMA_REG_84833_CTL_LED_CTL_1			0xa8ec
524 	#define MDIO_PMA_REG_84823_LED3_STRETCH_EN			0x0080
525 
526 /* BCM84833 only */
527 #define MDIO_84833_TOP_CFG_FW_REV			0x400f
528 	#define MDIO_84833_TOP_CFG_FW_EEE		0x10b1
529 	#define MDIO_84833_TOP_CFG_FW_NO_EEE		0x1f81
530 #define MDIO_84833_TOP_CFG_XGPHY_STRAP1 		0x401a
531 	#define MDIO_84833_SUPER_ISOLATE 		0x8000
532 /* These are mailbox register set used by 84833/84858. */
533 #define MDIO_848xx_TOP_CFG_SCRATCH_REG0			0x4005
534 #define MDIO_848xx_TOP_CFG_SCRATCH_REG1 		0x4006
535 #define MDIO_848xx_TOP_CFG_SCRATCH_REG2			0x4007
536 #define MDIO_848xx_TOP_CFG_SCRATCH_REG3			0x4008
537 #define MDIO_848xx_TOP_CFG_SCRATCH_REG4			0x4009
538 #define MDIO_848xx_TOP_CFG_SCRATCH_REG26		0x4037
539 #define MDIO_848xx_TOP_CFG_SCRATCH_REG27		0x4038
540 #define MDIO_848xx_TOP_CFG_SCRATCH_REG28		0x4039
541 #define MDIO_848xx_TOP_CFG_SCRATCH_REG29		0x403a
542 #define MDIO_848xx_TOP_CFG_SCRATCH_REG30		0x403b
543 #define MDIO_848xx_TOP_CFG_SCRATCH_REG31		0x403c
544 #define MDIO_848xx_CMD_HDLR_COMMAND	(MDIO_848xx_TOP_CFG_SCRATCH_REG0)
545 #define MDIO_848xx_CMD_HDLR_STATUS	(MDIO_848xx_TOP_CFG_SCRATCH_REG26)
546 #define MDIO_848xx_CMD_HDLR_DATA1	(MDIO_848xx_TOP_CFG_SCRATCH_REG27)
547 #define MDIO_848xx_CMD_HDLR_DATA2	(MDIO_848xx_TOP_CFG_SCRATCH_REG28)
548 #define MDIO_848xx_CMD_HDLR_DATA3	(MDIO_848xx_TOP_CFG_SCRATCH_REG29)
549 #define MDIO_848xx_CMD_HDLR_DATA4	(MDIO_848xx_TOP_CFG_SCRATCH_REG30)
550 #define MDIO_848xx_CMD_HDLR_DATA5	(MDIO_848xx_TOP_CFG_SCRATCH_REG31)
551 
552 /* Mailbox command set used by 84833/84858 */
553 #define PHY848xx_CMD_SET_PAIR_SWAP			0x8001
554 #define PHY848xx_CMD_GET_EEE_MODE			0x8008
555 #define PHY848xx_CMD_SET_EEE_MODE			0x8009
556 #define PHY848xx_CMD_GET_CURRENT_TEMP			0x8031
557 /* Mailbox status set used by 84833 only */
558 #define PHY84833_STATUS_CMD_RECEIVED			0x0001
559 #define PHY84833_STATUS_CMD_IN_PROGRESS			0x0002
560 #define PHY84833_STATUS_CMD_COMPLETE_PASS		0x0004
561 #define PHY84833_STATUS_CMD_COMPLETE_ERROR		0x0008
562 #define PHY84833_STATUS_CMD_OPEN_FOR_CMDS		0x0010
563 #define PHY84833_STATUS_CMD_SYSTEM_BOOT			0x0020
564 #define PHY84833_STATUS_CMD_NOT_OPEN_FOR_CMDS		0x0040
565 #define PHY84833_STATUS_CMD_CLEAR_COMPLETE		0x0080
566 #define PHY84833_STATUS_CMD_OPEN_OVERRIDE		0xa5a5
567 /* Mailbox Process */
568 #define PHY84833_MB_PROCESS1				1
569 #define PHY84833_MB_PROCESS2				2
570 #define PHY84833_MB_PROCESS3				3
571 
572 
573 /* Mailbox status set used by 84858 only */
574 #define PHY84858_STATUS_CMD_RECEIVED			0x0001
575 #define PHY84858_STATUS_CMD_IN_PROGRESS			0x0002
576 #define PHY84858_STATUS_CMD_COMPLETE_PASS		0x0004
577 #define PHY84858_STATUS_CMD_COMPLETE_ERROR		0x0008
578 #define PHY84858_STATUS_CMD_SYSTEM_BUSY                 0xbbbb
579 
580 
581 /* Warpcore clause 45 addressing */
582 #define MDIO_WC_DEVAD					0x3
583 #define MDIO_WC_REG_IEEE0BLK_MIICNTL                    0x0
584 #define MDIO_WC_REG_IEEE0BLK_AUTONEGNP                  0x7
585 #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT0       0x10
586 #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1       0x11
587 #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2       0x12
588 	#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY	0x4000
589 	#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ		0x8000
590 #define MDIO_WC_REG_PCS_STATUS2				0x0021
591 #define MDIO_WC_REG_PMD_KR_CONTROL			0x0096
592 #define MDIO_WC_REG_XGXSBLK0_XGXSCONTROL                0x8000
593 #define MDIO_WC_REG_XGXSBLK0_MISCCONTROL1               0x800e
594 #define MDIO_WC_REG_XGXSBLK1_DESKEW                     0x8010
595 #define MDIO_WC_REG_XGXSBLK1_LANECTRL0                  0x8015
596 #define MDIO_WC_REG_XGXSBLK1_LANECTRL1                  0x8016
597 #define MDIO_WC_REG_XGXSBLK1_LANECTRL2                  0x8017
598 #define MDIO_WC_REG_XGXSBLK1_LANECTRL3                  0x8018
599 #define MDIO_WC_REG_XGXSBLK1_LANETEST0                  0x801a
600 #define MDIO_WC_REG_TX0_ANA_CTRL0			0x8061
601 #define MDIO_WC_REG_TX1_ANA_CTRL0			0x8071
602 #define MDIO_WC_REG_TX2_ANA_CTRL0			0x8081
603 #define MDIO_WC_REG_TX3_ANA_CTRL0			0x8091
604 #define MDIO_WC_REG_TX0_TX_DRIVER			0x8067
605 #define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET			0x01
606 #define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_MASK				0x000e
607 #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET		0x04
608 #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_MASK			0x00f0
609 #define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET		0x08
610 #define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_MASK				0x0f00
611 #define MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET		0x0c
612 #define MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_MASK			0x7000
613 #define MDIO_WC_REG_TX1_TX_DRIVER			0x8077
614 #define MDIO_WC_REG_TX2_TX_DRIVER			0x8087
615 #define MDIO_WC_REG_TX3_TX_DRIVER			0x8097
616 #define MDIO_WC_REG_RX0_ANARXCONTROL1G                  0x80b9
617 #define MDIO_WC_REG_RX2_ANARXCONTROL1G                  0x80d9
618 #define MDIO_WC_REG_RX0_PCI_CTRL			0x80ba
619 #define MDIO_WC_REG_RX1_PCI_CTRL			0x80ca
620 #define MDIO_WC_REG_RX2_PCI_CTRL			0x80da
621 #define MDIO_WC_REG_RX3_PCI_CTRL			0x80ea
622 #define MDIO_WC_REG_RXB_ANA_RX_CONTROL_PCI		0x80fa
623 #define MDIO_WC_REG_XGXSBLK2_UNICORE_MODE_10G 		0x8104
624 #define MDIO_WC_REG_XGXSBLK2_LANE_RESET 		0x810a
625 #define MDIO_WC_REG_XGXS_STATUS3			0x8129
626 #define MDIO_WC_REG_PAR_DET_10G_STATUS			0x8130
627 #define MDIO_WC_REG_PAR_DET_10G_CTRL			0x8131
628 #define MDIO_WC_REG_XGXS_STATUS4                        0x813c
629 #define MDIO_WC_REG_XGXS_X2_CONTROL2 		        0x8141
630 #define MDIO_WC_REG_XGXS_X2_CONTROL3 		        0x8142
631 #define MDIO_WC_REG_XGXS_RX_LN_SWAP1		      	0x816B
632 #define MDIO_WC_REG_XGXS_TX_LN_SWAP1		      	0x8169
633 #define MDIO_WC_REG_GP2_STATUS_GP_2_0			0x81d0
634 #define MDIO_WC_REG_GP2_STATUS_GP_2_1			0x81d1
635 #define MDIO_WC_REG_GP2_STATUS_GP_2_2			0x81d2
636 #define MDIO_WC_REG_GP2_STATUS_GP_2_3			0x81d3
637 #define MDIO_WC_REG_GP2_STATUS_GP_2_4			0x81d4
638 	#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL 0x1000
639 	#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CMPL 0x0100
640 	#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP 0x0010
641 	#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CAP 0x1
642 #define MDIO_WC_REG_UC_INFO_B0_DEAD_TRAP                0x81EE
643 #define MDIO_WC_REG_UC_INFO_B1_VERSION                  0x81F0
644 #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE		0x81F2
645 	#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE0_OFFSET	0x0
646 		#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT        0x0
647 		#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_OPT_LR     0x1
648 		#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC        0x2
649 		#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_XLAUI      0x3
650 		#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_LONG_CH_6G     0x4
651 	#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE1_OFFSET	0x4
652 	#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE2_OFFSET	0x8
653 	#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE3_OFFSET	0xc
654 #define MDIO_WC_REG_UC_INFO_B1_CRC                      0x81FE
655 #define MDIO_WC_REG_DSC1B0_UC_CTRL				0x820e
656 	#define MDIO_WC_REG_DSC1B0_UC_CTRL_RDY4CMD			(1<<7)
657 #define MDIO_WC_REG_DSC_SMC				0x8213
658 #define MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0		0x821e
659 #define MDIO_WC_REG_TX_FIR_TAP				0x82e2
660 	#define MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET		0x00
661 	#define MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_MASK			0x000f
662 	#define MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET		0x04
663 	#define MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_MASK		0x03f0
664 	#define MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET		0x0a
665 	#define MDIO_WC_REG_TX_FIR_TAP_POST_TAP_MASK		0x7c00
666 	#define MDIO_WC_REG_TX_FIR_TAP_ENABLE		0x8000
667 #define MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP		0x82e2
668 #define MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL      0x82e3
669 #define MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL	0x82e6
670 #define MDIO_WC_REG_CL72_USERB0_CL72_BR_DEF_CTRL	0x82e7
671 #define MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL	0x82e8
672 #define MDIO_WC_REG_CL72_USERB0_CL72_MISC4_CONTROL      0x82ec
673 #define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1         0x8300
674 #define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2         0x8301
675 #define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3         0x8302
676 #define MDIO_WC_REG_SERDESDIGITAL_STATUS1000X1          0x8304
677 #define MDIO_WC_REG_SERDESDIGITAL_MISC1                 0x8308
678 #define MDIO_WC_REG_SERDESDIGITAL_MISC2                 0x8309
679 #define MDIO_WC_REG_DIGITAL3_UP1                        0x8329
680 #define MDIO_WC_REG_DIGITAL3_LP_UP1                     0x832c
681 #define MDIO_WC_REG_DIGITAL4_MISC3                      0x833c
682 #define MDIO_WC_REG_DIGITAL4_MISC5                      0x833e
683 #define MDIO_WC_REG_DIGITAL5_MISC6                      0x8345
684 #define MDIO_WC_REG_DIGITAL5_MISC7                      0x8349
685 #define MDIO_WC_REG_DIGITAL5_LINK_STATUS		0x834d
686 #define MDIO_WC_REG_DIGITAL5_ACTUAL_SPEED               0x834e
687 #define MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL           0x8350
688 #define MDIO_WC_REG_CL49_USERB0_CTRL	                0x8368
689 #define MDIO_WC_REG_CL73_USERB0_CTRL                    0x8370
690 #define MDIO_WC_REG_CL73_USERB0_USTAT                   0x8371
691 #define MDIO_WC_REG_CL73_BAM_CTRL1			0x8372
692 #define MDIO_WC_REG_CL73_BAM_CTRL2			0x8373
693 #define MDIO_WC_REG_CL73_BAM_CTRL3			0x8374
694 #define MDIO_WC_REG_CL73_BAM_CODE_FIELD			0x837b
695 #define MDIO_WC_REG_EEE_COMBO_CONTROL0                  0x8390
696 #define MDIO_WC_REG_TX66_CONTROL                        0x83b0
697 #define MDIO_WC_REG_RX66_CONTROL                        0x83c0
698 #define MDIO_WC_REG_RX66_SCW0                           0x83c2
699 #define MDIO_WC_REG_RX66_SCW1                           0x83c3
700 #define MDIO_WC_REG_RX66_SCW2                           0x83c4
701 #define MDIO_WC_REG_RX66_SCW3                           0x83c5
702 #define MDIO_WC_REG_RX66_SCW0_MASK                      0x83c6
703 #define MDIO_WC_REG_RX66_SCW1_MASK                      0x83c7
704 #define MDIO_WC_REG_RX66_SCW2_MASK                      0x83c8
705 #define MDIO_WC_REG_RX66_SCW3_MASK                      0x83c9
706 #define MDIO_WC_REG_FX100_CTRL1				0x8400
707 #define MDIO_WC_REG_FX100_CTRL3				0x8402
708 #define MDIO_WC_REG_CL82_USERB1_TX_CTRL5		0x8436
709 #define MDIO_WC_REG_CL82_USERB1_TX_CTRL6		0x8437
710 #define MDIO_WC_REG_CL82_USERB1_TX_CTRL7		0x8438
711 #define MDIO_WC_REG_CL82_USERB1_TX_CTRL9		0x8439
712 #define MDIO_WC_REG_CL82_USERB1_RX_CTRL10		0x843a
713 #define MDIO_WC_REG_CL82_USERB1_RX_CTRL11		0x843b
714 #define MDIO_WC_REG_ETA_CL73_OUI1			0x8453
715 #define MDIO_WC_REG_ETA_CL73_OUI2			0x8454
716 #define MDIO_WC_REG_ETA_CL73_OUI3			0x8455
717 #define MDIO_WC_REG_ETA_CL73_LD_BAM_CODE		0x8456
718 #define MDIO_WC_REG_ETA_CL73_LD_UD_CODE			0x8457
719 #define MDIO_WC_REG_MICROBLK_CMD                        0xffc2
720 #define MDIO_WC_REG_MICROBLK_DL_STATUS                  0xffc5
721 #define MDIO_WC_REG_MICROBLK_CMD3                       0xffcc
722 
723 #define MDIO_WC_REG_AERBLK_AER                          0xffde
724 #define MDIO_WC_REG_COMBO_IEEE0_MIICTRL			0xffe0
725 #define MDIO_WC_REG_COMBO_IEEE0_MIIISTAT                0xffe1
726 
727 #define MDIO_WC0_XGXS_BLK2_LANE_RESET                   0x810A
728 	#define MDIO_WC0_XGXS_BLK2_LANE_RESET_RX_BITSHIFT 	0
729 	#define MDIO_WC0_XGXS_BLK2_LANE_RESET_TX_BITSHIFT 	4
730 
731 #define MDIO_WC0_XGXS_BLK6_XGXS_X2_CONTROL2             0x8141
732 
733 #define DIGITAL5_ACTUAL_SPEED_TX_MASK                   0x003f
734 
735 /* 54618se */
736 #define MDIO_REG_GPHY_MII_STATUS			0x1
737 #define MDIO_REG_GPHY_PHYID_LSB				0x3
738 #define MDIO_REG_GPHY_CL45_ADDR_REG			0xd
739 	#define MDIO_REG_GPHY_CL45_REG_WRITE		0x4000
740 	#define MDIO_REG_GPHY_CL45_REG_READ		0xc000
741 #define MDIO_REG_GPHY_CL45_DATA_REG			0xe
742 	#define MDIO_REG_GPHY_EEE_RESOLVED		0x803e
743 #define MDIO_REG_GPHY_EXP_ACCESS_GATE			0x15
744 #define MDIO_REG_GPHY_EXP_ACCESS			0x17
745 	#define MDIO_REG_GPHY_EXP_ACCESS_TOP		0xd00
746 	#define MDIO_REG_GPHY_EXP_TOP_2K_BUF		0x40
747 #define MDIO_REG_GPHY_AUX_STATUS			0x19
748 #define MDIO_REG_INTR_STATUS				0x1a
749 #define MDIO_REG_INTR_MASK				0x1b
750 	#define MDIO_REG_INTR_MASK_LINK_STATUS			(0x1 << 1)
751 #define MDIO_REG_GPHY_SHADOW				0x1c
752 	#define MDIO_REG_GPHY_SHADOW_LED_SEL1			(0x0d << 10)
753 	#define MDIO_REG_GPHY_SHADOW_LED_SEL2			(0x0e << 10)
754 	#define MDIO_REG_GPHY_SHADOW_WR_ENA			(0x1 << 15)
755 	#define MDIO_REG_GPHY_SHADOW_AUTO_DET_MED		(0x1e << 10)
756 	#define MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD		(0x1 << 8)
757 
758 
759 typedef elink_status_t (*read_sfp_module_eeprom_func_p)(struct elink_phy *phy,
760 					     struct elink_params *params,
761 					     uint8_t dev_addr, uint16_t addr, uint8_t byte_cnt,
762 					     uint8_t *o_buf, uint8_t);
763 /********************************************************/
764 #define ELINK_ETH_HLEN			14
765 /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
766 #define ELINK_ETH_OVREHEAD			(ELINK_ETH_HLEN + 8 + 8)
767 #define ELINK_ETH_MIN_PACKET_SIZE		60
768 #define ELINK_ETH_MAX_PACKET_SIZE		1500
769 #define ELINK_ETH_MAX_JUMBO_PACKET_SIZE	9600
770 #define ELINK_MDIO_ACCESS_TIMEOUT		1000
771 #define WC_LANE_MAX			4
772 #define I2C_SWITCH_WIDTH		2
773 #define I2C_BSC0			0
774 #define I2C_BSC1			1
775 #define I2C_WA_RETRY_CNT		3
776 #define I2C_WA_PWR_ITER			(I2C_WA_RETRY_CNT - 1)
777 #define MCPR_IMC_COMMAND_READ_OP	1
778 #define MCPR_IMC_COMMAND_WRITE_OP	2
779 
780 /* LED Blink rate that will achieve ~15.9Hz */
781 #define LED_BLINK_RATE_VAL_E3		354
782 #define LED_BLINK_RATE_VAL_E1X_E2	480
783 /***********************************************************/
784 /*			Shortcut definitions		   */
785 /***********************************************************/
786 
787 #define ELINK_NIG_LATCH_BC_ENABLE_MI_INT 0
788 
789 #define ELINK_NIG_STATUS_EMAC0_MI_INT \
790 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
791 #define ELINK_NIG_STATUS_XGXS0_LINK10G \
792 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
793 #define ELINK_NIG_STATUS_XGXS0_LINK_STATUS \
794 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
795 #define ELINK_NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
796 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
797 #define ELINK_NIG_STATUS_SERDES0_LINK_STATUS \
798 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
799 #define ELINK_NIG_MASK_MI_INT \
800 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
801 #define ELINK_NIG_MASK_XGXS0_LINK10G \
802 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
803 #define ELINK_NIG_MASK_XGXS0_LINK_STATUS \
804 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
805 #define ELINK_NIG_MASK_SERDES0_LINK_STATUS \
806 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
807 
808 #define ELINK_MDIO_AN_CL73_OR_37_COMPLETE \
809 		(MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
810 		 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
811 
812 #define ELINK_XGXS_RESET_BITS \
813 	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
814 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
815 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
816 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
817 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
818 
819 #define ELINK_SERDES_RESET_BITS \
820 	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
821 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
822 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
823 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
824 
825 #define ELINK_AUTONEG_CL37		SHARED_HW_CFG_AN_ENABLE_CL37
826 #define ELINK_AUTONEG_CL73		SHARED_HW_CFG_AN_ENABLE_CL73
827 #define ELINK_AUTONEG_BAM		SHARED_HW_CFG_AN_ENABLE_BAM
828 #define ELINK_AUTONEG_PARALLEL \
829 				SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
830 #define ELINK_AUTONEG_SGMII_FIBER_AUTODET \
831 				SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
832 #define ELINK_AUTONEG_REMOTE_PHY	SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
833 
834 #define ELINK_GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
835 			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
836 #define ELINK_GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
837 			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
838 #define ELINK_GP_STATUS_SPEED_MASK \
839 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
840 #define ELINK_GP_STATUS_10M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
841 #define ELINK_GP_STATUS_100M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
842 #define ELINK_GP_STATUS_1G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
843 #define ELINK_GP_STATUS_2_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
844 #define ELINK_GP_STATUS_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
845 #define ELINK_GP_STATUS_6G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
846 #define ELINK_GP_STATUS_10G_HIG \
847 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
848 #define ELINK_GP_STATUS_10G_CX4 \
849 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
850 #define ELINK_GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
851 #define ELINK_GP_STATUS_10G_KX4 \
852 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
853 #define	ELINK_GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
854 #define	ELINK_GP_STATUS_10G_XFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
855 #define	ELINK_GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
856 #define	ELINK_GP_STATUS_10G_SFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
857 #define	ELINK_GP_STATUS_20G_KR2 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_KR2
858 #define ELINK_LINK_10THD		LINK_STATUS_SPEED_AND_DUPLEX_10THD
859 #define ELINK_LINK_10TFD		LINK_STATUS_SPEED_AND_DUPLEX_10TFD
860 #define ELINK_LINK_100TXHD		LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
861 #define ELINK_LINK_100T4		LINK_STATUS_SPEED_AND_DUPLEX_100T4
862 #define ELINK_LINK_100TXFD		LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
863 #define ELINK_LINK_1000THD		LINK_STATUS_SPEED_AND_DUPLEX_1000THD
864 #define ELINK_LINK_1000TFD		LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
865 #define ELINK_LINK_1000XFD		LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
866 #define ELINK_LINK_2500THD		LINK_STATUS_SPEED_AND_DUPLEX_2500THD
867 #define ELINK_LINK_2500TFD		LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
868 #define ELINK_LINK_2500XFD		LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
869 #define ELINK_LINK_10GTFD		LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
870 #define ELINK_LINK_10GXFD		LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
871 #define ELINK_LINK_20GTFD		LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
872 #define ELINK_LINK_20GXFD		LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
873 
874 #define ELINK_LINK_UPDATE_MASK \
875 			(LINK_STATUS_SPEED_AND_DUPLEX_MASK | \
876 			 LINK_STATUS_LINK_UP | \
877 			 LINK_STATUS_PHYSICAL_LINK_FLAG | \
878 			 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \
879 			 LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \
880 			 LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \
881 			 LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \
882 			 LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \
883 			 LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE)
884 
885 #define ELINK_SFP_EEPROM_CON_TYPE_ADDR		0x2
886 	#define ELINK_SFP_EEPROM_CON_TYPE_VAL_UNKNOWN	0x0
887 	#define ELINK_SFP_EEPROM_CON_TYPE_VAL_LC	0x7
888 	#define ELINK_SFP_EEPROM_CON_TYPE_VAL_COPPER	0x21
889 	#define ELINK_SFP_EEPROM_CON_TYPE_VAL_RJ45	0x22
890 
891 
892 #define ELINK_SFP_EEPROM_10G_COMP_CODE_ADDR		0x3
893 	#define ELINK_SFP_EEPROM_10G_COMP_CODE_SR_MASK	(1<<4)
894 	#define ELINK_SFP_EEPROM_10G_COMP_CODE_LR_MASK	(1<<5)
895 	#define ELINK_SFP_EEPROM_10G_COMP_CODE_LRM_MASK	(1<<6)
896 
897 #define ELINK_SFP_EEPROM_1G_COMP_CODE_ADDR		0x6
898 	#define ELINK_SFP_EEPROM_1G_COMP_CODE_SX	(1<<0)
899 	#define ELINK_SFP_EEPROM_1G_COMP_CODE_LX	(1<<1)
900 	#define ELINK_SFP_EEPROM_1G_COMP_CODE_CX	(1<<2)
901 	#define ELINK_SFP_EEPROM_1G_COMP_CODE_BASE_T	(1<<3)
902 
903 #define ELINK_SFP_EEPROM_FC_TX_TECH_ADDR		0x8
904 	#define ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
905 	#define ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE  0x8
906 
907 #define ELINK_SFP_EEPROM_OPTIONS_ADDR			0x40
908 	#define ELINK_SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
909 #define ELINK_SFP_EEPROM_OPTIONS_SIZE			2
910 
911 #define ELINK_EDC_MODE_LINEAR				0x0022
912 #define ELINK_EDC_MODE_LIMITING				0x0044
913 #define ELINK_EDC_MODE_PASSIVE_DAC			0x0055
914 #define ELINK_EDC_MODE_ACTIVE_DAC			0x0066
915 
916 /* ETS defines*/
917 #define DCBX_INVALID_COS					(0xFF)
918 
919 #define ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND		(0x5000)
920 #define ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT		(0x5000)
921 #define ELINK_ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS		(1360)
922 #define ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS			(2720)
923 #define ELINK_ETS_E3B0_PBF_MIN_W_VAL				(10000)
924 
925 #define ELINK_MAX_PACKET_SIZE					(9700)
926 #define MAX_KR_LINK_RETRY				4
927 #define DEFAULT_TX_DRV_BRDCT		2
928 #define DEFAULT_TX_DRV_IFIR		0
929 #define DEFAULT_TX_DRV_POST2		3
930 #define DEFAULT_TX_DRV_IPRE_DRIVER	6
931 
932 /**********************************************************/
933 /*                     INTERFACE                          */
934 /**********************************************************/
935 
936 #define CL22_WR_OVER_CL45(_sc, _phy, _bank, _addr, _val) \
937 	elink_cl45_write(_sc, _phy, \
938 		(_phy)->def_md_devad, \
939 		(_bank + (_addr & 0xf)), \
940 		_val)
941 
942 #define CL22_RD_OVER_CL45(_sc, _phy, _bank, _addr, _val) \
943 	elink_cl45_read(_sc, _phy, \
944 		(_phy)->def_md_devad, \
945 		(_bank + (_addr & 0xf)), \
946 		_val)
947 
948 static elink_status_t elink_check_half_open_conn(struct elink_params *params,
949 				      struct elink_vars *vars, uint8_t notify);
950 static elink_status_t elink_sfp_module_detection(struct elink_phy *phy,
951 				      struct elink_params *params);
952 
953 static uint32_t elink_bits_en(struct bxe_softc *sc, uint32_t reg, uint32_t bits)
954 {
955 	uint32_t val = REG_RD(sc, reg);
956 
957 	val |= bits;
958 	REG_WR(sc, reg, val);
959 	return val;
960 }
961 
962 static uint32_t elink_bits_dis(struct bxe_softc *sc, uint32_t reg, uint32_t bits)
963 {
964 	uint32_t val = REG_RD(sc, reg);
965 
966 	val &= ~bits;
967 	REG_WR(sc, reg, val);
968 	return val;
969 }
970 
971 /*
972  * elink_check_lfa - This function checks if link reinitialization is required,
973  *                   or link flap can be avoided.
974  *
975  * @params:	link parameters
976  * Returns 0 if Link Flap Avoidance conditions are met otherwise, the failed
977  *         condition code.
978  */
979 static int elink_check_lfa(struct elink_params *params)
980 {
981 	uint32_t link_status, cfg_idx, lfa_mask, cfg_size;
982 	uint32_t cur_speed_cap_mask, cur_req_fc_auto_adv, additional_config;
983 	uint32_t saved_val, req_val, eee_status;
984 	struct bxe_softc *sc = params->sc;
985 
986 	additional_config =
987 		REG_RD(sc, params->lfa_base +
988 			   offsetof(struct shmem_lfa, additional_config));
989 
990 	/* NOTE: must be first condition checked -
991 	* to verify DCC bit is cleared in any case!
992 	*/
993 	if (additional_config & NO_LFA_DUE_TO_DCC_MASK) {
994 		ELINK_DEBUG_P0(sc, "No LFA due to DCC flap after clp exit\n");
995 		REG_WR(sc, params->lfa_base +
996 			   offsetof(struct shmem_lfa, additional_config),
997 		       additional_config & ~NO_LFA_DUE_TO_DCC_MASK);
998 		return LFA_DCC_LFA_DISABLED;
999 	}
1000 
1001 	/* Verify that link is up */
1002 	link_status = REG_RD(sc, params->shmem_base +
1003 			     offsetof(struct shmem_region,
1004 				      port_mb[params->port].link_status));
1005 	if (!(link_status & LINK_STATUS_LINK_UP))
1006 		return LFA_LINK_DOWN;
1007 
1008 	/* if loaded after BOOT from SAN, don't flap the link in any case and
1009 	 * rely on link set by preboot driver
1010 	 */
1011 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_BOOT_FROM_SAN)
1012 		return 0;
1013 
1014 	/* Verify that loopback mode is not set */
1015 	if (params->loopback_mode)
1016 		return LFA_LOOPBACK_ENABLED;
1017 
1018 	/* Verify that MFW supports LFA */
1019 	if (!params->lfa_base)
1020 		return LFA_MFW_IS_TOO_OLD;
1021 
1022 	if (params->num_phys == 3) {
1023 		cfg_size = 2;
1024 		lfa_mask = 0xffffffff;
1025 	} else {
1026 		cfg_size = 1;
1027 		lfa_mask = 0xffff;
1028 	}
1029 
1030 	/* Compare Duplex */
1031 	saved_val = REG_RD(sc, params->lfa_base +
1032 			   offsetof(struct shmem_lfa, req_duplex));
1033 	req_val = params->req_duplex[0] | (params->req_duplex[1] << 16);
1034 	if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
1035 		ELINK_DEBUG_P2(sc, "Duplex mismatch %x vs. %x\n",
1036 			       (saved_val & lfa_mask), (req_val & lfa_mask));
1037 		return LFA_DUPLEX_MISMATCH;
1038 	}
1039 	/* Compare Flow Control */
1040 	saved_val = REG_RD(sc, params->lfa_base +
1041 			   offsetof(struct shmem_lfa, req_flow_ctrl));
1042 	req_val = params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16);
1043 	if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
1044 		ELINK_DEBUG_P2(sc, "Flow control mismatch %x vs. %x\n",
1045 			       (saved_val & lfa_mask), (req_val & lfa_mask));
1046 		return LFA_FLOW_CTRL_MISMATCH;
1047 	}
1048 	/* Compare Link Speed */
1049 	saved_val = REG_RD(sc, params->lfa_base +
1050 			   offsetof(struct shmem_lfa, req_line_speed));
1051 	req_val = params->req_line_speed[0] | (params->req_line_speed[1] << 16);
1052 	if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
1053 		ELINK_DEBUG_P2(sc, "Link speed mismatch %x vs. %x\n",
1054 			       (saved_val & lfa_mask), (req_val & lfa_mask));
1055 		return LFA_LINK_SPEED_MISMATCH;
1056 	}
1057 
1058 	for (cfg_idx = 0; cfg_idx < cfg_size; cfg_idx++) {
1059 		cur_speed_cap_mask = REG_RD(sc, params->lfa_base +
1060 					    offsetof(struct shmem_lfa,
1061 						     speed_cap_mask[cfg_idx]));
1062 
1063 		if (cur_speed_cap_mask != params->speed_cap_mask[cfg_idx]) {
1064 			ELINK_DEBUG_P2(sc, "Speed Cap mismatch %x vs. %x\n",
1065 				       cur_speed_cap_mask,
1066 				       params->speed_cap_mask[cfg_idx]);
1067 			return LFA_SPEED_CAP_MISMATCH;
1068 		}
1069 	}
1070 
1071 	cur_req_fc_auto_adv =
1072 		REG_RD(sc, params->lfa_base +
1073 		       offsetof(struct shmem_lfa, additional_config)) &
1074 		REQ_FC_AUTO_ADV_MASK;
1075 
1076 	if ((uint16_t)cur_req_fc_auto_adv != params->req_fc_auto_adv) {
1077 		ELINK_DEBUG_P2(sc, "Flow Ctrl AN mismatch %x vs. %x\n",
1078 			       cur_req_fc_auto_adv, params->req_fc_auto_adv);
1079 		return LFA_FLOW_CTRL_MISMATCH;
1080 	}
1081 
1082 	eee_status = REG_RD(sc, params->shmem2_base +
1083 			    offsetof(struct shmem2_region,
1084 				     eee_status[params->port]));
1085 
1086 	if (((eee_status & SHMEM_EEE_LPI_REQUESTED_BIT) ^
1087 	     (params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)) ||
1088 	    ((eee_status & SHMEM_EEE_REQUESTED_BIT) ^
1089 	     (params->eee_mode & ELINK_EEE_MODE_ADV_LPI))) {
1090 		ELINK_DEBUG_P2(sc, "EEE mismatch %x vs. %x\n", params->eee_mode,
1091 			       eee_status);
1092 		return LFA_EEE_MISMATCH;
1093 	}
1094 
1095 	/* LFA conditions are met */
1096 	return 0;
1097 }
1098 /******************************************************************/
1099 /*			EPIO/GPIO section			  */
1100 /******************************************************************/
1101 static void elink_get_epio(struct bxe_softc *sc, uint32_t epio_pin, uint32_t *en)
1102 {
1103 	uint32_t epio_mask, gp_oenable;
1104 	*en = 0;
1105 	/* Sanity check */
1106 	if (epio_pin > 31) {
1107 		ELINK_DEBUG_P1(sc, "Invalid EPIO pin %d to get\n", epio_pin);
1108 		return;
1109 	}
1110 
1111 	epio_mask = 1 << epio_pin;
1112 	/* Set this EPIO to output */
1113 	gp_oenable = REG_RD(sc, MCP_REG_MCPR_GP_OENABLE);
1114 	REG_WR(sc, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask);
1115 
1116 	*en = (REG_RD(sc, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin;
1117 }
1118 static void elink_set_epio(struct bxe_softc *sc, uint32_t epio_pin, uint32_t en)
1119 {
1120 	uint32_t epio_mask, gp_output, gp_oenable;
1121 
1122 	/* Sanity check */
1123 	if (epio_pin > 31) {
1124 		ELINK_DEBUG_P1(sc, "Invalid EPIO pin %d to set\n", epio_pin);
1125 		return;
1126 	}
1127 	ELINK_DEBUG_P2(sc, "Setting EPIO pin %d to %d\n", epio_pin, en);
1128 	epio_mask = 1 << epio_pin;
1129 	/* Set this EPIO to output */
1130 	gp_output = REG_RD(sc, MCP_REG_MCPR_GP_OUTPUTS);
1131 	if (en)
1132 		gp_output |= epio_mask;
1133 	else
1134 		gp_output &= ~epio_mask;
1135 
1136 	REG_WR(sc, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
1137 
1138 	/* Set the value for this EPIO */
1139 	gp_oenable = REG_RD(sc, MCP_REG_MCPR_GP_OENABLE);
1140 	REG_WR(sc, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
1141 }
1142 
1143 static void elink_set_cfg_pin(struct bxe_softc *sc, uint32_t pin_cfg, uint32_t val)
1144 {
1145 	if (pin_cfg == PIN_CFG_NA)
1146 		return;
1147 	if (pin_cfg >= PIN_CFG_EPIO0) {
1148 		elink_set_epio(sc, pin_cfg - PIN_CFG_EPIO0, val);
1149 	} else {
1150 		uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
1151 		uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
1152 		elink_cb_gpio_write(sc, gpio_num, (uint8_t)val, gpio_port);
1153 	}
1154 }
1155 
1156 static uint32_t elink_get_cfg_pin(struct bxe_softc *sc, uint32_t pin_cfg, uint32_t *val)
1157 {
1158 	if (pin_cfg == PIN_CFG_NA)
1159 		return ELINK_STATUS_ERROR;
1160 	if (pin_cfg >= PIN_CFG_EPIO0) {
1161 		elink_get_epio(sc, pin_cfg - PIN_CFG_EPIO0, val);
1162 	} else {
1163 		uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
1164 		uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
1165 		*val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
1166 	}
1167 	return ELINK_STATUS_OK;
1168 
1169 }
1170 /******************************************************************/
1171 /*				ETS section			  */
1172 /******************************************************************/
1173 static void elink_ets_e2e3a0_disabled(struct elink_params *params)
1174 {
1175 	/* ETS disabled configuration*/
1176 	struct bxe_softc *sc = params->sc;
1177 
1178 	ELINK_DEBUG_P0(sc, "ETS E2E3 disabled configuration\n");
1179 
1180 	/* mapping between entry  priority to client number (0,1,2 -debug and
1181 	 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
1182 	 * 3bits client num.
1183 	 *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1184 	 * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
1185 	 */
1186 
1187 	REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
1188 	/* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1189 	 * as strict.  Bits 0,1,2 - debug and management entries, 3 -
1190 	 * COS0 entry, 4 - COS1 entry.
1191 	 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
1192 	 * bit4   bit3	  bit2   bit1	  bit0
1193 	 * MCP and debug are strict
1194 	 */
1195 
1196 	REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
1197 	/* defines which entries (clients) are subjected to WFQ arbitration */
1198 	REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
1199 	/* For strict priority entries defines the number of consecutive
1200 	 * slots for the highest priority.
1201 	 */
1202 	REG_WR(sc, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1203 	/* mapping between the CREDIT_WEIGHT registers and actual client
1204 	 * numbers
1205 	 */
1206 	REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
1207 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
1208 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
1209 
1210 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
1211 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
1212 	REG_WR(sc, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
1213 	/* ETS mode disable */
1214 	REG_WR(sc, PBF_REG_ETS_ENABLED, 0);
1215 	/* If ETS mode is enabled (there is no strict priority) defines a WFQ
1216 	 * weight for COS0/COS1.
1217 	 */
1218 	REG_WR(sc, PBF_REG_COS0_WEIGHT, 0x2710);
1219 	REG_WR(sc, PBF_REG_COS1_WEIGHT, 0x2710);
1220 	/* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
1221 	REG_WR(sc, PBF_REG_COS0_UPPER_BOUND, 0x989680);
1222 	REG_WR(sc, PBF_REG_COS1_UPPER_BOUND, 0x989680);
1223 	/* Defines the number of consecutive slots for the strict priority */
1224 	REG_WR(sc, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1225 }
1226 /******************************************************************************
1227 * Description:
1228 *	Getting min_w_val will be set according to line speed .
1229 *.
1230 ******************************************************************************/
1231 static uint32_t elink_ets_get_min_w_val_nig(const struct elink_vars *vars)
1232 {
1233 	uint32_t min_w_val = 0;
1234 	/* Calculate min_w_val.*/
1235 	if (vars->link_up) {
1236 		if (vars->line_speed == ELINK_SPEED_20000)
1237 			min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
1238 		else
1239 			min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS;
1240 	} else
1241 		min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
1242 	/* If the link isn't up (static configuration for example ) The
1243 	 * link will be according to 20GBPS.
1244 	 */
1245 	return min_w_val;
1246 }
1247 /******************************************************************************
1248 * Description:
1249 *	Getting credit upper bound form min_w_val.
1250 *.
1251 ******************************************************************************/
1252 static uint32_t elink_ets_get_credit_upper_bound(const uint32_t min_w_val)
1253 {
1254 	const uint32_t credit_upper_bound = (uint32_t)ELINK_MAXVAL((150 * min_w_val),
1255 						ELINK_MAX_PACKET_SIZE);
1256 	return credit_upper_bound;
1257 }
1258 /******************************************************************************
1259 * Description:
1260 *	Set credit upper bound for NIG.
1261 *.
1262 ******************************************************************************/
1263 static void elink_ets_e3b0_set_credit_upper_bound_nig(
1264 	const struct elink_params *params,
1265 	const uint32_t min_w_val)
1266 {
1267 	struct bxe_softc *sc = params->sc;
1268 	const uint8_t port = params->port;
1269 	const uint32_t credit_upper_bound =
1270 	    elink_ets_get_credit_upper_bound(min_w_val);
1271 
1272 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 :
1273 		NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound);
1274 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 :
1275 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound);
1276 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 :
1277 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound);
1278 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 :
1279 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound);
1280 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 :
1281 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound);
1282 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 :
1283 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound);
1284 
1285 	if (!port) {
1286 		REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6,
1287 			credit_upper_bound);
1288 		REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7,
1289 			credit_upper_bound);
1290 		REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8,
1291 			credit_upper_bound);
1292 	}
1293 }
1294 /******************************************************************************
1295 * Description:
1296 *	Will return the NIG ETS registers to init values.Except
1297 *	credit_upper_bound.
1298 *	That isn't used in this configuration (No WFQ is enabled) and will be
1299 *	configured according to spec.
1300 *.
1301 ******************************************************************************/
1302 static void elink_ets_e3b0_nig_disabled(const struct elink_params *params,
1303 					const struct elink_vars *vars)
1304 {
1305 	struct bxe_softc *sc = params->sc;
1306 	const uint8_t port = params->port;
1307 	const uint32_t min_w_val = elink_ets_get_min_w_val_nig(vars);
1308 	/* Mapping between entry  priority to client number (0,1,2 -debug and
1309 	 * management clients, 3 - COS0 client, 4 - COS1, ... 8 -
1310 	 * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
1311 	 * reset value or init tool
1312 	 */
1313 	if (port) {
1314 		REG_WR(sc, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210);
1315 		REG_WR(sc, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0);
1316 	} else {
1317 		REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210);
1318 		REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8);
1319 	}
1320 	/* For strict priority entries defines the number of consecutive
1321 	 * slots for the highest priority.
1322 	 */
1323 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
1324 		   NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1325 	/* Mapping between the CREDIT_WEIGHT registers and actual client
1326 	 * numbers
1327 	 */
1328 	if (port) {
1329 		/*Port 1 has 6 COS*/
1330 		REG_WR(sc, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543);
1331 		REG_WR(sc, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0);
1332 	} else {
1333 		/*Port 0 has 9 COS*/
1334 		REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB,
1335 		       0x43210876);
1336 		REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5);
1337 	}
1338 
1339 	/* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1340 	 * as strict.  Bits 0,1,2 - debug and management entries, 3 -
1341 	 * COS0 entry, 4 - COS1 entry.
1342 	 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
1343 	 * bit4   bit3	  bit2   bit1	  bit0
1344 	 * MCP and debug are strict
1345 	 */
1346 	if (port)
1347 		REG_WR(sc, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f);
1348 	else
1349 		REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff);
1350 	/* defines which entries (clients) are subjected to WFQ arbitration */
1351 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
1352 		   NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
1353 
1354 	/* Please notice the register address are note continuous and a
1355 	 * for here is note appropriate.In 2 port mode port0 only COS0-5
1356 	 * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
1357 	 * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
1358 	 * are never used for WFQ
1359 	 */
1360 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
1361 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0);
1362 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
1363 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0);
1364 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
1365 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0);
1366 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 :
1367 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0);
1368 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 :
1369 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0);
1370 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 :
1371 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0);
1372 	if (!port) {
1373 		REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0);
1374 		REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0);
1375 		REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0);
1376 	}
1377 
1378 	elink_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val);
1379 }
1380 /******************************************************************************
1381 * Description:
1382 *	Set credit upper bound for PBF.
1383 *.
1384 ******************************************************************************/
1385 static void elink_ets_e3b0_set_credit_upper_bound_pbf(
1386 	const struct elink_params *params,
1387 	const uint32_t min_w_val)
1388 {
1389 	struct bxe_softc *sc = params->sc;
1390 	const uint32_t credit_upper_bound =
1391 	    elink_ets_get_credit_upper_bound(min_w_val);
1392 	const uint8_t port = params->port;
1393 	uint32_t base_upper_bound = 0;
1394 	uint8_t max_cos = 0;
1395 	uint8_t i = 0;
1396 	/* In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
1397 	 * port mode port1 has COS0-2 that can be used for WFQ.
1398 	 */
1399 	if (!port) {
1400 		base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0;
1401 		max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1402 	} else {
1403 		base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1;
1404 		max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1;
1405 	}
1406 
1407 	for (i = 0; i < max_cos; i++)
1408 		REG_WR(sc, base_upper_bound + (i << 2), credit_upper_bound);
1409 }
1410 
1411 /******************************************************************************
1412 * Description:
1413 *	Will return the PBF ETS registers to init values.Except
1414 *	credit_upper_bound.
1415 *	That isn't used in this configuration (No WFQ is enabled) and will be
1416 *	configured according to spec.
1417 *.
1418 ******************************************************************************/
1419 static void elink_ets_e3b0_pbf_disabled(const struct elink_params *params)
1420 {
1421 	struct bxe_softc *sc = params->sc;
1422 	const uint8_t port = params->port;
1423 	const uint32_t min_w_val_pbf = ELINK_ETS_E3B0_PBF_MIN_W_VAL;
1424 	uint8_t i = 0;
1425 	uint32_t base_weight = 0;
1426 	uint8_t max_cos = 0;
1427 
1428 	/* Mapping between entry  priority to client number 0 - COS0
1429 	 * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
1430 	 * TODO_ETS - Should be done by reset value or init tool
1431 	 */
1432 	if (port)
1433 		/*  0x688 (|011|0 10|00 1|000) */
1434 		REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , 0x688);
1435 	else
1436 		/*  (10 1|100 |011|0 10|00 1|000) */
1437 		REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , 0x2C688);
1438 
1439 	/* TODO_ETS - Should be done by reset value or init tool */
1440 	if (port)
1441 		/* 0x688 (|011|0 10|00 1|000)*/
1442 		REG_WR(sc, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688);
1443 	else
1444 	/* 0x2C688 (10 1|100 |011|0 10|00 1|000) */
1445 	REG_WR(sc, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688);
1446 
1447 	REG_WR(sc, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 :
1448 		   PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0 , 0x100);
1449 
1450 
1451 	REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
1452 		   PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , 0);
1453 
1454 	REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
1455 		   PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 , 0);
1456 	/* In 2 port mode port0 has COS0-5 that can be used for WFQ.
1457 	 * In 4 port mode port1 has COS0-2 that can be used for WFQ.
1458 	 */
1459 	if (!port) {
1460 		base_weight = PBF_REG_COS0_WEIGHT_P0;
1461 		max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1462 	} else {
1463 		base_weight = PBF_REG_COS0_WEIGHT_P1;
1464 		max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1;
1465 	}
1466 
1467 	for (i = 0; i < max_cos; i++)
1468 		REG_WR(sc, base_weight + (0x4 * i), 0);
1469 
1470 	elink_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1471 }
1472 /******************************************************************************
1473 * Description:
1474 *	E3B0 disable will return basically the values to init values.
1475 *.
1476 ******************************************************************************/
1477 static elink_status_t elink_ets_e3b0_disabled(const struct elink_params *params,
1478 				   const struct elink_vars *vars)
1479 {
1480 	struct bxe_softc *sc = params->sc;
1481 
1482 	if (!CHIP_IS_E3B0(sc)) {
1483 		ELINK_DEBUG_P0(sc,
1484 		   "elink_ets_e3b0_disabled the chip isn't E3B0\n");
1485 		return ELINK_STATUS_ERROR;
1486 	}
1487 
1488 	elink_ets_e3b0_nig_disabled(params, vars);
1489 
1490 	elink_ets_e3b0_pbf_disabled(params);
1491 
1492 	return ELINK_STATUS_OK;
1493 }
1494 
1495 /******************************************************************************
1496 * Description:
1497 *	Disable will return basically the values to init values.
1498 *
1499 ******************************************************************************/
1500 elink_status_t elink_ets_disabled(struct elink_params *params,
1501 		      struct elink_vars *vars)
1502 {
1503 	struct bxe_softc *sc = params->sc;
1504 	elink_status_t elink_status = ELINK_STATUS_OK;
1505 
1506 	if ((CHIP_IS_E2(sc)) || (CHIP_IS_E3A0(sc)))
1507 		elink_ets_e2e3a0_disabled(params);
1508 	else if (CHIP_IS_E3B0(sc))
1509 		elink_status = elink_ets_e3b0_disabled(params, vars);
1510 	else {
1511 		ELINK_DEBUG_P0(sc, "elink_ets_disabled - chip not supported\n");
1512 		return ELINK_STATUS_ERROR;
1513 	}
1514 
1515 	return elink_status;
1516 }
1517 
1518 /******************************************************************************
1519 * Description
1520 *	Set the COS mappimg to SP and BW until this point all the COS are not
1521 *	set as SP or BW.
1522 ******************************************************************************/
1523 static elink_status_t elink_ets_e3b0_cli_map(const struct elink_params *params,
1524 				  const struct elink_ets_params *ets_params,
1525 				  const uint8_t cos_sp_bitmap,
1526 				  const uint8_t cos_bw_bitmap)
1527 {
1528 	struct bxe_softc *sc = params->sc;
1529 	const uint8_t port = params->port;
1530 	const uint8_t nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3);
1531 	const uint8_t pbf_cli_sp_bitmap = cos_sp_bitmap;
1532 	const uint8_t nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3;
1533 	const uint8_t pbf_cli_subject2wfq_bitmap = cos_bw_bitmap;
1534 
1535 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT :
1536 	       NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap);
1537 
1538 	REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
1539 	       PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , pbf_cli_sp_bitmap);
1540 
1541 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
1542 	       NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ,
1543 	       nig_cli_subject2wfq_bitmap);
1544 
1545 	REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
1546 	       PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0,
1547 	       pbf_cli_subject2wfq_bitmap);
1548 
1549 	return ELINK_STATUS_OK;
1550 }
1551 
1552 /******************************************************************************
1553 * Description:
1554 *	This function is needed because NIG ARB_CREDIT_WEIGHT_X are
1555 *	not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
1556 ******************************************************************************/
1557 static elink_status_t elink_ets_e3b0_set_cos_bw(struct bxe_softc *sc,
1558 				     const uint8_t cos_entry,
1559 				     const uint32_t min_w_val_nig,
1560 				     const uint32_t min_w_val_pbf,
1561 				     const uint16_t total_bw,
1562 				     const uint8_t bw,
1563 				     const uint8_t port)
1564 {
1565 	uint32_t nig_reg_adress_crd_weight = 0;
1566 	uint32_t pbf_reg_adress_crd_weight = 0;
1567 	/* Calculate and set BW for this COS - use 1 instead of 0 for BW */
1568 	const uint32_t cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw;
1569 	const uint32_t cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw;
1570 
1571 	switch (cos_entry) {
1572 	case 0:
1573 	    nig_reg_adress_crd_weight =
1574 		 (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
1575 		     NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0;
1576 	     pbf_reg_adress_crd_weight = (port) ?
1577 		 PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0;
1578 	     break;
1579 	case 1:
1580 	     nig_reg_adress_crd_weight = (port) ?
1581 		 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
1582 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1;
1583 	     pbf_reg_adress_crd_weight = (port) ?
1584 		 PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0;
1585 	     break;
1586 	case 2:
1587 	     nig_reg_adress_crd_weight = (port) ?
1588 		 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
1589 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2;
1590 
1591 		 pbf_reg_adress_crd_weight = (port) ?
1592 		     PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0;
1593 	     break;
1594 	case 3:
1595 	    if (port)
1596 			return ELINK_STATUS_ERROR;
1597 	     nig_reg_adress_crd_weight =
1598 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3;
1599 	     pbf_reg_adress_crd_weight =
1600 		 PBF_REG_COS3_WEIGHT_P0;
1601 	     break;
1602 	case 4:
1603 	    if (port)
1604 		return ELINK_STATUS_ERROR;
1605 	     nig_reg_adress_crd_weight =
1606 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4;
1607 	     pbf_reg_adress_crd_weight = PBF_REG_COS4_WEIGHT_P0;
1608 	     break;
1609 	case 5:
1610 	    if (port)
1611 		return ELINK_STATUS_ERROR;
1612 	     nig_reg_adress_crd_weight =
1613 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5;
1614 	     pbf_reg_adress_crd_weight = PBF_REG_COS5_WEIGHT_P0;
1615 	     break;
1616 	}
1617 
1618 	REG_WR(sc, nig_reg_adress_crd_weight, cos_bw_nig);
1619 
1620 	REG_WR(sc, pbf_reg_adress_crd_weight, cos_bw_pbf);
1621 
1622 	return ELINK_STATUS_OK;
1623 }
1624 /******************************************************************************
1625 * Description:
1626 *	Calculate the total BW.A value of 0 isn't legal.
1627 *
1628 ******************************************************************************/
1629 static elink_status_t elink_ets_e3b0_get_total_bw(
1630 	const struct elink_params *params,
1631 	struct elink_ets_params *ets_params,
1632 	uint16_t *total_bw)
1633 {
1634 	struct bxe_softc *sc = params->sc;
1635 	uint8_t cos_idx = 0;
1636 	uint8_t is_bw_cos_exist = 0;
1637 
1638 	*total_bw = 0 ;
1639 	/* Calculate total BW requested */
1640 	for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
1641 		if (ets_params->cos[cos_idx].state == elink_cos_state_bw) {
1642 			is_bw_cos_exist = 1;
1643 			if (!ets_params->cos[cos_idx].params.bw_params.bw) {
1644 				ELINK_DEBUG_P0(sc, "elink_ets_E3B0_config BW"
1645 						   "was set to 0\n");
1646 				/* This is to prevent a state when ramrods
1647 				 * can't be sent
1648 				 */
1649 				ets_params->cos[cos_idx].params.bw_params.bw
1650 					 = 1;
1651 			}
1652 			*total_bw +=
1653 				ets_params->cos[cos_idx].params.bw_params.bw;
1654 		}
1655 	}
1656 
1657 	/* Check total BW is valid */
1658 	if ((is_bw_cos_exist == 1) && (*total_bw != 100)) {
1659 		if (*total_bw == 0) {
1660 			ELINK_DEBUG_P0(sc,
1661 			   "elink_ets_E3B0_config total BW shouldn't be 0\n");
1662 			return ELINK_STATUS_ERROR;
1663 		}
1664 		ELINK_DEBUG_P0(sc,
1665 		   "elink_ets_E3B0_config total BW should be 100\n");
1666 		/* We can handle a case whre the BW isn't 100 this can happen
1667 		 * if the TC are joined.
1668 		 */
1669 	}
1670 	return ELINK_STATUS_OK;
1671 }
1672 
1673 /******************************************************************************
1674 * Description:
1675 *	Invalidate all the sp_pri_to_cos.
1676 *
1677 ******************************************************************************/
1678 static void elink_ets_e3b0_sp_pri_to_cos_init(uint8_t *sp_pri_to_cos)
1679 {
1680 	uint8_t pri = 0;
1681 	for (pri = 0; pri < ELINK_DCBX_MAX_NUM_COS; pri++)
1682 		sp_pri_to_cos[pri] = DCBX_INVALID_COS;
1683 }
1684 /******************************************************************************
1685 * Description:
1686 *	Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1687 *	according to sp_pri_to_cos.
1688 *
1689 ******************************************************************************/
1690 static elink_status_t elink_ets_e3b0_sp_pri_to_cos_set(const struct elink_params *params,
1691 					    uint8_t *sp_pri_to_cos, const uint8_t pri,
1692 					    const uint8_t cos_entry)
1693 {
1694 	struct bxe_softc *sc = params->sc;
1695 	const uint8_t port = params->port;
1696 	const uint8_t max_num_of_cos = (port) ? ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1697 		ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1698 
1699 	if (pri >= max_num_of_cos) {
1700 		ELINK_DEBUG_P0(sc, "elink_ets_e3b0_sp_pri_to_cos_set invalid "
1701 		   "parameter Illegal strict priority\n");
1702 	    return ELINK_STATUS_ERROR;
1703 	}
1704 
1705 	if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {
1706 		ELINK_DEBUG_P0(sc, "elink_ets_e3b0_sp_pri_to_cos_set invalid "
1707 				   "parameter There can't be two COS's with "
1708 				   "the same strict pri\n");
1709 		return ELINK_STATUS_ERROR;
1710 	}
1711 
1712 	sp_pri_to_cos[pri] = cos_entry;
1713 	return ELINK_STATUS_OK;
1714 
1715 }
1716 
1717 /******************************************************************************
1718 * Description:
1719 *	Returns the correct value according to COS and priority in
1720 *	the sp_pri_cli register.
1721 *
1722 ******************************************************************************/
1723 static uint64_t elink_e3b0_sp_get_pri_cli_reg(const uint8_t cos, const uint8_t cos_offset,
1724 					 const uint8_t pri_set,
1725 					 const uint8_t pri_offset,
1726 					 const uint8_t entry_size)
1727 {
1728 	uint64_t pri_cli_nig = 0;
1729 	pri_cli_nig = ((uint64_t)(cos + cos_offset)) << (entry_size *
1730 						    (pri_set + pri_offset));
1731 
1732 	return pri_cli_nig;
1733 }
1734 /******************************************************************************
1735 * Description:
1736 *	Returns the correct value according to COS and priority in the
1737 *	sp_pri_cli register for NIG.
1738 *
1739 ******************************************************************************/
1740 static uint64_t elink_e3b0_sp_get_pri_cli_reg_nig(const uint8_t cos, const uint8_t pri_set)
1741 {
1742 	/* MCP Dbg0 and dbg1 are always with higher strict pri*/
1743 	const uint8_t nig_cos_offset = 3;
1744 	const uint8_t nig_pri_offset = 3;
1745 
1746 	return elink_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set,
1747 		nig_pri_offset, 4);
1748 
1749 }
1750 /******************************************************************************
1751 * Description:
1752 *	Returns the correct value according to COS and priority in the
1753 *	sp_pri_cli register for PBF.
1754 *
1755 ******************************************************************************/
1756 static uint64_t elink_e3b0_sp_get_pri_cli_reg_pbf(const uint8_t cos, const uint8_t pri_set)
1757 {
1758 	const uint8_t pbf_cos_offset = 0;
1759 	const uint8_t pbf_pri_offset = 0;
1760 
1761 	return elink_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set,
1762 		pbf_pri_offset, 3);
1763 
1764 }
1765 
1766 /******************************************************************************
1767 * Description:
1768 *	Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1769 *	according to sp_pri_to_cos.(which COS has higher priority)
1770 *
1771 ******************************************************************************/
1772 static elink_status_t elink_ets_e3b0_sp_set_pri_cli_reg(const struct elink_params *params,
1773 					     uint8_t *sp_pri_to_cos)
1774 {
1775 	struct bxe_softc *sc = params->sc;
1776 	uint8_t i = 0;
1777 	const uint8_t port = params->port;
1778 	/* MCP Dbg0 and dbg1 are always with higher strict pri*/
1779 	uint64_t pri_cli_nig = 0x210;
1780 	uint32_t pri_cli_pbf = 0x0;
1781 	uint8_t pri_set = 0;
1782 	uint8_t pri_bitmask = 0;
1783 	const uint8_t max_num_of_cos = (port) ? ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1784 		ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1785 
1786 	uint8_t cos_bit_to_set = (1 << max_num_of_cos) - 1;
1787 
1788 	/* Set all the strict priority first */
1789 	for (i = 0; i < max_num_of_cos; i++) {
1790 		if (sp_pri_to_cos[i] != DCBX_INVALID_COS) {
1791 			if (sp_pri_to_cos[i] >= ELINK_DCBX_MAX_NUM_COS) {
1792 				ELINK_DEBUG_P0(sc,
1793 					   "elink_ets_e3b0_sp_set_pri_cli_reg "
1794 					   "invalid cos entry\n");
1795 				return ELINK_STATUS_ERROR;
1796 			}
1797 
1798 			pri_cli_nig |= elink_e3b0_sp_get_pri_cli_reg_nig(
1799 			    sp_pri_to_cos[i], pri_set);
1800 
1801 			pri_cli_pbf |= elink_e3b0_sp_get_pri_cli_reg_pbf(
1802 			    sp_pri_to_cos[i], pri_set);
1803 			pri_bitmask = 1 << sp_pri_to_cos[i];
1804 			/* COS is used remove it from bitmap.*/
1805 			if (!(pri_bitmask & cos_bit_to_set)) {
1806 				ELINK_DEBUG_P0(sc,
1807 					"elink_ets_e3b0_sp_set_pri_cli_reg "
1808 					"invalid There can't be two COS's with"
1809 					" the same strict pri\n");
1810 				return ELINK_STATUS_ERROR;
1811 			}
1812 			cos_bit_to_set &= ~pri_bitmask;
1813 			pri_set++;
1814 		}
1815 	}
1816 
1817 	/* Set all the Non strict priority i= COS*/
1818 	for (i = 0; i < max_num_of_cos; i++) {
1819 		pri_bitmask = 1 << i;
1820 		/* Check if COS was already used for SP */
1821 		if (pri_bitmask & cos_bit_to_set) {
1822 			/* COS wasn't used for SP */
1823 			pri_cli_nig |= elink_e3b0_sp_get_pri_cli_reg_nig(
1824 			    i, pri_set);
1825 
1826 			pri_cli_pbf |= elink_e3b0_sp_get_pri_cli_reg_pbf(
1827 			    i, pri_set);
1828 			/* COS is used remove it from bitmap.*/
1829 			cos_bit_to_set &= ~pri_bitmask;
1830 			pri_set++;
1831 		}
1832 	}
1833 
1834 	if (pri_set != max_num_of_cos) {
1835 		ELINK_DEBUG_P0(sc, "elink_ets_e3b0_sp_set_pri_cli_reg not all "
1836 				   "entries were set\n");
1837 		return ELINK_STATUS_ERROR;
1838 	}
1839 
1840 	if (port) {
1841 		/* Only 6 usable clients*/
1842 		REG_WR(sc, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB,
1843 		       (uint32_t)pri_cli_nig);
1844 
1845 		REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , pri_cli_pbf);
1846 	} else {
1847 		/* Only 9 usable clients*/
1848 		const uint32_t pri_cli_nig_lsb = (uint32_t) (pri_cli_nig);
1849 		const uint32_t pri_cli_nig_msb = (uint32_t) ((pri_cli_nig >> 32) & 0xF);
1850 
1851 		REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB,
1852 		       pri_cli_nig_lsb);
1853 		REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB,
1854 		       pri_cli_nig_msb);
1855 
1856 		REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , pri_cli_pbf);
1857 	}
1858 	return ELINK_STATUS_OK;
1859 }
1860 
1861 /******************************************************************************
1862 * Description:
1863 *	Configure the COS to ETS according to BW and SP settings.
1864 ******************************************************************************/
1865 elink_status_t elink_ets_e3b0_config(const struct elink_params *params,
1866 			 const struct elink_vars *vars,
1867 			 struct elink_ets_params *ets_params)
1868 {
1869 	struct bxe_softc *sc = params->sc;
1870 	elink_status_t elink_status = ELINK_STATUS_OK;
1871 	const uint8_t port = params->port;
1872 	uint16_t total_bw = 0;
1873 	const uint32_t min_w_val_nig = elink_ets_get_min_w_val_nig(vars);
1874 	const uint32_t min_w_val_pbf = ELINK_ETS_E3B0_PBF_MIN_W_VAL;
1875 	uint8_t cos_bw_bitmap = 0;
1876 	uint8_t cos_sp_bitmap = 0;
1877 	uint8_t sp_pri_to_cos[ELINK_DCBX_MAX_NUM_COS] = {0};
1878 	const uint8_t max_num_of_cos = (port) ? ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1879 		ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1880 	uint8_t cos_entry = 0;
1881 
1882 	if (!CHIP_IS_E3B0(sc)) {
1883 		ELINK_DEBUG_P0(sc,
1884 		   "elink_ets_e3b0_disabled the chip isn't E3B0\n");
1885 		return ELINK_STATUS_ERROR;
1886 	}
1887 
1888 	if ((ets_params->num_of_cos > max_num_of_cos)) {
1889 		ELINK_DEBUG_P0(sc, "elink_ets_E3B0_config the number of COS "
1890 				   "isn't supported\n");
1891 		return ELINK_STATUS_ERROR;
1892 	}
1893 
1894 	/* Prepare sp strict priority parameters*/
1895 	elink_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos);
1896 
1897 	/* Prepare BW parameters*/
1898 	elink_status = elink_ets_e3b0_get_total_bw(params, ets_params,
1899 						   &total_bw);
1900 	if (elink_status != ELINK_STATUS_OK) {
1901 		ELINK_DEBUG_P0(sc,
1902 		   "elink_ets_E3B0_config get_total_bw failed\n");
1903 		return ELINK_STATUS_ERROR;
1904 	}
1905 
1906 	/* Upper bound is set according to current link speed (min_w_val
1907 	 * should be the same for upper bound and COS credit val).
1908 	 */
1909 	elink_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
1910 	elink_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1911 
1912 
1913 	for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) {
1914 		if (elink_cos_state_bw == ets_params->cos[cos_entry].state) {
1915 			cos_bw_bitmap |= (1 << cos_entry);
1916 			/* The function also sets the BW in HW(not the mappin
1917 			 * yet)
1918 			 */
1919 			elink_status = elink_ets_e3b0_set_cos_bw(
1920 				sc, cos_entry, min_w_val_nig, min_w_val_pbf,
1921 				total_bw,
1922 				ets_params->cos[cos_entry].params.bw_params.bw,
1923 				 port);
1924 		} else if (elink_cos_state_strict ==
1925 			ets_params->cos[cos_entry].state){
1926 			cos_sp_bitmap |= (1 << cos_entry);
1927 
1928 			elink_status = elink_ets_e3b0_sp_pri_to_cos_set(
1929 				params,
1930 				sp_pri_to_cos,
1931 				ets_params->cos[cos_entry].params.sp_params.pri,
1932 				cos_entry);
1933 
1934 		} else {
1935 			ELINK_DEBUG_P0(sc,
1936 			   "elink_ets_e3b0_config cos state not valid\n");
1937 			return ELINK_STATUS_ERROR;
1938 		}
1939 		if (elink_status != ELINK_STATUS_OK) {
1940 			ELINK_DEBUG_P0(sc,
1941 			   "elink_ets_e3b0_config set cos bw failed\n");
1942 			return elink_status;
1943 		}
1944 	}
1945 
1946 	/* Set SP register (which COS has higher priority) */
1947 	elink_status = elink_ets_e3b0_sp_set_pri_cli_reg(params,
1948 							 sp_pri_to_cos);
1949 
1950 	if (elink_status != ELINK_STATUS_OK) {
1951 		ELINK_DEBUG_P0(sc,
1952 		   "elink_ets_E3B0_config set_pri_cli_reg failed\n");
1953 		return elink_status;
1954 	}
1955 
1956 	/* Set client mapping of BW and strict */
1957 	elink_status = elink_ets_e3b0_cli_map(params, ets_params,
1958 					      cos_sp_bitmap,
1959 					      cos_bw_bitmap);
1960 
1961 	if (elink_status != ELINK_STATUS_OK) {
1962 		ELINK_DEBUG_P0(sc, "elink_ets_E3B0_config SP failed\n");
1963 		return elink_status;
1964 	}
1965 	return ELINK_STATUS_OK;
1966 }
1967 static void elink_ets_bw_limit_common(const struct elink_params *params)
1968 {
1969 	/* ETS disabled configuration */
1970 	struct bxe_softc *sc = params->sc;
1971 	ELINK_DEBUG_P0(sc, "ETS enabled BW limit configuration\n");
1972 	/* Defines which entries (clients) are subjected to WFQ arbitration
1973 	 * COS0 0x8
1974 	 * COS1 0x10
1975 	 */
1976 	REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
1977 	/* Mapping between the ARB_CREDIT_WEIGHT registers and actual
1978 	 * client numbers (WEIGHT_0 does not actually have to represent
1979 	 * client 0)
1980 	 *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1981 	 *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
1982 	 */
1983 	REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
1984 
1985 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
1986 	       ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1987 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
1988 	       ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1989 
1990 	/* ETS mode enabled*/
1991 	REG_WR(sc, PBF_REG_ETS_ENABLED, 1);
1992 
1993 	/* Defines the number of consecutive slots for the strict priority */
1994 	REG_WR(sc, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1995 	/* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1996 	 * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
1997 	 * entry, 4 - COS1 entry.
1998 	 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1999 	 * bit4   bit3	  bit2     bit1	   bit0
2000 	 * MCP and debug are strict
2001 	 */
2002 	REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
2003 
2004 	/* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
2005 	REG_WR(sc, PBF_REG_COS0_UPPER_BOUND,
2006 	       ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
2007 	REG_WR(sc, PBF_REG_COS1_UPPER_BOUND,
2008 	       ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
2009 }
2010 
2011 void elink_ets_bw_limit(const struct elink_params *params, const uint32_t cos0_bw,
2012 			const uint32_t cos1_bw)
2013 {
2014 	/* ETS disabled configuration*/
2015 	struct bxe_softc *sc = params->sc;
2016 	const uint32_t total_bw = cos0_bw + cos1_bw;
2017 	uint32_t cos0_credit_weight = 0;
2018 	uint32_t cos1_credit_weight = 0;
2019 
2020 	ELINK_DEBUG_P0(sc, "ETS enabled BW limit configuration\n");
2021 
2022 	if ((!total_bw) ||
2023 	    (!cos0_bw) ||
2024 	    (!cos1_bw)) {
2025 		ELINK_DEBUG_P0(sc, "Total BW can't be zero\n");
2026 		return;
2027 	}
2028 
2029 	cos0_credit_weight = (cos0_bw * ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT)/
2030 		total_bw;
2031 	cos1_credit_weight = (cos1_bw * ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT)/
2032 		total_bw;
2033 
2034 	elink_ets_bw_limit_common(params);
2035 
2036 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
2037 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
2038 
2039 	REG_WR(sc, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
2040 	REG_WR(sc, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
2041 }
2042 
2043 elink_status_t elink_ets_strict(const struct elink_params *params, const uint8_t strict_cos)
2044 {
2045 	/* ETS disabled configuration*/
2046 	struct bxe_softc *sc = params->sc;
2047 	uint32_t val	= 0;
2048 
2049 	ELINK_DEBUG_P0(sc, "ETS enabled strict configuration\n");
2050 	/* Bitmap of 5bits length. Each bit specifies whether the entry behaves
2051 	 * as strict.  Bits 0,1,2 - debug and management entries,
2052 	 * 3 - COS0 entry, 4 - COS1 entry.
2053 	 *  COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
2054 	 *  bit4   bit3	  bit2      bit1     bit0
2055 	 * MCP and debug are strict
2056 	 */
2057 	REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
2058 	/* For strict priority entries defines the number of consecutive slots
2059 	 * for the highest priority.
2060 	 */
2061 	REG_WR(sc, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
2062 	/* ETS mode disable */
2063 	REG_WR(sc, PBF_REG_ETS_ENABLED, 0);
2064 	/* Defines the number of consecutive slots for the strict priority */
2065 	REG_WR(sc, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
2066 
2067 	/* Defines the number of consecutive slots for the strict priority */
2068 	REG_WR(sc, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
2069 
2070 	/* Mapping between entry  priority to client number (0,1,2 -debug and
2071 	 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
2072 	 * 3bits client num.
2073 	 *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
2074 	 * dbg0-010     dbg1-001     cos1-100     cos0-011     MCP-000
2075 	 * dbg0-010     dbg1-001     cos0-011     cos1-100     MCP-000
2076 	 */
2077 	val = (!strict_cos) ? 0x2318 : 0x22E0;
2078 	REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
2079 
2080 	return ELINK_STATUS_OK;
2081 }
2082 
2083 /******************************************************************/
2084 /*			PFC section				  */
2085 /******************************************************************/
2086 static void elink_update_pfc_xmac(struct elink_params *params,
2087 				  struct elink_vars *vars,
2088 				  uint8_t is_lb)
2089 {
2090 	struct bxe_softc *sc = params->sc;
2091 	uint32_t xmac_base;
2092 	uint32_t pause_val, pfc0_val, pfc1_val;
2093 
2094 	/* XMAC base adrr */
2095 	xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
2096 
2097 	/* Initialize pause and pfc registers */
2098 	pause_val = 0x18000;
2099 	pfc0_val = 0xFFFF8000;
2100 	pfc1_val = 0x2;
2101 
2102 	/* No PFC support */
2103 	if (!(params->feature_config_flags &
2104 	      ELINK_FEATURE_CONFIG_PFC_ENABLED)) {
2105 
2106 		/* RX flow control - Process pause frame in receive direction
2107 		 */
2108 		if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
2109 			pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
2110 
2111 		/* TX flow control - Send pause packet when buffer is full */
2112 		if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
2113 			pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
2114 	} else {/* PFC support */
2115 		pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
2116 			XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
2117 			XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
2118 			XMAC_PFC_CTRL_HI_REG_TX_PFC_EN |
2119 			XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
2120 		/* Write pause and PFC registers */
2121 		REG_WR(sc, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
2122 		REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
2123 		REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
2124 		pfc1_val &= ~XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
2125 
2126 	}
2127 
2128 	/* Write pause and PFC registers */
2129 	REG_WR(sc, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
2130 	REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
2131 	REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
2132 
2133 
2134 	/* Set MAC address for source TX Pause/PFC frames */
2135 	REG_WR(sc, xmac_base + XMAC_REG_CTRL_SA_LO,
2136 	       ((params->mac_addr[2] << 24) |
2137 		(params->mac_addr[3] << 16) |
2138 		(params->mac_addr[4] << 8) |
2139 		(params->mac_addr[5])));
2140 	REG_WR(sc, xmac_base + XMAC_REG_CTRL_SA_HI,
2141 	       ((params->mac_addr[0] << 8) |
2142 		(params->mac_addr[1])));
2143 
2144 	DELAY(30);
2145 }
2146 
2147 static void elink_emac_get_pfc_stat(struct elink_params *params,
2148 				    uint32_t pfc_frames_sent[2],
2149 				    uint32_t pfc_frames_received[2])
2150 {
2151 	/* Read pfc statistic */
2152 	struct bxe_softc *sc = params->sc;
2153 	uint32_t emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2154 	uint32_t val_xon = 0;
2155 	uint32_t val_xoff = 0;
2156 
2157 	ELINK_DEBUG_P0(sc, "pfc statistic read from EMAC\n");
2158 
2159 	/* PFC received frames */
2160 	val_xoff = REG_RD(sc, emac_base +
2161 				EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
2162 	val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
2163 	val_xon = REG_RD(sc, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
2164 	val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
2165 
2166 	pfc_frames_received[0] = val_xon + val_xoff;
2167 
2168 	/* PFC received sent */
2169 	val_xoff = REG_RD(sc, emac_base +
2170 				EMAC_REG_RX_PFC_STATS_XOFF_SENT);
2171 	val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
2172 	val_xon = REG_RD(sc, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
2173 	val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
2174 
2175 	pfc_frames_sent[0] = val_xon + val_xoff;
2176 }
2177 
2178 /* Read pfc statistic*/
2179 void elink_pfc_statistic(struct elink_params *params, struct elink_vars *vars,
2180 			 uint32_t pfc_frames_sent[2],
2181 			 uint32_t pfc_frames_received[2])
2182 {
2183 	/* Read pfc statistic */
2184 	struct bxe_softc *sc = params->sc;
2185 
2186 	ELINK_DEBUG_P0(sc, "pfc statistic\n");
2187 
2188 	if (!vars->link_up)
2189 		return;
2190 
2191 	if (vars->mac_type == ELINK_MAC_TYPE_EMAC) {
2192 		ELINK_DEBUG_P0(sc, "About to read PFC stats from EMAC\n");
2193 		elink_emac_get_pfc_stat(params, pfc_frames_sent,
2194 					pfc_frames_received);
2195 	}
2196 }
2197 /******************************************************************/
2198 /*			MAC/PBF section				  */
2199 /******************************************************************/
2200 static void elink_set_mdio_clk(struct bxe_softc *sc, uint32_t chip_id,
2201 			       uint32_t emac_base)
2202 {
2203 	uint32_t new_mode, cur_mode;
2204 	uint32_t clc_cnt;
2205 	/* Set clause 45 mode, slow down the MDIO clock to 2.5MHz
2206 	 * (a value of 49==0x31) and make sure that the AUTO poll is off
2207 	 */
2208 	cur_mode = REG_RD(sc, emac_base + EMAC_REG_EMAC_MDIO_MODE);
2209 
2210 	if (USES_WARPCORE(sc))
2211 		clc_cnt = 74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
2212 	else
2213 		clc_cnt = 49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
2214 
2215 	if (((cur_mode & EMAC_MDIO_MODE_CLOCK_CNT) == clc_cnt) &&
2216 	    (cur_mode & (EMAC_MDIO_MODE_CLAUSE_45)))
2217 		return;
2218 
2219 	new_mode = cur_mode &
2220 		~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
2221 	new_mode |= clc_cnt;
2222 	new_mode |= (EMAC_MDIO_MODE_CLAUSE_45);
2223 
2224 	ELINK_DEBUG_P2(sc, "Changing emac_mode from 0x%x to 0x%x\n",
2225 	   cur_mode, new_mode);
2226 	REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_MODE, new_mode);
2227 	DELAY(40);
2228 }
2229 
2230 static uint8_t elink_is_4_port_mode(struct bxe_softc *sc)
2231 {
2232 	uint32_t port4mode_ovwr_val;
2233 	/* Check 4-port override enabled */
2234 	port4mode_ovwr_val = REG_RD(sc, MISC_REG_PORT4MODE_EN_OVWR);
2235 	if (port4mode_ovwr_val & (1<<0)) {
2236 		/* Return 4-port mode override value */
2237 		return ((port4mode_ovwr_val & (1<<1)) == (1<<1));
2238 	}
2239 	/* Return 4-port mode from input pin */
2240 	return (uint8_t)REG_RD(sc, MISC_REG_PORT4MODE_EN);
2241 }
2242 
2243 static void elink_set_mdio_emac_per_phy(struct bxe_softc *sc,
2244 					struct elink_params *params)
2245 {
2246 	uint8_t phy_index;
2247 
2248 	/* Set mdio clock per phy */
2249 	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
2250 	      phy_index++)
2251 		elink_set_mdio_clk(sc, params->chip_id,
2252 				   params->phy[phy_index].mdio_ctrl);
2253 }
2254 
2255 static void elink_emac_init(struct elink_params *params,
2256 			    struct elink_vars *vars)
2257 {
2258 	/* reset and unreset the emac core */
2259 	struct bxe_softc *sc = params->sc;
2260 	uint8_t port = params->port;
2261 	uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2262 	uint32_t val;
2263 	uint16_t timeout;
2264 
2265 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2266 	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
2267 	DELAY(5);
2268 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2269 	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
2270 
2271 	/* init emac - use read-modify-write */
2272 	/* self clear reset */
2273 	val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2274 	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
2275 
2276 	timeout = 200;
2277 	do {
2278 		val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2279 		ELINK_DEBUG_P1(sc, "EMAC reset reg is %u\n", val);
2280 		if (!timeout) {
2281 			ELINK_DEBUG_P0(sc, "EMAC timeout!\n");
2282 			return;
2283 		}
2284 		timeout--;
2285 	} while (val & EMAC_MODE_RESET);
2286 
2287 	elink_set_mdio_emac_per_phy(sc, params);
2288 	/* Set mac address */
2289 	val = ((params->mac_addr[0] << 8) |
2290 		params->mac_addr[1]);
2291 	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MAC_MATCH, val);
2292 
2293 	val = ((params->mac_addr[2] << 24) |
2294 	       (params->mac_addr[3] << 16) |
2295 	       (params->mac_addr[4] << 8) |
2296 		params->mac_addr[5]);
2297 	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MAC_MATCH + 4, val);
2298 }
2299 
2300 static void elink_set_xumac_nig(struct elink_params *params,
2301 				uint16_t tx_pause_en,
2302 				uint8_t enable)
2303 {
2304 	struct bxe_softc *sc = params->sc;
2305 
2306 	REG_WR(sc, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
2307 	       enable);
2308 	REG_WR(sc, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
2309 	       enable);
2310 	REG_WR(sc, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
2311 	       NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
2312 }
2313 
2314 static void elink_set_umac_rxtx(struct elink_params *params, uint8_t en)
2315 {
2316 	uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
2317 	uint32_t val;
2318 	struct bxe_softc *sc = params->sc;
2319 	if (!(REG_RD(sc, MISC_REG_RESET_REG_2) &
2320 		   (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)))
2321 		return;
2322 	val = REG_RD(sc, umac_base + UMAC_REG_COMMAND_CONFIG);
2323 	if (en)
2324 		val |= (UMAC_COMMAND_CONFIG_REG_TX_ENA |
2325 			UMAC_COMMAND_CONFIG_REG_RX_ENA);
2326 	else
2327 		val &= ~(UMAC_COMMAND_CONFIG_REG_TX_ENA |
2328 			 UMAC_COMMAND_CONFIG_REG_RX_ENA);
2329 	/* Disable RX and TX */
2330 	REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2331 }
2332 
2333 static void elink_umac_enable(struct elink_params *params,
2334 			    struct elink_vars *vars, uint8_t lb)
2335 {
2336 	uint32_t val;
2337 	uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
2338 	struct bxe_softc *sc = params->sc;
2339 	/* Reset UMAC */
2340 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2341 	       (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
2342 	DELAY(1000 * 1);
2343 
2344 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2345 	       (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
2346 
2347 	ELINK_DEBUG_P0(sc, "enabling UMAC\n");
2348 
2349 	/* This register opens the gate for the UMAC despite its name */
2350 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
2351 
2352 	val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
2353 		UMAC_COMMAND_CONFIG_REG_PAD_EN |
2354 		UMAC_COMMAND_CONFIG_REG_SW_RESET |
2355 		UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
2356 	switch (vars->line_speed) {
2357 	case ELINK_SPEED_10:
2358 		val |= (0<<2);
2359 		break;
2360 	case ELINK_SPEED_100:
2361 		val |= (1<<2);
2362 		break;
2363 	case ELINK_SPEED_1000:
2364 		val |= (2<<2);
2365 		break;
2366 	case ELINK_SPEED_2500:
2367 		val |= (3<<2);
2368 		break;
2369 	default:
2370 		ELINK_DEBUG_P1(sc, "Invalid speed for UMAC %d\n",
2371 			       vars->line_speed);
2372 		break;
2373 	}
2374 	if (!(vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2375 		val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE;
2376 
2377 	if (!(vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2378 		val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
2379 
2380 	if (vars->duplex == DUPLEX_HALF)
2381 		val |= UMAC_COMMAND_CONFIG_REG_HD_ENA;
2382 
2383 	REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2384 	DELAY(50);
2385 
2386 	/* Configure UMAC for EEE */
2387 	if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
2388 		ELINK_DEBUG_P0(sc, "configured UMAC for EEE\n");
2389 		REG_WR(sc, umac_base + UMAC_REG_UMAC_EEE_CTRL,
2390 		       UMAC_UMAC_EEE_CTRL_REG_EEE_EN);
2391 		REG_WR(sc, umac_base + UMAC_REG_EEE_WAKE_TIMER, 0x11);
2392 	} else {
2393 		REG_WR(sc, umac_base + UMAC_REG_UMAC_EEE_CTRL, 0x0);
2394 	}
2395 
2396 	/* Set MAC address for source TX Pause/PFC frames (under SW reset) */
2397 	REG_WR(sc, umac_base + UMAC_REG_MAC_ADDR0,
2398 	       ((params->mac_addr[2] << 24) |
2399 		(params->mac_addr[3] << 16) |
2400 		(params->mac_addr[4] << 8) |
2401 		(params->mac_addr[5])));
2402 	REG_WR(sc, umac_base + UMAC_REG_MAC_ADDR1,
2403 	       ((params->mac_addr[0] << 8) |
2404 		(params->mac_addr[1])));
2405 
2406 	/* Enable RX and TX */
2407 	val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
2408 	val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
2409 		UMAC_COMMAND_CONFIG_REG_RX_ENA;
2410 	REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2411 	DELAY(50);
2412 
2413 	/* Remove SW Reset */
2414 	val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
2415 
2416 	/* Check loopback mode */
2417 	if (lb)
2418 		val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
2419 	REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2420 
2421 	/* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
2422 	 * length used by the MAC receive logic to check frames.
2423 	 */
2424 	REG_WR(sc, umac_base + UMAC_REG_MAXFR, 0x2710);
2425 	elink_set_xumac_nig(params,
2426 			    ((vars->flow_ctrl & ELINK_FLOW_CTRL_TX) != 0), 1);
2427 	vars->mac_type = ELINK_MAC_TYPE_UMAC;
2428 
2429 }
2430 
2431 /* Define the XMAC mode */
2432 static void elink_xmac_init(struct elink_params *params, uint32_t max_speed)
2433 {
2434 	struct bxe_softc *sc = params->sc;
2435 	uint32_t is_port4mode = elink_is_4_port_mode(sc);
2436 
2437 	/* In 4-port mode, need to set the mode only once, so if XMAC is
2438 	 * already out of reset, it means the mode has already been set,
2439 	 * and it must not* reset the XMAC again, since it controls both
2440 	 * ports of the path
2441 	 */
2442 
2443 	if (((CHIP_NUM(sc) == CHIP_NUM_57840_4_10) ||
2444 	     (CHIP_NUM(sc) == CHIP_NUM_57840_2_20) ||
2445 	     (CHIP_NUM(sc) == CHIP_NUM_57840_OBS)) &&
2446 	    is_port4mode &&
2447 	    (REG_RD(sc, MISC_REG_RESET_REG_2) &
2448 	     MISC_REGISTERS_RESET_REG_2_XMAC)) {
2449 		ELINK_DEBUG_P0(sc,
2450 		   "XMAC already out of reset in 4-port mode\n");
2451 		return;
2452 	}
2453 
2454 	/* Hard reset */
2455 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2456 	       MISC_REGISTERS_RESET_REG_2_XMAC);
2457 	DELAY(1000 * 1);
2458 
2459 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2460 	       MISC_REGISTERS_RESET_REG_2_XMAC);
2461 	if (is_port4mode) {
2462 		ELINK_DEBUG_P0(sc, "Init XMAC to 2 ports x 10G per path\n");
2463 
2464 		/* Set the number of ports on the system side to up to 2 */
2465 		REG_WR(sc, MISC_REG_XMAC_CORE_PORT_MODE, 1);
2466 
2467 		/* Set the number of ports on the Warp Core to 10G */
2468 		REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 3);
2469 	} else {
2470 		/* Set the number of ports on the system side to 1 */
2471 		REG_WR(sc, MISC_REG_XMAC_CORE_PORT_MODE, 0);
2472 		if (max_speed == ELINK_SPEED_10000) {
2473 			ELINK_DEBUG_P0(sc,
2474 			   "Init XMAC to 10G x 1 port per path\n");
2475 			/* Set the number of ports on the Warp Core to 10G */
2476 			REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 3);
2477 		} else {
2478 			ELINK_DEBUG_P0(sc,
2479 			   "Init XMAC to 20G x 2 ports per path\n");
2480 			/* Set the number of ports on the Warp Core to 20G */
2481 			REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 1);
2482 		}
2483 	}
2484 	/* Soft reset */
2485 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2486 	       MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
2487 	DELAY(1000 * 1);
2488 
2489 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2490 	       MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
2491 
2492 }
2493 
2494 static void elink_set_xmac_rxtx(struct elink_params *params, uint8_t en)
2495 {
2496 	uint8_t port = params->port;
2497 	struct bxe_softc *sc = params->sc;
2498 	uint32_t pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
2499 	uint32_t val;
2500 
2501 	if (REG_RD(sc, MISC_REG_RESET_REG_2) &
2502 	    MISC_REGISTERS_RESET_REG_2_XMAC) {
2503 		/* Send an indication to change the state in the NIG back to XON
2504 		 * Clearing this bit enables the next set of this bit to get
2505 		 * rising edge
2506 		 */
2507 		pfc_ctrl = REG_RD(sc, xmac_base + XMAC_REG_PFC_CTRL_HI);
2508 		REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI,
2509 		       (pfc_ctrl & ~(1<<1)));
2510 		REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI,
2511 		       (pfc_ctrl | (1<<1)));
2512 		ELINK_DEBUG_P1(sc, "Disable XMAC on port %x\n", port);
2513 		val = REG_RD(sc, xmac_base + XMAC_REG_CTRL);
2514 		if (en)
2515 			val |= (XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
2516 		else
2517 			val &= ~(XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
2518 		REG_WR(sc, xmac_base + XMAC_REG_CTRL, val);
2519 	}
2520 }
2521 
2522 static elink_status_t elink_xmac_enable(struct elink_params *params,
2523 			     struct elink_vars *vars, uint8_t lb)
2524 {
2525 	uint32_t val, xmac_base;
2526 	struct bxe_softc *sc = params->sc;
2527 	ELINK_DEBUG_P0(sc, "enabling XMAC\n");
2528 
2529 	xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
2530 
2531 	elink_xmac_init(params, vars->line_speed);
2532 
2533 	/* This register determines on which events the MAC will assert
2534 	 * error on the i/f to the NIG along w/ EOP.
2535 	 */
2536 
2537 	/* This register tells the NIG whether to send traffic to UMAC
2538 	 * or XMAC
2539 	 */
2540 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0);
2541 
2542 	/* When XMAC is in XLGMII mode, disable sending idles for fault
2543 	 * detection.
2544 	 */
2545 	if (!(params->phy[ELINK_INT_PHY].flags & ELINK_FLAGS_TX_ERROR_CHECK)) {
2546 		REG_WR(sc, xmac_base + XMAC_REG_RX_LSS_CTRL,
2547 		       (XMAC_RX_LSS_CTRL_REG_LOCAL_FAULT_DISABLE |
2548 			XMAC_RX_LSS_CTRL_REG_REMOTE_FAULT_DISABLE));
2549 		REG_WR(sc, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
2550 		REG_WR(sc, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
2551 		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
2552 		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
2553 	}
2554 	/* Set Max packet size */
2555 	REG_WR(sc, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
2556 
2557 	/* CRC append for Tx packets */
2558 	REG_WR(sc, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
2559 
2560 	/* update PFC */
2561 	elink_update_pfc_xmac(params, vars, 0);
2562 
2563 	if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
2564 		ELINK_DEBUG_P0(sc, "Setting XMAC for EEE\n");
2565 		REG_WR(sc, xmac_base + XMAC_REG_EEE_TIMERS_HI, 0x1380008);
2566 		REG_WR(sc, xmac_base + XMAC_REG_EEE_CTRL, 0x1);
2567 	} else {
2568 		REG_WR(sc, xmac_base + XMAC_REG_EEE_CTRL, 0x0);
2569 	}
2570 
2571 	/* Enable TX and RX */
2572 	val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
2573 
2574 	/* Set MAC in XLGMII mode for dual-mode */
2575 	if ((vars->line_speed == ELINK_SPEED_20000) &&
2576 	    (params->phy[ELINK_INT_PHY].supported &
2577 	     ELINK_SUPPORTED_20000baseKR2_Full))
2578 		val |= XMAC_CTRL_REG_XLGMII_ALIGN_ENB;
2579 
2580 	/* Check loopback mode */
2581 	if (lb)
2582 		val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK;
2583 	REG_WR(sc, xmac_base + XMAC_REG_CTRL, val);
2584 	elink_set_xumac_nig(params,
2585 			    ((vars->flow_ctrl & ELINK_FLOW_CTRL_TX) != 0), 1);
2586 
2587 	vars->mac_type = ELINK_MAC_TYPE_XMAC;
2588 
2589 	return ELINK_STATUS_OK;
2590 }
2591 
2592 static elink_status_t elink_emac_enable(struct elink_params *params,
2593 			     struct elink_vars *vars, uint8_t lb)
2594 {
2595 	struct bxe_softc *sc = params->sc;
2596 	uint8_t port = params->port;
2597 	uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2598 	uint32_t val;
2599 
2600 	ELINK_DEBUG_P0(sc, "enabling EMAC\n");
2601 
2602 	/* Disable BMAC */
2603 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2604 	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2605 
2606 	/* enable emac and not bmac */
2607 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
2608 
2609 #ifdef ELINK_INCLUDE_EMUL
2610 	/* for paladium */
2611 	if (CHIP_REV_IS_EMUL(sc)) {
2612 		/* Use lane 1 (of lanes 0-3) */
2613 		REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
2614 		REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
2615 	}
2616 	/* for fpga */
2617 	else
2618 #endif
2619 #ifdef ELINK_INCLUDE_FPGA
2620 	if (CHIP_REV_IS_FPGA(sc)) {
2621 		/* Use lane 1 (of lanes 0-3) */
2622 		ELINK_DEBUG_P0(sc, "elink_emac_enable: Setting FPGA\n");
2623 
2624 		REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
2625 		REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
2626 	} else
2627 #endif
2628 	/* ASIC */
2629 	if (vars->phy_flags & PHY_XGXS_FLAG) {
2630 		uint32_t ser_lane = ((params->lane_config &
2631 				 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
2632 				PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
2633 
2634 		ELINK_DEBUG_P0(sc, "XGXS\n");
2635 		/* select the master lanes (out of 0-3) */
2636 		REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
2637 		/* select XGXS */
2638 		REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
2639 
2640 	} else { /* SerDes */
2641 		ELINK_DEBUG_P0(sc, "SerDes\n");
2642 		/* select SerDes */
2643 		REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
2644 	}
2645 
2646 	elink_bits_en(sc, emac_base + EMAC_REG_EMAC_RX_MODE,
2647 		      EMAC_RX_MODE_RESET);
2648 	elink_bits_en(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
2649 		      EMAC_TX_MODE_RESET);
2650 
2651 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
2652 	if (CHIP_REV_IS_SLOW(sc)) {
2653 		/* config GMII mode */
2654 		val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2655 		elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
2656 	} else { /* ASIC */
2657 #endif
2658 		/* pause enable/disable */
2659 		elink_bits_dis(sc, emac_base + EMAC_REG_EMAC_RX_MODE,
2660 			       EMAC_RX_MODE_FLOW_EN);
2661 
2662 		elink_bits_dis(sc,  emac_base + EMAC_REG_EMAC_TX_MODE,
2663 			       (EMAC_TX_MODE_EXT_PAUSE_EN |
2664 				EMAC_TX_MODE_FLOW_EN));
2665 		if (!(params->feature_config_flags &
2666 		      ELINK_FEATURE_CONFIG_PFC_ENABLED)) {
2667 			if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
2668 				elink_bits_en(sc, emac_base +
2669 					      EMAC_REG_EMAC_RX_MODE,
2670 					      EMAC_RX_MODE_FLOW_EN);
2671 
2672 			if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
2673 				elink_bits_en(sc, emac_base +
2674 					      EMAC_REG_EMAC_TX_MODE,
2675 					      (EMAC_TX_MODE_EXT_PAUSE_EN |
2676 					       EMAC_TX_MODE_FLOW_EN));
2677 		} else
2678 			elink_bits_en(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
2679 				      EMAC_TX_MODE_FLOW_EN);
2680 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
2681 	}
2682 #endif
2683 
2684 	/* KEEP_VLAN_TAG, promiscuous */
2685 	val = REG_RD(sc, emac_base + EMAC_REG_EMAC_RX_MODE);
2686 	val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
2687 
2688 	/* Setting this bit causes MAC control frames (except for pause
2689 	 * frames) to be passed on for processing. This setting has no
2690 	 * affect on the operation of the pause frames. This bit effects
2691 	 * all packets regardless of RX Parser packet sorting logic.
2692 	 * Turn the PFC off to make sure we are in Xon state before
2693 	 * enabling it.
2694 	 */
2695 	elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_MODE, 0);
2696 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED) {
2697 		ELINK_DEBUG_P0(sc, "PFC is enabled\n");
2698 		/* Enable PFC again */
2699 		elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_MODE,
2700 			EMAC_REG_RX_PFC_MODE_RX_EN |
2701 			EMAC_REG_RX_PFC_MODE_TX_EN |
2702 			EMAC_REG_RX_PFC_MODE_PRIORITIES);
2703 
2704 		elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_PARAM,
2705 			((0x0101 <<
2706 			  EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
2707 			 (0x00ff <<
2708 			  EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
2709 		val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
2710 	}
2711 	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_RX_MODE, val);
2712 
2713 	/* Set Loopback */
2714 	val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2715 	if (lb)
2716 		val |= 0x810;
2717 	else
2718 		val &= ~0x810;
2719 	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE, val);
2720 
2721 	/* Enable emac */
2722 	REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port*4, 1);
2723 
2724 	/* Enable emac for jumbo packets */
2725 	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_RX_MTU_SIZE,
2726 		(EMAC_RX_MTU_SIZE_JUMBO_ENA |
2727 		 (ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD)));
2728 
2729 	/* Strip CRC */
2730 	REG_WR(sc, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
2731 
2732 	/* Disable the NIG in/out to the bmac */
2733 	REG_WR(sc, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
2734 	REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
2735 	REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
2736 
2737 	/* Enable the NIG in/out to the emac */
2738 	REG_WR(sc, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
2739 	val = 0;
2740 	if ((params->feature_config_flags &
2741 	      ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
2742 	    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2743 		val = 1;
2744 
2745 	REG_WR(sc, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
2746 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
2747 
2748 #ifdef ELINK_INCLUDE_EMUL
2749 	if (CHIP_REV_IS_EMUL(sc)) {
2750 		/* Take the BigMac out of reset */
2751 		REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2752 		       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2753 
2754 		/* Enable access for bmac registers */
2755 		REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
2756 	} else
2757 #endif
2758 	REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
2759 
2760 	vars->mac_type = ELINK_MAC_TYPE_EMAC;
2761 	return ELINK_STATUS_OK;
2762 }
2763 
2764 static void elink_update_pfc_bmac1(struct elink_params *params,
2765 				   struct elink_vars *vars)
2766 {
2767 	uint32_t wb_data[2];
2768 	struct bxe_softc *sc = params->sc;
2769 	uint32_t bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
2770 		NIG_REG_INGRESS_BMAC0_MEM;
2771 
2772 	uint32_t val = 0x14;
2773 	if ((!(params->feature_config_flags &
2774 	      ELINK_FEATURE_CONFIG_PFC_ENABLED)) &&
2775 		(vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2776 		/* Enable BigMAC to react on received Pause packets */
2777 		val |= (1<<5);
2778 	wb_data[0] = val;
2779 	wb_data[1] = 0;
2780 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
2781 
2782 	/* TX control */
2783 	val = 0xc0;
2784 	if (!(params->feature_config_flags &
2785 	      ELINK_FEATURE_CONFIG_PFC_ENABLED) &&
2786 		(vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2787 		val |= 0x800000;
2788 	wb_data[0] = val;
2789 	wb_data[1] = 0;
2790 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
2791 }
2792 
2793 static void elink_update_pfc_bmac2(struct elink_params *params,
2794 				   struct elink_vars *vars,
2795 				   uint8_t is_lb)
2796 {
2797 	/* Set rx control: Strip CRC and enable BigMAC to relay
2798 	 * control packets to the system as well
2799 	 */
2800 	uint32_t wb_data[2];
2801 	struct bxe_softc *sc = params->sc;
2802 	uint32_t bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
2803 		NIG_REG_INGRESS_BMAC0_MEM;
2804 	uint32_t val = 0x14;
2805 
2806 	if ((!(params->feature_config_flags &
2807 	      ELINK_FEATURE_CONFIG_PFC_ENABLED)) &&
2808 		(vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2809 		/* Enable BigMAC to react on received Pause packets */
2810 		val |= (1<<5);
2811 	wb_data[0] = val;
2812 	wb_data[1] = 0;
2813 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
2814 	DELAY(30);
2815 
2816 	/* Tx control */
2817 	val = 0xc0;
2818 	if (!(params->feature_config_flags &
2819 				ELINK_FEATURE_CONFIG_PFC_ENABLED) &&
2820 	    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2821 		val |= 0x800000;
2822 	wb_data[0] = val;
2823 	wb_data[1] = 0;
2824 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
2825 
2826 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED) {
2827 		ELINK_DEBUG_P0(sc, "PFC is enabled\n");
2828 		/* Enable PFC RX & TX & STATS and set 8 COS  */
2829 		wb_data[0] = 0x0;
2830 		wb_data[0] |= (1<<0);  /* RX */
2831 		wb_data[0] |= (1<<1);  /* TX */
2832 		wb_data[0] |= (1<<2);  /* Force initial Xon */
2833 		wb_data[0] |= (1<<3);  /* 8 cos */
2834 		wb_data[0] |= (1<<5);  /* STATS */
2835 		wb_data[1] = 0;
2836 		REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
2837 			    wb_data, 2);
2838 		/* Clear the force Xon */
2839 		wb_data[0] &= ~(1<<2);
2840 	} else {
2841 		ELINK_DEBUG_P0(sc, "PFC is disabled\n");
2842 		/* Disable PFC RX & TX & STATS and set 8 COS */
2843 		wb_data[0] = 0x8;
2844 		wb_data[1] = 0;
2845 	}
2846 
2847 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
2848 
2849 	/* Set Time (based unit is 512 bit time) between automatic
2850 	 * re-sending of PP packets amd enable automatic re-send of
2851 	 * Per-Priroity Packet as long as pp_gen is asserted and
2852 	 * pp_disable is low.
2853 	 */
2854 	val = 0x8000;
2855 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
2856 		val |= (1<<16); /* enable automatic re-send */
2857 
2858 	wb_data[0] = val;
2859 	wb_data[1] = 0;
2860 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
2861 		    wb_data, 2);
2862 
2863 	/* mac control */
2864 	val = 0x3; /* Enable RX and TX */
2865 	if (is_lb) {
2866 		val |= 0x4; /* Local loopback */
2867 		ELINK_DEBUG_P0(sc, "enable bmac loopback\n");
2868 	}
2869 	/* When PFC enabled, Pass pause frames towards the NIG. */
2870 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
2871 		val |= ((1<<6)|(1<<5));
2872 
2873 	wb_data[0] = val;
2874 	wb_data[1] = 0;
2875 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2876 }
2877 
2878 /******************************************************************************
2879 * Description:
2880 *  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2881 *  not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2882 ******************************************************************************/
2883 static elink_status_t elink_pfc_nig_rx_priority_mask(struct bxe_softc *sc,
2884 					   uint8_t cos_entry,
2885 					   uint32_t priority_mask, uint8_t port)
2886 {
2887 	uint32_t nig_reg_rx_priority_mask_add = 0;
2888 
2889 	switch (cos_entry) {
2890 	case 0:
2891 	     nig_reg_rx_priority_mask_add = (port) ?
2892 		 NIG_REG_P1_RX_COS0_PRIORITY_MASK :
2893 		 NIG_REG_P0_RX_COS0_PRIORITY_MASK;
2894 	     break;
2895 	case 1:
2896 	    nig_reg_rx_priority_mask_add = (port) ?
2897 		NIG_REG_P1_RX_COS1_PRIORITY_MASK :
2898 		NIG_REG_P0_RX_COS1_PRIORITY_MASK;
2899 	    break;
2900 	case 2:
2901 	    nig_reg_rx_priority_mask_add = (port) ?
2902 		NIG_REG_P1_RX_COS2_PRIORITY_MASK :
2903 		NIG_REG_P0_RX_COS2_PRIORITY_MASK;
2904 	    break;
2905 	case 3:
2906 	    if (port)
2907 		return ELINK_STATUS_ERROR;
2908 	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
2909 	    break;
2910 	case 4:
2911 	    if (port)
2912 		return ELINK_STATUS_ERROR;
2913 	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
2914 	    break;
2915 	case 5:
2916 	    if (port)
2917 		return ELINK_STATUS_ERROR;
2918 	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
2919 	    break;
2920 	}
2921 
2922 	REG_WR(sc, nig_reg_rx_priority_mask_add, priority_mask);
2923 
2924 	return ELINK_STATUS_OK;
2925 }
2926 static void elink_update_mng(struct elink_params *params, uint32_t link_status)
2927 {
2928 	struct bxe_softc *sc = params->sc;
2929 
2930 	REG_WR(sc, params->shmem_base +
2931 	       offsetof(struct shmem_region,
2932 			port_mb[params->port].link_status), link_status);
2933 }
2934 
2935 static void elink_update_pfc_nig(struct elink_params *params,
2936 		struct elink_vars *vars,
2937 		struct elink_nig_brb_pfc_port_params *nig_params)
2938 {
2939 	uint32_t xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
2940 	uint32_t llfc_enable = 0, xcm_out_en = 0, hwpfc_enable = 0;
2941 	uint32_t pkt_priority_to_cos = 0;
2942 	struct bxe_softc *sc = params->sc;
2943 	uint8_t port = params->port;
2944 
2945 	int set_pfc = params->feature_config_flags &
2946 		ELINK_FEATURE_CONFIG_PFC_ENABLED;
2947 	ELINK_DEBUG_P0(sc, "updating pfc nig parameters\n");
2948 
2949 	/* When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2950 	 * MAC control frames (that are not pause packets)
2951 	 * will be forwarded to the XCM.
2952 	 */
2953 	xcm_mask = REG_RD(sc, port ? NIG_REG_LLH1_XCM_MASK :
2954 			  NIG_REG_LLH0_XCM_MASK);
2955 	/* NIG params will override non PFC params, since it's possible to
2956 	 * do transition from PFC to SAFC
2957 	 */
2958 	if (set_pfc) {
2959 		pause_enable = 0;
2960 		llfc_out_en = 0;
2961 		llfc_enable = 0;
2962 		if (CHIP_IS_E3(sc))
2963 			ppp_enable = 0;
2964 		else
2965 			ppp_enable = 1;
2966 		xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2967 				     NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2968 		xcm_out_en = 0;
2969 		hwpfc_enable = 1;
2970 	} else  {
2971 		if (nig_params) {
2972 			llfc_out_en = nig_params->llfc_out_en;
2973 			llfc_enable = nig_params->llfc_enable;
2974 			pause_enable = nig_params->pause_enable;
2975 		} else  /* Default non PFC mode - PAUSE */
2976 			pause_enable = 1;
2977 
2978 		xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2979 			NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2980 		xcm_out_en = 1;
2981 	}
2982 
2983 	if (CHIP_IS_E3(sc))
2984 		REG_WR(sc, port ? NIG_REG_BRB1_PAUSE_IN_EN :
2985 		       NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
2986 	REG_WR(sc, port ? NIG_REG_LLFC_OUT_EN_1 :
2987 	       NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
2988 	REG_WR(sc, port ? NIG_REG_LLFC_ENABLE_1 :
2989 	       NIG_REG_LLFC_ENABLE_0, llfc_enable);
2990 	REG_WR(sc, port ? NIG_REG_PAUSE_ENABLE_1 :
2991 	       NIG_REG_PAUSE_ENABLE_0, pause_enable);
2992 
2993 	REG_WR(sc, port ? NIG_REG_PPP_ENABLE_1 :
2994 	       NIG_REG_PPP_ENABLE_0, ppp_enable);
2995 
2996 	REG_WR(sc, port ? NIG_REG_LLH1_XCM_MASK :
2997 	       NIG_REG_LLH0_XCM_MASK, xcm_mask);
2998 
2999 	REG_WR(sc, port ? NIG_REG_LLFC_EGRESS_SRC_ENABLE_1 :
3000 	       NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
3001 
3002 	/* Output enable for RX_XCM # IF */
3003 	REG_WR(sc, port ? NIG_REG_XCM1_OUT_EN :
3004 	       NIG_REG_XCM0_OUT_EN, xcm_out_en);
3005 
3006 	/* HW PFC TX enable */
3007 	REG_WR(sc, port ? NIG_REG_P1_HWPFC_ENABLE :
3008 	       NIG_REG_P0_HWPFC_ENABLE, hwpfc_enable);
3009 
3010 	if (nig_params) {
3011 		uint8_t i = 0;
3012 		pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
3013 
3014 		for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
3015 			elink_pfc_nig_rx_priority_mask(sc, i,
3016 		nig_params->rx_cos_priority_mask[i], port);
3017 
3018 		REG_WR(sc, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
3019 		       NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
3020 		       nig_params->llfc_high_priority_classes);
3021 
3022 		REG_WR(sc, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
3023 		       NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
3024 		       nig_params->llfc_low_priority_classes);
3025 	}
3026 	REG_WR(sc, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
3027 	       NIG_REG_P0_PKT_PRIORITY_TO_COS,
3028 	       pkt_priority_to_cos);
3029 }
3030 
3031 elink_status_t elink_update_pfc(struct elink_params *params,
3032 		      struct elink_vars *vars,
3033 		      struct elink_nig_brb_pfc_port_params *pfc_params)
3034 {
3035 	/* The PFC and pause are orthogonal to one another, meaning when
3036 	 * PFC is enabled, the pause are disabled, and when PFC is
3037 	 * disabled, pause are set according to the pause result.
3038 	 */
3039 	uint32_t val;
3040 	struct bxe_softc *sc = params->sc;
3041 	uint8_t bmac_loopback = (params->loopback_mode == ELINK_LOOPBACK_BMAC);
3042 
3043 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
3044 		vars->link_status |= LINK_STATUS_PFC_ENABLED;
3045 	else
3046 		vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
3047 
3048 	elink_update_mng(params, vars->link_status);
3049 
3050 	/* Update NIG params */
3051 	elink_update_pfc_nig(params, vars, pfc_params);
3052 
3053 	if (!vars->link_up)
3054 		return ELINK_STATUS_OK;
3055 
3056 	ELINK_DEBUG_P0(sc, "About to update PFC in BMAC\n");
3057 
3058 	if (CHIP_IS_E3(sc)) {
3059 		if (vars->mac_type == ELINK_MAC_TYPE_XMAC)
3060 			elink_update_pfc_xmac(params, vars, 0);
3061 	} else {
3062 		val = REG_RD(sc, MISC_REG_RESET_REG_2);
3063 		if ((val &
3064 		     (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
3065 		    == 0) {
3066 			ELINK_DEBUG_P0(sc, "About to update PFC in EMAC\n");
3067 			elink_emac_enable(params, vars, 0);
3068 			return ELINK_STATUS_OK;
3069 		}
3070 		if (CHIP_IS_E2(sc))
3071 			elink_update_pfc_bmac2(params, vars, bmac_loopback);
3072 		else
3073 			elink_update_pfc_bmac1(params, vars);
3074 
3075 		val = 0;
3076 		if ((params->feature_config_flags &
3077 		     ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
3078 		    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
3079 			val = 1;
3080 		REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
3081 	}
3082 	return ELINK_STATUS_OK;
3083 }
3084 
3085 static elink_status_t elink_bmac1_enable(struct elink_params *params,
3086 			      struct elink_vars *vars,
3087 			      uint8_t is_lb)
3088 {
3089 	struct bxe_softc *sc = params->sc;
3090 	uint8_t port = params->port;
3091 	uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
3092 			       NIG_REG_INGRESS_BMAC0_MEM;
3093 	uint32_t wb_data[2];
3094 	uint32_t val;
3095 
3096 	ELINK_DEBUG_P0(sc, "Enabling BigMAC1\n");
3097 
3098 	/* XGXS control */
3099 	wb_data[0] = 0x3c;
3100 	wb_data[1] = 0;
3101 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
3102 		    wb_data, 2);
3103 
3104 	/* TX MAC SA */
3105 	wb_data[0] = ((params->mac_addr[2] << 24) |
3106 		       (params->mac_addr[3] << 16) |
3107 		       (params->mac_addr[4] << 8) |
3108 			params->mac_addr[5]);
3109 	wb_data[1] = ((params->mac_addr[0] << 8) |
3110 			params->mac_addr[1]);
3111 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
3112 
3113 	/* MAC control */
3114 	val = 0x3;
3115 	if (is_lb) {
3116 		val |= 0x4;
3117 		ELINK_DEBUG_P0(sc,  "enable bmac loopback\n");
3118 	}
3119 	wb_data[0] = val;
3120 	wb_data[1] = 0;
3121 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
3122 
3123 	/* Set rx mtu */
3124 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3125 	wb_data[1] = 0;
3126 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
3127 
3128 	elink_update_pfc_bmac1(params, vars);
3129 
3130 	/* Set tx mtu */
3131 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3132 	wb_data[1] = 0;
3133 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
3134 
3135 	/* Set cnt max size */
3136 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3137 	wb_data[1] = 0;
3138 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
3139 
3140 	/* Configure SAFC */
3141 	wb_data[0] = 0x1000200;
3142 	wb_data[1] = 0;
3143 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
3144 		    wb_data, 2);
3145 #ifdef ELINK_INCLUDE_EMUL
3146 	/* Fix for emulation */
3147 	if (CHIP_REV_IS_EMUL(sc)) {
3148 		wb_data[0] = 0xf000;
3149 		wb_data[1] = 0;
3150 		REG_WR_DMAE(sc,	bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
3151 			    wb_data, 2);
3152 	}
3153 #endif
3154 
3155 	return ELINK_STATUS_OK;
3156 }
3157 
3158 static elink_status_t elink_bmac2_enable(struct elink_params *params,
3159 			      struct elink_vars *vars,
3160 			      uint8_t is_lb)
3161 {
3162 	struct bxe_softc *sc = params->sc;
3163 	uint8_t port = params->port;
3164 	uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
3165 			       NIG_REG_INGRESS_BMAC0_MEM;
3166 	uint32_t wb_data[2];
3167 
3168 	ELINK_DEBUG_P0(sc, "Enabling BigMAC2\n");
3169 
3170 	wb_data[0] = 0;
3171 	wb_data[1] = 0;
3172 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
3173 	DELAY(30);
3174 
3175 	/* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
3176 	wb_data[0] = 0x3c;
3177 	wb_data[1] = 0;
3178 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
3179 		    wb_data, 2);
3180 
3181 	DELAY(30);
3182 
3183 	/* TX MAC SA */
3184 	wb_data[0] = ((params->mac_addr[2] << 24) |
3185 		       (params->mac_addr[3] << 16) |
3186 		       (params->mac_addr[4] << 8) |
3187 			params->mac_addr[5]);
3188 	wb_data[1] = ((params->mac_addr[0] << 8) |
3189 			params->mac_addr[1]);
3190 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
3191 		    wb_data, 2);
3192 
3193 	DELAY(30);
3194 
3195 	/* Configure SAFC */
3196 	wb_data[0] = 0x1000200;
3197 	wb_data[1] = 0;
3198 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
3199 		    wb_data, 2);
3200 	DELAY(30);
3201 
3202 	/* Set RX MTU */
3203 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3204 	wb_data[1] = 0;
3205 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
3206 	DELAY(30);
3207 
3208 	/* Set TX MTU */
3209 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3210 	wb_data[1] = 0;
3211 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
3212 	DELAY(30);
3213 	/* Set cnt max size */
3214 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD - 2;
3215 	wb_data[1] = 0;
3216 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
3217 	DELAY(30);
3218 	elink_update_pfc_bmac2(params, vars, is_lb);
3219 
3220 	return ELINK_STATUS_OK;
3221 }
3222 
3223 static elink_status_t elink_bmac_enable(struct elink_params *params,
3224 			     struct elink_vars *vars,
3225 			     uint8_t is_lb, uint8_t reset_bmac)
3226 {
3227 	elink_status_t rc = ELINK_STATUS_OK;
3228 	uint8_t port = params->port;
3229 	struct bxe_softc *sc = params->sc;
3230 	uint32_t val;
3231 	/* Reset and unreset the BigMac */
3232 	if (reset_bmac) {
3233 		REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
3234 		       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
3235 		DELAY(1000 * 1);
3236 	}
3237 
3238 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
3239 	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
3240 
3241 	/* Enable access for bmac registers */
3242 	REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
3243 
3244 	/* Enable BMAC according to BMAC type*/
3245 	if (CHIP_IS_E2(sc))
3246 		rc = elink_bmac2_enable(params, vars, is_lb);
3247 	else
3248 		rc = elink_bmac1_enable(params, vars, is_lb);
3249 	REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
3250 	REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
3251 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
3252 	val = 0;
3253 	if ((params->feature_config_flags &
3254 	      ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
3255 	    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
3256 		val = 1;
3257 	REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
3258 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
3259 	REG_WR(sc, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
3260 	REG_WR(sc, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
3261 	REG_WR(sc, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
3262 	REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
3263 
3264 	vars->mac_type = ELINK_MAC_TYPE_BMAC;
3265 	return rc;
3266 }
3267 
3268 static void elink_set_bmac_rx(struct bxe_softc *sc, uint32_t chip_id, uint8_t port, uint8_t en)
3269 {
3270 	uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
3271 			NIG_REG_INGRESS_BMAC0_MEM;
3272 	uint32_t wb_data[2];
3273 	uint32_t nig_bmac_enable = REG_RD(sc, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
3274 
3275 	if (CHIP_IS_E2(sc))
3276 		bmac_addr += BIGMAC2_REGISTER_BMAC_CONTROL;
3277 	else
3278 		bmac_addr += BIGMAC_REGISTER_BMAC_CONTROL;
3279 	/* Only if the bmac is out of reset */
3280 	if (REG_RD(sc, MISC_REG_RESET_REG_2) &
3281 			(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
3282 	    nig_bmac_enable) {
3283 		/* Clear Rx Enable bit in BMAC_CONTROL register */
3284 		REG_RD_DMAE(sc, bmac_addr, wb_data, 2);
3285 		if (en)
3286 			wb_data[0] |= ELINK_BMAC_CONTROL_RX_ENABLE;
3287 		else
3288 			wb_data[0] &= ~ELINK_BMAC_CONTROL_RX_ENABLE;
3289 		REG_WR_DMAE(sc, bmac_addr, wb_data, 2);
3290 		DELAY(1000 * 1);
3291 	}
3292 }
3293 
3294 static elink_status_t elink_pbf_update(struct elink_params *params, uint32_t flow_ctrl,
3295 			    uint32_t line_speed)
3296 {
3297 	struct bxe_softc *sc = params->sc;
3298 	uint8_t port = params->port;
3299 	uint32_t init_crd, crd;
3300 	uint32_t count = 1000;
3301 
3302 	/* Disable port */
3303 	REG_WR(sc, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
3304 
3305 	/* Wait for init credit */
3306 	init_crd = REG_RD(sc, PBF_REG_P0_INIT_CRD + port*4);
3307 	crd = REG_RD(sc, PBF_REG_P0_CREDIT + port*8);
3308 	ELINK_DEBUG_P2(sc, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
3309 
3310 	while ((init_crd != crd) && count) {
3311 		DELAY(1000 * 5);
3312 		crd = REG_RD(sc, PBF_REG_P0_CREDIT + port*8);
3313 		count--;
3314 	}
3315 	crd = REG_RD(sc, PBF_REG_P0_CREDIT + port*8);
3316 	if (init_crd != crd) {
3317 		ELINK_DEBUG_P2(sc, "BUG! init_crd 0x%x != crd 0x%x\n",
3318 			  init_crd, crd);
3319 		return ELINK_STATUS_ERROR;
3320 	}
3321 
3322 	if (flow_ctrl & ELINK_FLOW_CTRL_RX ||
3323 	    line_speed == ELINK_SPEED_10 ||
3324 	    line_speed == ELINK_SPEED_100 ||
3325 	    line_speed == ELINK_SPEED_1000 ||
3326 	    line_speed == ELINK_SPEED_2500) {
3327 		REG_WR(sc, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
3328 		/* Update threshold */
3329 		REG_WR(sc, PBF_REG_P0_ARB_THRSH + port*4, 0);
3330 		/* Update init credit */
3331 		init_crd = 778;		/* (800-18-4) */
3332 
3333 	} else {
3334 		uint32_t thresh = (ELINK_ETH_MAX_JUMBO_PACKET_SIZE +
3335 			      ELINK_ETH_OVREHEAD)/16;
3336 		REG_WR(sc, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
3337 		/* Update threshold */
3338 		REG_WR(sc, PBF_REG_P0_ARB_THRSH + port*4, thresh);
3339 		/* Update init credit */
3340 		switch (line_speed) {
3341 		case ELINK_SPEED_10000:
3342 			init_crd = thresh + 553 - 22;
3343 			break;
3344 		default:
3345 			ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x\n",
3346 				  line_speed);
3347 			return ELINK_STATUS_ERROR;
3348 		}
3349 	}
3350 	REG_WR(sc, PBF_REG_P0_INIT_CRD + port*4, init_crd);
3351 	ELINK_DEBUG_P2(sc, "PBF updated to speed %d credit %d\n",
3352 		 line_speed, init_crd);
3353 
3354 	/* Probe the credit changes */
3355 	REG_WR(sc, PBF_REG_INIT_P0 + port*4, 0x1);
3356 	DELAY(1000 * 5);
3357 	REG_WR(sc, PBF_REG_INIT_P0 + port*4, 0x0);
3358 
3359 	/* Enable port */
3360 	REG_WR(sc, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
3361 	return ELINK_STATUS_OK;
3362 }
3363 
3364 /**
3365  * elink_get_emac_base - retrive emac base address
3366  *
3367  * @bp:			driver handle
3368  * @mdc_mdio_access:	access type
3369  * @port:		port id
3370  *
3371  * This function selects the MDC/MDIO access (through emac0 or
3372  * emac1) depend on the mdc_mdio_access, port, port swapped. Each
3373  * phy has a default access mode, which could also be overridden
3374  * by nvram configuration. This parameter, whether this is the
3375  * default phy configuration, or the nvram overrun
3376  * configuration, is passed here as mdc_mdio_access and selects
3377  * the emac_base for the CL45 read/writes operations
3378  */
3379 static uint32_t elink_get_emac_base(struct bxe_softc *sc,
3380 			       uint32_t mdc_mdio_access, uint8_t port)
3381 {
3382 	uint32_t emac_base = 0;
3383 	switch (mdc_mdio_access) {
3384 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
3385 		break;
3386 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
3387 		if (REG_RD(sc, NIG_REG_PORT_SWAP))
3388 			emac_base = GRCBASE_EMAC1;
3389 		else
3390 			emac_base = GRCBASE_EMAC0;
3391 		break;
3392 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
3393 		if (REG_RD(sc, NIG_REG_PORT_SWAP))
3394 			emac_base = GRCBASE_EMAC0;
3395 		else
3396 			emac_base = GRCBASE_EMAC1;
3397 		break;
3398 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
3399 		emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3400 		break;
3401 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
3402 		emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
3403 		break;
3404 	default:
3405 		break;
3406 	}
3407 	return emac_base;
3408 
3409 }
3410 
3411 /******************************************************************/
3412 /*			CL22 access functions			  */
3413 /******************************************************************/
3414 static elink_status_t elink_cl22_write(struct bxe_softc *sc,
3415 				       struct elink_phy *phy,
3416 				       uint16_t reg, uint16_t val)
3417 {
3418 	uint32_t tmp, mode;
3419 	uint8_t i;
3420 	elink_status_t rc = ELINK_STATUS_OK;
3421 	/* Switch to CL22 */
3422 	mode = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
3423 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
3424 	       mode & ~EMAC_MDIO_MODE_CLAUSE_45);
3425 
3426 	/* Address */
3427 	tmp = ((phy->addr << 21) | (reg << 16) | val |
3428 	       EMAC_MDIO_COMM_COMMAND_WRITE_22 |
3429 	       EMAC_MDIO_COMM_START_BUSY);
3430 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3431 
3432 	for (i = 0; i < 50; i++) {
3433 		DELAY(10);
3434 
3435 		tmp = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3436 		if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3437 			DELAY(5);
3438 			break;
3439 		}
3440 	}
3441 	if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3442 		ELINK_DEBUG_P0(sc, "write phy register failed\n");
3443 		rc = ELINK_STATUS_TIMEOUT;
3444 	}
3445 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
3446 	return rc;
3447 }
3448 
3449 static elink_status_t elink_cl22_read(struct bxe_softc *sc,
3450 				      struct elink_phy *phy,
3451 				      uint16_t reg, uint16_t *ret_val)
3452 {
3453 	uint32_t val, mode;
3454 	uint16_t i;
3455 	elink_status_t rc = ELINK_STATUS_OK;
3456 
3457 	/* Switch to CL22 */
3458 	mode = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
3459 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
3460 	       mode & ~EMAC_MDIO_MODE_CLAUSE_45);
3461 
3462 	/* Address */
3463 	val = ((phy->addr << 21) | (reg << 16) |
3464 	       EMAC_MDIO_COMM_COMMAND_READ_22 |
3465 	       EMAC_MDIO_COMM_START_BUSY);
3466 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3467 
3468 	for (i = 0; i < 50; i++) {
3469 		DELAY(10);
3470 
3471 		val = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3472 		if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3473 			*ret_val = (uint16_t)(val & EMAC_MDIO_COMM_DATA);
3474 			DELAY(5);
3475 			break;
3476 		}
3477 	}
3478 	if (val & EMAC_MDIO_COMM_START_BUSY) {
3479 		ELINK_DEBUG_P0(sc, "read phy register failed\n");
3480 
3481 		*ret_val = 0;
3482 		rc = ELINK_STATUS_TIMEOUT;
3483 	}
3484 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
3485 	return rc;
3486 }
3487 
3488 /******************************************************************/
3489 /*			CL45 access functions			  */
3490 /******************************************************************/
3491 static elink_status_t elink_cl45_read(struct bxe_softc *sc, struct elink_phy *phy,
3492 			   uint8_t devad, uint16_t reg, uint16_t *ret_val)
3493 {
3494 	uint32_t val;
3495 	uint16_t i;
3496 	elink_status_t rc = ELINK_STATUS_OK;
3497 	uint32_t chip_id;
3498 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_G) {
3499 		chip_id = (REG_RD(sc, MISC_REG_CHIP_NUM) << 16) |
3500 			  ((REG_RD(sc, MISC_REG_CHIP_REV) & 0xf) << 12);
3501 		elink_set_mdio_clk(sc, chip_id, phy->mdio_ctrl);
3502 	}
3503 
3504 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3505 		elink_bits_en(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3506 			      EMAC_MDIO_STATUS_10MB);
3507 	/* Address */
3508 	val = ((phy->addr << 21) | (devad << 16) | reg |
3509 	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
3510 	       EMAC_MDIO_COMM_START_BUSY);
3511 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3512 
3513 	for (i = 0; i < 50; i++) {
3514 		DELAY(10);
3515 
3516 		val = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3517 		if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3518 			DELAY(5);
3519 			break;
3520 		}
3521 	}
3522 	if (val & EMAC_MDIO_COMM_START_BUSY) {
3523 		ELINK_DEBUG_P0(sc, "read phy register failed\n");
3524 		elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT); // "MDC/MDIO access timeout\n"
3525 
3526 		*ret_val = 0;
3527 		rc = ELINK_STATUS_TIMEOUT;
3528 	} else {
3529 		/* Data */
3530 		val = ((phy->addr << 21) | (devad << 16) |
3531 		       EMAC_MDIO_COMM_COMMAND_READ_45 |
3532 		       EMAC_MDIO_COMM_START_BUSY);
3533 		REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3534 
3535 		for (i = 0; i < 50; i++) {
3536 			DELAY(10);
3537 
3538 			val = REG_RD(sc, phy->mdio_ctrl +
3539 				     EMAC_REG_EMAC_MDIO_COMM);
3540 			if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3541 				*ret_val = (uint16_t)(val & EMAC_MDIO_COMM_DATA);
3542 				break;
3543 			}
3544 		}
3545 		if (val & EMAC_MDIO_COMM_START_BUSY) {
3546 			ELINK_DEBUG_P0(sc, "read phy register failed\n");
3547 			elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT); // "MDC/MDIO access timeout\n"
3548 
3549 			*ret_val = 0;
3550 			rc = ELINK_STATUS_TIMEOUT;
3551 		}
3552 	}
3553 	/* Work around for E3 A0 */
3554 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA) {
3555 		phy->flags ^= ELINK_FLAGS_DUMMY_READ;
3556 		if (phy->flags & ELINK_FLAGS_DUMMY_READ) {
3557 			uint16_t temp_val;
3558 			elink_cl45_read(sc, phy, devad, 0xf, &temp_val);
3559 		}
3560 	}
3561 
3562 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3563 		elink_bits_dis(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3564 			       EMAC_MDIO_STATUS_10MB);
3565 	return rc;
3566 }
3567 
3568 static elink_status_t elink_cl45_write(struct bxe_softc *sc, struct elink_phy *phy,
3569 			    uint8_t devad, uint16_t reg, uint16_t val)
3570 {
3571 	uint32_t tmp;
3572 	uint8_t i;
3573 	elink_status_t rc = ELINK_STATUS_OK;
3574 	uint32_t chip_id;
3575 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_G) {
3576 		chip_id = (REG_RD(sc, MISC_REG_CHIP_NUM) << 16) |
3577 			  ((REG_RD(sc, MISC_REG_CHIP_REV) & 0xf) << 12);
3578 		elink_set_mdio_clk(sc, chip_id, phy->mdio_ctrl);
3579 	}
3580 
3581 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3582 		elink_bits_en(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3583 			      EMAC_MDIO_STATUS_10MB);
3584 
3585 	/* Address */
3586 	tmp = ((phy->addr << 21) | (devad << 16) | reg |
3587 	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
3588 	       EMAC_MDIO_COMM_START_BUSY);
3589 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3590 
3591 	for (i = 0; i < 50; i++) {
3592 		DELAY(10);
3593 
3594 		tmp = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3595 		if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3596 			DELAY(5);
3597 			break;
3598 		}
3599 	}
3600 	if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3601 		ELINK_DEBUG_P0(sc, "write phy register failed\n");
3602 		elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT); // "MDC/MDIO access timeout\n"
3603 
3604 		rc = ELINK_STATUS_TIMEOUT;
3605 	} else {
3606 		/* Data */
3607 		tmp = ((phy->addr << 21) | (devad << 16) | val |
3608 		       EMAC_MDIO_COMM_COMMAND_WRITE_45 |
3609 		       EMAC_MDIO_COMM_START_BUSY);
3610 		REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3611 
3612 		for (i = 0; i < 50; i++) {
3613 			DELAY(10);
3614 
3615 			tmp = REG_RD(sc, phy->mdio_ctrl +
3616 				     EMAC_REG_EMAC_MDIO_COMM);
3617 			if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3618 				DELAY(5);
3619 				break;
3620 			}
3621 		}
3622 		if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3623 			ELINK_DEBUG_P0(sc, "write phy register failed\n");
3624 			elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT); // "MDC/MDIO access timeout\n"
3625 
3626 			rc = ELINK_STATUS_TIMEOUT;
3627 		}
3628 	}
3629 	/* Work around for E3 A0 */
3630 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA) {
3631 		phy->flags ^= ELINK_FLAGS_DUMMY_READ;
3632 		if (phy->flags & ELINK_FLAGS_DUMMY_READ) {
3633 			uint16_t temp_val;
3634 			elink_cl45_read(sc, phy, devad, 0xf, &temp_val);
3635 		}
3636 	}
3637 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3638 		elink_bits_dis(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3639 			       EMAC_MDIO_STATUS_10MB);
3640 	return rc;
3641 }
3642 
3643 /******************************************************************/
3644 /*			EEE section				   */
3645 /******************************************************************/
3646 static uint8_t elink_eee_has_cap(struct elink_params *params)
3647 {
3648 	struct bxe_softc *sc = params->sc;
3649 
3650 	if (REG_RD(sc, params->shmem2_base) <=
3651 		   offsetof(struct shmem2_region, eee_status[params->port]))
3652 		return 0;
3653 
3654 	return 1;
3655 }
3656 
3657 static elink_status_t elink_eee_nvram_to_time(uint32_t nvram_mode, uint32_t *idle_timer)
3658 {
3659 	switch (nvram_mode) {
3660 	case PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED:
3661 		*idle_timer = ELINK_EEE_MODE_NVRAM_BALANCED_TIME;
3662 		break;
3663 	case PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE:
3664 		*idle_timer = ELINK_EEE_MODE_NVRAM_AGGRESSIVE_TIME;
3665 		break;
3666 	case PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY:
3667 		*idle_timer = ELINK_EEE_MODE_NVRAM_LATENCY_TIME;
3668 		break;
3669 	default:
3670 		*idle_timer = 0;
3671 		break;
3672 	}
3673 
3674 	return ELINK_STATUS_OK;
3675 }
3676 
3677 static elink_status_t elink_eee_time_to_nvram(uint32_t idle_timer, uint32_t *nvram_mode)
3678 {
3679 	switch (idle_timer) {
3680 	case ELINK_EEE_MODE_NVRAM_BALANCED_TIME:
3681 		*nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED;
3682 		break;
3683 	case ELINK_EEE_MODE_NVRAM_AGGRESSIVE_TIME:
3684 		*nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE;
3685 		break;
3686 	case ELINK_EEE_MODE_NVRAM_LATENCY_TIME:
3687 		*nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY;
3688 		break;
3689 	default:
3690 		*nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED;
3691 		break;
3692 	}
3693 
3694 	return ELINK_STATUS_OK;
3695 }
3696 
3697 static uint32_t elink_eee_calc_timer(struct elink_params *params)
3698 {
3699 	uint32_t eee_mode, eee_idle;
3700 	struct bxe_softc *sc = params->sc;
3701 
3702 	if (params->eee_mode & ELINK_EEE_MODE_OVERRIDE_NVRAM) {
3703 		if (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME) {
3704 			/* time value in eee_mode --> used directly*/
3705 			eee_idle = params->eee_mode & ELINK_EEE_MODE_TIMER_MASK;
3706 		} else {
3707 			/* hsi value in eee_mode --> time */
3708 			if (elink_eee_nvram_to_time(params->eee_mode &
3709 						    ELINK_EEE_MODE_NVRAM_MASK,
3710 						    &eee_idle))
3711 				return 0;
3712 		}
3713 	} else {
3714 		/* hsi values in nvram --> time*/
3715 		eee_mode = ((REG_RD(sc, params->shmem_base +
3716 				    offsetof(struct shmem_region, dev_info.
3717 				    port_feature_config[params->port].
3718 				    eee_power_mode)) &
3719 			     PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >>
3720 			    PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT);
3721 
3722 		if (elink_eee_nvram_to_time(eee_mode, &eee_idle))
3723 			return 0;
3724 	}
3725 
3726 	return eee_idle;
3727 }
3728 
3729 static elink_status_t elink_eee_set_timers(struct elink_params *params,
3730 				   struct elink_vars *vars)
3731 {
3732 	uint32_t eee_idle = 0, eee_mode;
3733 	struct bxe_softc *sc = params->sc;
3734 
3735 	eee_idle = elink_eee_calc_timer(params);
3736 
3737 	if (eee_idle) {
3738 		REG_WR(sc, MISC_REG_CPMU_LP_IDLE_THR_P0 + (params->port << 2),
3739 		       eee_idle);
3740 	} else if ((params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI) &&
3741 		   (params->eee_mode & ELINK_EEE_MODE_OVERRIDE_NVRAM) &&
3742 		   (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME)) {
3743 		ELINK_DEBUG_P0(sc, "Error: Tx LPI is enabled with timer 0\n");
3744 		return ELINK_STATUS_ERROR;
3745 	}
3746 
3747 	vars->eee_status &= ~(SHMEM_EEE_TIMER_MASK | SHMEM_EEE_TIME_OUTPUT_BIT);
3748 	if (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME) {
3749 		/* eee_idle in 1u --> eee_status in 16u */
3750 		eee_idle >>= 4;
3751 		vars->eee_status |= (eee_idle & SHMEM_EEE_TIMER_MASK) |
3752 				    SHMEM_EEE_TIME_OUTPUT_BIT;
3753 	} else {
3754 		if (elink_eee_time_to_nvram(eee_idle, &eee_mode))
3755 			return ELINK_STATUS_ERROR;
3756 		vars->eee_status |= eee_mode;
3757 	}
3758 
3759 	return ELINK_STATUS_OK;
3760 }
3761 
3762 static elink_status_t elink_eee_initial_config(struct elink_params *params,
3763 				     struct elink_vars *vars, uint8_t mode)
3764 {
3765 	vars->eee_status |= ((uint32_t) mode) << SHMEM_EEE_SUPPORTED_SHIFT;
3766 
3767 	/* Propagate params' bits --> vars (for migration exposure) */
3768 	if (params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)
3769 		vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT;
3770 	else
3771 		vars->eee_status &= ~SHMEM_EEE_LPI_REQUESTED_BIT;
3772 
3773 	if (params->eee_mode & ELINK_EEE_MODE_ADV_LPI)
3774 		vars->eee_status |= SHMEM_EEE_REQUESTED_BIT;
3775 	else
3776 		vars->eee_status &= ~SHMEM_EEE_REQUESTED_BIT;
3777 
3778 	return elink_eee_set_timers(params, vars);
3779 }
3780 
3781 static elink_status_t elink_eee_disable(struct elink_phy *phy,
3782 				struct elink_params *params,
3783 				struct elink_vars *vars)
3784 {
3785 	struct bxe_softc *sc = params->sc;
3786 
3787 	/* Make Certain LPI is disabled */
3788 	REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), 0);
3789 
3790 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0x0);
3791 
3792 	vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
3793 
3794 	return ELINK_STATUS_OK;
3795 }
3796 
3797 static elink_status_t elink_eee_advertise(struct elink_phy *phy,
3798 				  struct elink_params *params,
3799 				  struct elink_vars *vars, uint8_t modes)
3800 {
3801 	struct bxe_softc *sc = params->sc;
3802 	uint16_t val = 0;
3803 
3804 	/* Mask events preventing LPI generation */
3805 	REG_WR(sc, MISC_REG_CPMU_LP_MASK_EXT_P0 + (params->port << 2), 0xfc20);
3806 
3807 	if (modes & SHMEM_EEE_10G_ADV) {
3808 		ELINK_DEBUG_P0(sc, "Advertise 10GBase-T EEE\n");
3809 		val |= 0x8;
3810 	}
3811 	if (modes & SHMEM_EEE_1G_ADV) {
3812 		ELINK_DEBUG_P0(sc, "Advertise 1GBase-T EEE\n");
3813 		val |= 0x4;
3814 	}
3815 
3816 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, val);
3817 
3818 	vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
3819 	vars->eee_status |= (modes << SHMEM_EEE_ADV_STATUS_SHIFT);
3820 
3821 	return ELINK_STATUS_OK;
3822 }
3823 
3824 static void elink_update_mng_eee(struct elink_params *params, uint32_t eee_status)
3825 {
3826 	struct bxe_softc *sc = params->sc;
3827 
3828 	if (elink_eee_has_cap(params))
3829 		REG_WR(sc, params->shmem2_base +
3830 		       offsetof(struct shmem2_region,
3831 				eee_status[params->port]), eee_status);
3832 }
3833 
3834 static void elink_eee_an_resolve(struct elink_phy *phy,
3835 				  struct elink_params *params,
3836 				  struct elink_vars *vars)
3837 {
3838 	struct bxe_softc *sc = params->sc;
3839 	uint16_t adv = 0, lp = 0;
3840 	uint32_t lp_adv = 0;
3841 	uint8_t neg = 0;
3842 
3843 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, &adv);
3844 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LP_EEE_ADV, &lp);
3845 
3846 	if (lp & 0x2) {
3847 		lp_adv |= SHMEM_EEE_100M_ADV;
3848 		if (adv & 0x2) {
3849 			if (vars->line_speed == ELINK_SPEED_100)
3850 				neg = 1;
3851 			ELINK_DEBUG_P0(sc, "EEE negotiated - 100M\n");
3852 		}
3853 	}
3854 	if (lp & 0x14) {
3855 		lp_adv |= SHMEM_EEE_1G_ADV;
3856 		if (adv & 0x14) {
3857 			if (vars->line_speed == ELINK_SPEED_1000)
3858 				neg = 1;
3859 			ELINK_DEBUG_P0(sc, "EEE negotiated - 1G\n");
3860 		}
3861 	}
3862 	if (lp & 0x68) {
3863 		lp_adv |= SHMEM_EEE_10G_ADV;
3864 		if (adv & 0x68) {
3865 			if (vars->line_speed == ELINK_SPEED_10000)
3866 				neg = 1;
3867 			ELINK_DEBUG_P0(sc, "EEE negotiated - 10G\n");
3868 		}
3869 	}
3870 
3871 	vars->eee_status &= ~SHMEM_EEE_LP_ADV_STATUS_MASK;
3872 	vars->eee_status |= (lp_adv << SHMEM_EEE_LP_ADV_STATUS_SHIFT);
3873 
3874 	if (neg) {
3875 		ELINK_DEBUG_P0(sc, "EEE is active\n");
3876 		vars->eee_status |= SHMEM_EEE_ACTIVE_BIT;
3877 	}
3878 }
3879 
3880 /******************************************************************/
3881 /*			BSC access functions from E3	          */
3882 /******************************************************************/
3883 static void elink_bsc_module_sel(struct elink_params *params)
3884 {
3885 	int idx;
3886 	uint32_t board_cfg, sfp_ctrl;
3887 	uint32_t i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
3888 	struct bxe_softc *sc = params->sc;
3889 	uint8_t port = params->port;
3890 	/* Read I2C output PINs */
3891 	board_cfg = REG_RD(sc, params->shmem_base +
3892 			   offsetof(struct shmem_region,
3893 				    dev_info.shared_hw_config.board));
3894 	i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
3895 	i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
3896 			SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
3897 
3898 	/* Read I2C output value */
3899 	sfp_ctrl = REG_RD(sc, params->shmem_base +
3900 			  offsetof(struct shmem_region,
3901 				 dev_info.port_hw_config[port].e3_cmn_pin_cfg));
3902 	i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
3903 	i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
3904 	ELINK_DEBUG_P0(sc, "Setting BSC switch\n");
3905 	for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
3906 		elink_set_cfg_pin(sc, i2c_pins[idx], i2c_val[idx]);
3907 }
3908 
3909 static elink_status_t elink_bsc_read(struct bxe_softc *sc,
3910 			  uint8_t sl_devid,
3911 			  uint16_t sl_addr,
3912 			  uint8_t lc_addr,
3913 			  uint8_t xfer_cnt,
3914 			  uint32_t *data_array)
3915 {
3916 	uint32_t val, i;
3917 	elink_status_t rc = ELINK_STATUS_OK;
3918 
3919 	if (xfer_cnt > 16) {
3920 		ELINK_DEBUG_P1(sc, "invalid xfer_cnt %d. Max is 16 bytes\n",
3921 					xfer_cnt);
3922 		return ELINK_STATUS_ERROR;
3923 	}
3924 
3925 	xfer_cnt = 16 - lc_addr;
3926 
3927 	/* Enable the engine */
3928 	val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3929 	val |= MCPR_IMC_COMMAND_ENABLE;
3930 	REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
3931 
3932 	/* Program slave device ID */
3933 	val = (sl_devid << 16) | sl_addr;
3934 	REG_WR(sc, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
3935 
3936 	/* Start xfer with 0 byte to update the address pointer ???*/
3937 	val = (MCPR_IMC_COMMAND_ENABLE) |
3938 	      (MCPR_IMC_COMMAND_WRITE_OP <<
3939 		MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3940 		(lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
3941 	REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
3942 
3943 	/* Poll for completion */
3944 	i = 0;
3945 	val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3946 	while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3947 		DELAY(10);
3948 		val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3949 		if (i++ > 1000) {
3950 			ELINK_DEBUG_P1(sc, "wr 0 byte timed out after %d try\n",
3951 								i);
3952 			rc = ELINK_STATUS_TIMEOUT;
3953 			break;
3954 		}
3955 	}
3956 	if (rc == ELINK_STATUS_TIMEOUT)
3957 		return rc;
3958 
3959 	/* Start xfer with read op */
3960 	val = (MCPR_IMC_COMMAND_ENABLE) |
3961 		(MCPR_IMC_COMMAND_READ_OP <<
3962 		MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3963 		(lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
3964 		  (xfer_cnt);
3965 	REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
3966 
3967 	/* Poll for completion */
3968 	i = 0;
3969 	val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3970 	while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3971 		DELAY(10);
3972 		val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3973 		if (i++ > 1000) {
3974 			ELINK_DEBUG_P1(sc, "rd op timed out after %d try\n", i);
3975 			rc = ELINK_STATUS_TIMEOUT;
3976 			break;
3977 		}
3978 	}
3979 	if (rc == ELINK_STATUS_TIMEOUT)
3980 		return rc;
3981 
3982 	for (i = (lc_addr >> 2); i < 4; i++) {
3983 		data_array[i] = REG_RD(sc, (MCP_REG_MCPR_IMC_DATAREG0 + i*4));
3984 #ifdef __BIG_ENDIAN
3985 		data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
3986 				((data_array[i] & 0x0000ff00) << 8) |
3987 				((data_array[i] & 0x00ff0000) >> 8) |
3988 				((data_array[i] & 0xff000000) >> 24);
3989 #endif
3990 	}
3991 	return rc;
3992 }
3993 
3994 static void elink_cl45_read_or_write(struct bxe_softc *sc, struct elink_phy *phy,
3995 				     uint8_t devad, uint16_t reg, uint16_t or_val)
3996 {
3997 	uint16_t val;
3998 	elink_cl45_read(sc, phy, devad, reg, &val);
3999 	elink_cl45_write(sc, phy, devad, reg, val | or_val);
4000 }
4001 
4002 static void elink_cl45_read_and_write(struct bxe_softc *sc,
4003 				      struct elink_phy *phy,
4004 				      uint8_t devad, uint16_t reg, uint16_t and_val)
4005 {
4006 	uint16_t val;
4007 	elink_cl45_read(sc, phy, devad, reg, &val);
4008 	elink_cl45_write(sc, phy, devad, reg, val & and_val);
4009 }
4010 
4011 elink_status_t elink_phy_read(struct elink_params *params, uint8_t phy_addr,
4012 		   uint8_t devad, uint16_t reg, uint16_t *ret_val)
4013 {
4014 	uint8_t phy_index;
4015 	/* Probe for the phy according to the given phy_addr, and execute
4016 	 * the read request on it
4017 	 */
4018 	for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
4019 		if (params->phy[phy_index].addr == phy_addr) {
4020 			return elink_cl45_read(params->sc,
4021 					       &params->phy[phy_index], devad,
4022 					       reg, ret_val);
4023 		}
4024 	}
4025 	return ELINK_STATUS_ERROR;
4026 }
4027 
4028 elink_status_t elink_phy_write(struct elink_params *params, uint8_t phy_addr,
4029 		    uint8_t devad, uint16_t reg, uint16_t val)
4030 {
4031 	uint8_t phy_index;
4032 	/* Probe for the phy according to the given phy_addr, and execute
4033 	 * the write request on it
4034 	 */
4035 	for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
4036 		if (params->phy[phy_index].addr == phy_addr) {
4037 			return elink_cl45_write(params->sc,
4038 						&params->phy[phy_index], devad,
4039 						reg, val);
4040 		}
4041 	}
4042 	return ELINK_STATUS_ERROR;
4043 }
4044 
4045 static uint8_t elink_get_warpcore_lane(struct elink_phy *phy,
4046 				  struct elink_params *params)
4047 {
4048 	uint8_t lane = 0;
4049 	struct bxe_softc *sc = params->sc;
4050 	uint32_t path_swap, path_swap_ovr;
4051 	uint8_t path, port;
4052 
4053 	path = SC_PATH(sc);
4054 	port = params->port;
4055 
4056 	if (elink_is_4_port_mode(sc)) {
4057 		uint32_t port_swap, port_swap_ovr;
4058 
4059 		/* Figure out path swap value */
4060 		path_swap_ovr = REG_RD(sc, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
4061 		if (path_swap_ovr & 0x1)
4062 			path_swap = (path_swap_ovr & 0x2);
4063 		else
4064 			path_swap = REG_RD(sc, MISC_REG_FOUR_PORT_PATH_SWAP);
4065 
4066 		if (path_swap)
4067 			path = path ^ 1;
4068 
4069 		/* Figure out port swap value */
4070 		port_swap_ovr = REG_RD(sc, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
4071 		if (port_swap_ovr & 0x1)
4072 			port_swap = (port_swap_ovr & 0x2);
4073 		else
4074 			port_swap = REG_RD(sc, MISC_REG_FOUR_PORT_PORT_SWAP);
4075 
4076 		if (port_swap)
4077 			port = port ^ 1;
4078 
4079 		lane = (port<<1) + path;
4080 	} else { /* Two port mode - no port swap */
4081 
4082 		/* Figure out path swap value */
4083 		path_swap_ovr =
4084 			REG_RD(sc, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
4085 		if (path_swap_ovr & 0x1) {
4086 			path_swap = (path_swap_ovr & 0x2);
4087 		} else {
4088 			path_swap =
4089 				REG_RD(sc, MISC_REG_TWO_PORT_PATH_SWAP);
4090 		}
4091 		if (path_swap)
4092 			path = path ^ 1;
4093 
4094 		lane = path << 1 ;
4095 	}
4096 	return lane;
4097 }
4098 
4099 
4100 static void elink_set_aer_mmd(struct elink_params *params,
4101 			      struct elink_phy *phy)
4102 {
4103 	uint32_t ser_lane;
4104 	uint16_t offset, aer_val;
4105 	struct bxe_softc *sc = params->sc;
4106 	ser_lane = ((params->lane_config &
4107 		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4108 		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4109 
4110 	offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
4111 		(phy->addr + ser_lane) : 0;
4112 
4113 	if (USES_WARPCORE(sc)) {
4114 		aer_val = elink_get_warpcore_lane(phy, params);
4115 		/* In Dual-lane mode, two lanes are joined together,
4116 		 * so in order to configure them, the AER broadcast method is
4117 		 * used here.
4118 		 * 0x200 is the broadcast address for lanes 0,1
4119 		 * 0x201 is the broadcast address for lanes 2,3
4120 		 */
4121 		if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
4122 			aer_val = (aer_val >> 1) | 0x200;
4123 	} else if (CHIP_IS_E2(sc))
4124 		aer_val = 0x3800 + offset - 1;
4125 	else
4126 		aer_val = 0x3800 + offset;
4127 
4128 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4129 			  MDIO_AER_BLOCK_AER_REG, aer_val);
4130 
4131 }
4132 
4133 /******************************************************************/
4134 /*			Internal phy section			  */
4135 /******************************************************************/
4136 
4137 static void elink_set_serdes_access(struct bxe_softc *sc, uint8_t port)
4138 {
4139 	uint32_t emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4140 
4141 	/* Set Clause 22 */
4142 	REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
4143 	REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
4144 	DELAY(500);
4145 	REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
4146 	DELAY(500);
4147 	 /* Set Clause 45 */
4148 	REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
4149 }
4150 
4151 static void elink_serdes_deassert(struct bxe_softc *sc, uint8_t port)
4152 {
4153 	uint32_t val;
4154 
4155 	ELINK_DEBUG_P0(sc, "elink_serdes_deassert\n");
4156 
4157 	val = ELINK_SERDES_RESET_BITS << (port*16);
4158 
4159 	/* Reset and unreset the SerDes/XGXS */
4160 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
4161 	DELAY(500);
4162 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
4163 
4164 	elink_set_serdes_access(sc, port);
4165 
4166 	REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
4167 	       ELINK_DEFAULT_PHY_DEV_ADDR);
4168 }
4169 
4170 static void elink_xgxs_specific_func(struct elink_phy *phy,
4171 				     struct elink_params *params,
4172 				     uint32_t action)
4173 {
4174 	struct bxe_softc *sc = params->sc;
4175 	switch (action) {
4176 	case ELINK_PHY_INIT:
4177 		/* Set correct devad */
4178 		REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_ST + params->port*0x18, 0);
4179 		REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
4180 		       phy->def_md_devad);
4181 		break;
4182 	}
4183 }
4184 
4185 static void elink_xgxs_deassert(struct elink_params *params)
4186 {
4187 	struct bxe_softc *sc = params->sc;
4188 	uint8_t port;
4189 	uint32_t val;
4190 	ELINK_DEBUG_P0(sc, "elink_xgxs_deassert\n");
4191 	port = params->port;
4192 
4193 	val = ELINK_XGXS_RESET_BITS << (port*16);
4194 
4195 	/* Reset and unreset the SerDes/XGXS */
4196 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
4197 	DELAY(500);
4198 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
4199 	elink_xgxs_specific_func(&params->phy[ELINK_INT_PHY], params,
4200 				 ELINK_PHY_INIT);
4201 }
4202 
4203 static void elink_calc_ieee_aneg_adv(struct elink_phy *phy,
4204 				     struct elink_params *params, uint16_t *ieee_fc)
4205 {
4206 	struct bxe_softc *sc = params->sc;
4207 	*ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
4208 	/* Resolve pause mode and advertisement Please refer to Table
4209 	 * 28B-3 of the 802.3ab-1999 spec
4210 	 */
4211 
4212 	switch (phy->req_flow_ctrl) {
4213 	case ELINK_FLOW_CTRL_AUTO:
4214 		switch (params->req_fc_auto_adv) {
4215 		case ELINK_FLOW_CTRL_BOTH:
4216 		case ELINK_FLOW_CTRL_RX:
4217 			*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4218 			break;
4219 		case ELINK_FLOW_CTRL_TX:
4220 			*ieee_fc |=
4221 				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
4222 			break;
4223 		default:
4224 			break;
4225 		}
4226 		break;
4227 	case ELINK_FLOW_CTRL_TX:
4228 		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
4229 		break;
4230 
4231 	case ELINK_FLOW_CTRL_RX:
4232 	case ELINK_FLOW_CTRL_BOTH:
4233 		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4234 		break;
4235 
4236 	case ELINK_FLOW_CTRL_NONE:
4237 	default:
4238 		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
4239 		break;
4240 	}
4241 	ELINK_DEBUG_P1(sc, "ieee_fc = 0x%x\n", *ieee_fc);
4242 }
4243 
4244 static void set_phy_vars(struct elink_params *params,
4245 			 struct elink_vars *vars)
4246 {
4247 	struct bxe_softc *sc = params->sc;
4248 	uint8_t actual_phy_idx, phy_index, link_cfg_idx;
4249 	uint8_t phy_config_swapped = params->multi_phy_config &
4250 			PORT_HW_CFG_PHY_SWAPPED_ENABLED;
4251 	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
4252 	      phy_index++) {
4253 		link_cfg_idx = ELINK_LINK_CONFIG_IDX(phy_index);
4254 		actual_phy_idx = phy_index;
4255 		if (phy_config_swapped) {
4256 			if (phy_index == ELINK_EXT_PHY1)
4257 				actual_phy_idx = ELINK_EXT_PHY2;
4258 			else if (phy_index == ELINK_EXT_PHY2)
4259 				actual_phy_idx = ELINK_EXT_PHY1;
4260 		}
4261 		params->phy[actual_phy_idx].req_flow_ctrl =
4262 			params->req_flow_ctrl[link_cfg_idx];
4263 
4264 		params->phy[actual_phy_idx].req_line_speed =
4265 			params->req_line_speed[link_cfg_idx];
4266 
4267 		params->phy[actual_phy_idx].speed_cap_mask =
4268 			params->speed_cap_mask[link_cfg_idx];
4269 
4270 		params->phy[actual_phy_idx].req_duplex =
4271 			params->req_duplex[link_cfg_idx];
4272 
4273 		if (params->req_line_speed[link_cfg_idx] ==
4274 		    ELINK_SPEED_AUTO_NEG)
4275 			vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
4276 
4277 		ELINK_DEBUG_P3(sc, "req_flow_ctrl %x, req_line_speed %x,"
4278 			   " speed_cap_mask %x\n",
4279 			   params->phy[actual_phy_idx].req_flow_ctrl,
4280 			   params->phy[actual_phy_idx].req_line_speed,
4281 			   params->phy[actual_phy_idx].speed_cap_mask);
4282 	}
4283 }
4284 
4285 static void elink_ext_phy_set_pause(struct elink_params *params,
4286 				    struct elink_phy *phy,
4287 				    struct elink_vars *vars)
4288 {
4289 	uint16_t val;
4290 	struct bxe_softc *sc = params->sc;
4291 	/* Read modify write pause advertizing */
4292 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
4293 
4294 	val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
4295 
4296 	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
4297 	elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
4298 	if ((vars->ieee_fc &
4299 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
4300 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
4301 		val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
4302 	}
4303 	if ((vars->ieee_fc &
4304 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
4305 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
4306 		val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
4307 	}
4308 	ELINK_DEBUG_P1(sc, "Ext phy AN advertize 0x%x\n", val);
4309 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
4310 }
4311 
4312 static void elink_pause_resolve(struct elink_phy *phy,
4313 				struct elink_params *params,
4314 				struct elink_vars *vars,
4315 				uint32_t pause_result)
4316 {
4317 	struct bxe_softc *sc = params->sc;
4318 						/*  LD	    LP	 */
4319 	switch (pause_result) {			/* ASYM P ASYM P */
4320 	case 0xb:				/*   1  0   1  1 */
4321 		ELINK_DEBUG_P0(sc, "Flow Control: TX only\n");
4322 		vars->flow_ctrl = ELINK_FLOW_CTRL_TX;
4323 		break;
4324 
4325 	case 0xe:				/*   1  1   1  0 */
4326 		ELINK_DEBUG_P0(sc, "Flow Control: RX only\n");
4327 		vars->flow_ctrl = ELINK_FLOW_CTRL_RX;
4328 		break;
4329 
4330 	case 0x5:				/*   0  1   0  1 */
4331 	case 0x7:				/*   0  1   1  1 */
4332 	case 0xd:				/*   1  1   0  1 */
4333 	case 0xf:				/*   1  1   1  1 */
4334 		/* If the user selected to advertise RX ONLY,
4335 		 * although we advertised both, need to enable
4336 		 * RX only.
4337 		 */
4338 
4339 		if (params->req_fc_auto_adv == ELINK_FLOW_CTRL_BOTH) {
4340 			ELINK_DEBUG_P0(sc, "Flow Control: RX & TX\n");
4341 		vars->flow_ctrl = ELINK_FLOW_CTRL_BOTH;
4342 		} else {
4343 			ELINK_DEBUG_P0(sc, "Flow Control: RX only\n");
4344 			vars->flow_ctrl = ELINK_FLOW_CTRL_RX;
4345 		}
4346 		break;
4347 	default:
4348 		ELINK_DEBUG_P0(sc, "Flow Control: None\n");
4349 		vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
4350 		break;
4351 	}
4352 	if (pause_result & (1<<0))
4353 		vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
4354 	if (pause_result & (1<<1))
4355 		vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
4356 
4357 }
4358 
4359 static void elink_ext_phy_update_adv_fc(struct elink_phy *phy,
4360 					struct elink_params *params,
4361 					struct elink_vars *vars)
4362 {
4363 	uint16_t ld_pause;		/* local */
4364 	uint16_t lp_pause;		/* link partner */
4365 	uint16_t pause_result;
4366 	struct bxe_softc *sc = params->sc;
4367 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
4368 		elink_cl22_read(sc, phy, 0x4, &ld_pause);
4369 		elink_cl22_read(sc, phy, 0x5, &lp_pause);
4370 	} else if (CHIP_IS_E3(sc) &&
4371 		ELINK_SINGLE_MEDIA_DIRECT(params)) {
4372 		uint8_t lane = elink_get_warpcore_lane(phy, params);
4373 		uint16_t gp_status, gp_mask;
4374 		elink_cl45_read(sc, phy,
4375 				MDIO_AN_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_4,
4376 				&gp_status);
4377 		gp_mask = (MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL |
4378 			   MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP) <<
4379 			lane;
4380 		if ((gp_status & gp_mask) == gp_mask) {
4381 			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4382 					MDIO_AN_REG_ADV_PAUSE, &ld_pause);
4383 			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4384 					MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
4385 		} else {
4386 			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4387 					MDIO_AN_REG_CL37_FC_LD, &ld_pause);
4388 			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4389 					MDIO_AN_REG_CL37_FC_LP, &lp_pause);
4390 			ld_pause = ((ld_pause &
4391 				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
4392 				    << 3);
4393 			lp_pause = ((lp_pause &
4394 				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
4395 				    << 3);
4396 		}
4397 	} else {
4398 		elink_cl45_read(sc, phy,
4399 				MDIO_AN_DEVAD,
4400 				MDIO_AN_REG_ADV_PAUSE, &ld_pause);
4401 		elink_cl45_read(sc, phy,
4402 				MDIO_AN_DEVAD,
4403 				MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
4404 	}
4405 	pause_result = (ld_pause &
4406 			MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
4407 	pause_result |= (lp_pause &
4408 			 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
4409 	ELINK_DEBUG_P1(sc, "Ext PHY pause result 0x%x\n", pause_result);
4410 	elink_pause_resolve(phy, params, vars, pause_result);
4411 
4412 }
4413 
4414 static uint8_t elink_ext_phy_resolve_fc(struct elink_phy *phy,
4415 				   struct elink_params *params,
4416 				   struct elink_vars *vars)
4417 {
4418 	uint8_t ret = 0;
4419 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
4420 	if (phy->req_flow_ctrl != ELINK_FLOW_CTRL_AUTO) {
4421 		/* Update the advertised flow-controled of LD/LP in AN */
4422 		if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
4423 			elink_ext_phy_update_adv_fc(phy, params, vars);
4424 		/* But set the flow-control result as the requested one */
4425 		vars->flow_ctrl = phy->req_flow_ctrl;
4426 	} else if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
4427 		vars->flow_ctrl = params->req_fc_auto_adv;
4428 	else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
4429 		ret = 1;
4430 		elink_ext_phy_update_adv_fc(phy, params, vars);
4431 	}
4432 	return ret;
4433 }
4434 /******************************************************************/
4435 /*			Warpcore section			  */
4436 /******************************************************************/
4437 /* The init_internal_warpcore should mirror the xgxs,
4438  * i.e. reset the lane (if needed), set aer for the
4439  * init configuration, and set/clear SGMII flag. Internal
4440  * phy init is done purely in phy_init stage.
4441  */
4442 #define WC_TX_DRIVER(post2, idriver, ipre, ifir) \
4443 	((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \
4444 	 (idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \
4445 	 (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET) | \
4446 	 (ifir << MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET))
4447 
4448 #define WC_TX_FIR(post, main, pre) \
4449 	((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \
4450 	 (main << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | \
4451 	 (pre << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET))
4452 
4453 static void elink_update_link_attr(struct elink_params *params, uint32_t link_attr)
4454 {
4455 	struct bxe_softc *sc = params->sc;
4456 
4457 	if (SHMEM2_HAS(sc, link_attr_sync))
4458 		REG_WR(sc, params->shmem2_base +
4459 		       offsetof(struct shmem2_region,
4460 				link_attr_sync[params->port]), link_attr);
4461 }
4462 
4463 static void elink_warpcore_enable_AN_KR2(struct elink_phy *phy,
4464 					 struct elink_params *params,
4465 					 struct elink_vars *vars)
4466 {
4467 	struct bxe_softc *sc = params->sc;
4468 	uint16_t i;
4469 	static struct elink_reg_set reg_set[] = {
4470 		/* Step 1 - Program the TX/RX alignment markers */
4471 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0xa157},
4472 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xcbe2},
4473 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0x7537},
4474 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0xa157},
4475 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xcbe2},
4476 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0x7537},
4477 		/* Step 2 - Configure the NP registers */
4478 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000a},
4479 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6400},
4480 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0620},
4481 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0157},
4482 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x6464},
4483 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x3150},
4484 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x3150},
4485 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0157},
4486 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0620}
4487 	};
4488 	ELINK_DEBUG_P0(sc, "Enabling 20G-KR2\n");
4489 
4490 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4491 				 MDIO_WC_REG_CL49_USERB0_CTRL, (3<<6));
4492 
4493 	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4494 		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4495 				 reg_set[i].val);
4496 
4497 	/* Start KR2 work-around timer which handles BCM8073 link-parner */
4498 	params->link_attr_sync |= LINK_ATTR_SYNC_KR2_ENABLE;
4499 	elink_update_link_attr(params, params->link_attr_sync);
4500 }
4501 
4502 static void elink_disable_kr2(struct elink_params *params,
4503 			      struct elink_vars *vars,
4504 			      struct elink_phy *phy)
4505 {
4506 	struct bxe_softc *sc = params->sc;
4507 	int i;
4508 	static struct elink_reg_set reg_set[] = {
4509 		/* Step 1 - Program the TX/RX alignment markers */
4510 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0x7690},
4511 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xe647},
4512 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0xc4f0},
4513 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0x7690},
4514 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xe647},
4515 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0xc4f0},
4516 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000c},
4517 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6000},
4518 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0000},
4519 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0002},
4520 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x0000},
4521 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x0af7},
4522 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x0af7},
4523 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0002},
4524 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0000}
4525 	};
4526 	ELINK_DEBUG_P0(sc, "Disabling 20G-KR2\n");
4527 
4528 	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4529 		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4530 				 reg_set[i].val);
4531 	params->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE;
4532 	elink_update_link_attr(params, params->link_attr_sync);
4533 
4534 	vars->check_kr2_recovery_cnt = ELINK_CHECK_KR2_RECOVERY_CNT;
4535 }
4536 
4537 static void elink_warpcore_set_lpi_passthrough(struct elink_phy *phy,
4538 					       struct elink_params *params)
4539 {
4540 	struct bxe_softc *sc = params->sc;
4541 
4542 	ELINK_DEBUG_P0(sc, "Configure WC for LPI pass through\n");
4543 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4544 			 MDIO_WC_REG_EEE_COMBO_CONTROL0, 0x7c);
4545 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4546 				 MDIO_WC_REG_DIGITAL4_MISC5, 0xc000);
4547 }
4548 
4549 static void elink_warpcore_restart_AN_KR(struct elink_phy *phy,
4550 					 struct elink_params *params)
4551 {
4552 	/* Restart autoneg on the leading lane only */
4553 	struct bxe_softc *sc = params->sc;
4554 	uint16_t lane = elink_get_warpcore_lane(phy, params);
4555 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4556 			  MDIO_AER_BLOCK_AER_REG, lane);
4557 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4558 			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
4559 
4560 	/* Restore AER */
4561 	elink_set_aer_mmd(params, phy);
4562 }
4563 
4564 static void elink_warpcore_enable_AN_KR(struct elink_phy *phy,
4565 					struct elink_params *params,
4566 					struct elink_vars *vars) {
4567 	uint16_t lane, i, cl72_ctrl, an_adv = 0, val;
4568 	uint32_t wc_lane_config;
4569 	struct bxe_softc *sc = params->sc;
4570 	static struct elink_reg_set reg_set[] = {
4571 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
4572 		{MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0},
4573 		{MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415},
4574 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190},
4575 		/* Disable Autoneg: re-enable it after adv is done. */
4576 		{MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0},
4577 		{MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2},
4578 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0},
4579 	};
4580 	ELINK_DEBUG_P0(sc, "Enable Auto Negotiation for KR\n");
4581 	/* Set to default registers that may be overriden by 10G force */
4582 	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4583 		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4584 				 reg_set[i].val);
4585 
4586 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4587 			MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl);
4588 	cl72_ctrl &= 0x08ff;
4589 	cl72_ctrl |= 0x3800;
4590 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4591 			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl);
4592 
4593 	/* Check adding advertisement for 1G KX */
4594 	if (((vars->line_speed == ELINK_SPEED_AUTO_NEG) &&
4595 	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
4596 	    (vars->line_speed == ELINK_SPEED_1000)) {
4597 		uint16_t addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2;
4598 		an_adv |= (1<<5);
4599 
4600 		/* Enable CL37 1G Parallel Detect */
4601 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD, addr, 0x1);
4602 		ELINK_DEBUG_P0(sc, "Advertize 1G\n");
4603 	}
4604 	if (((vars->line_speed == ELINK_SPEED_AUTO_NEG) &&
4605 	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
4606 	    (vars->line_speed ==  ELINK_SPEED_10000)) {
4607 		/* Check adding advertisement for 10G KR */
4608 		an_adv |= (1<<7);
4609 		/* Enable 10G Parallel Detect */
4610 		CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4611 				  MDIO_AER_BLOCK_AER_REG, 0);
4612 
4613 		elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4614 				 MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
4615 		elink_set_aer_mmd(params, phy);
4616 		ELINK_DEBUG_P0(sc, "Advertize 10G\n");
4617 	}
4618 
4619 	/* Set Transmit PMD settings */
4620 	lane = elink_get_warpcore_lane(phy, params);
4621 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4622 			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
4623 			 WC_TX_DRIVER(0x02, 0x06, 0x09, 0));
4624 	/* Configure the next lane if dual mode */
4625 	if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
4626 		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4627 				 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1),
4628 				 WC_TX_DRIVER(0x02, 0x06, 0x09, 0));
4629 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4630 			 MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
4631 			 0x03f0);
4632 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4633 			 MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
4634 			 0x03f0);
4635 
4636 	/* Advertised speeds */
4637 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4638 			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, an_adv);
4639 
4640 	/* Advertised and set FEC (Forward Error Correction) */
4641 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4642 			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2,
4643 			 (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY |
4644 			  MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ));
4645 
4646 	/* Enable CL37 BAM */
4647 	if (REG_RD(sc, params->shmem_base +
4648 		   offsetof(struct shmem_region, dev_info.
4649 			    port_hw_config[params->port].default_cfg)) &
4650 	    PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
4651 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4652 					 MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL,
4653 					 1);
4654 		ELINK_DEBUG_P0(sc, "Enable CL37 BAM on KR\n");
4655 	}
4656 
4657 	/* Advertise pause */
4658 	elink_ext_phy_set_pause(params, phy, vars);
4659 	vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
4660 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4661 				 MDIO_WC_REG_DIGITAL5_MISC7, 0x100);
4662 
4663 	/* Over 1G - AN local device user page 1 */
4664 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4665 			MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
4666 
4667 	if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
4668 	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) ||
4669 	    (phy->req_line_speed == ELINK_SPEED_20000)) {
4670 
4671 		CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4672 				  MDIO_AER_BLOCK_AER_REG, lane);
4673 
4674 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4675 					 MDIO_WC_REG_RX1_PCI_CTRL + (0x10*lane),
4676 					 (1<<11));
4677 
4678 		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4679 				 MDIO_WC_REG_XGXS_X2_CONTROL3, 0x7);
4680 		elink_set_aer_mmd(params, phy);
4681 
4682 		elink_warpcore_enable_AN_KR2(phy, params, vars);
4683 	} else {
4684 		/* Enable Auto-Detect to support 1G over CL37 as well */
4685 		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4686 				 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x10);
4687 		wc_lane_config = REG_RD(sc, params->shmem_base +
4688 					offsetof(struct shmem_region, dev_info.
4689 					shared_hw_config.wc_lane_config));
4690 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4691 				MDIO_WC_REG_RX0_PCI_CTRL + (lane << 4), &val);
4692 		/* Force cl48 sync_status LOW to avoid getting stuck in CL73
4693 		 * parallel-detect loop when CL73 and CL37 are enabled.
4694 		 */
4695 		val |= 1 << 11;
4696 
4697 		/* Restore Polarity settings in case it was run over by
4698 		 * previous link owner
4699 		 */
4700 		if (wc_lane_config &
4701 		    (SHARED_HW_CFG_RX_LANE0_POL_FLIP_ENABLED << lane))
4702 			val |= 3 << 2;
4703 		else
4704 			val &= ~(3 << 2);
4705 		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4706 				 MDIO_WC_REG_RX0_PCI_CTRL + (lane << 4),
4707 				 val);
4708 
4709 		elink_disable_kr2(params, vars, phy);
4710 	}
4711 
4712 	/* Enable Autoneg: only on the main lane */
4713 	elink_warpcore_restart_AN_KR(phy, params);
4714 }
4715 
4716 static void elink_warpcore_set_10G_KR(struct elink_phy *phy,
4717 				      struct elink_params *params,
4718 				      struct elink_vars *vars)
4719 {
4720 	struct bxe_softc *sc = params->sc;
4721 	uint16_t val16, i, lane;
4722 	static struct elink_reg_set reg_set[] = {
4723 		/* Disable Autoneg */
4724 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
4725 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
4726 			0x3f00},
4727 		{MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0},
4728 		{MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0},
4729 		{MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1},
4730 		{MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa},
4731 		/* Leave cl72 training enable, needed for KR */
4732 		{MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2}
4733 	};
4734 
4735 	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4736 		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4737 				 reg_set[i].val);
4738 
4739 	lane = elink_get_warpcore_lane(phy, params);
4740 	/* Global registers */
4741 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4742 			  MDIO_AER_BLOCK_AER_REG, 0);
4743 	/* Disable CL36 PCS Tx */
4744 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4745 			MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
4746 	val16 &= ~(0x0011 << lane);
4747 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4748 			 MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
4749 
4750 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4751 			MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
4752 	val16 |= (0x0303 << (lane << 1));
4753 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4754 			 MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
4755 	/* Restore AER */
4756 	elink_set_aer_mmd(params, phy);
4757 	/* Set speed via PMA/PMD register */
4758 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD,
4759 			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
4760 
4761 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD,
4762 			 MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
4763 
4764 	/* Enable encoded forced speed */
4765 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4766 			 MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
4767 
4768 	/* Turn TX scramble payload only the 64/66 scrambler */
4769 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4770 			 MDIO_WC_REG_TX66_CONTROL, 0x9);
4771 
4772 	/* Turn RX scramble payload only the 64/66 scrambler */
4773 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4774 				 MDIO_WC_REG_RX66_CONTROL, 0xF9);
4775 
4776 	/* Set and clear loopback to cause a reset to 64/66 decoder */
4777 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4778 			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
4779 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4780 			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
4781 
4782 }
4783 
4784 static void elink_warpcore_set_10G_XFI(struct elink_phy *phy,
4785 				       struct elink_params *params,
4786 				       uint8_t is_xfi)
4787 {
4788 	struct bxe_softc *sc = params->sc;
4789 	uint16_t misc1_val, tap_val, tx_driver_val, lane, val;
4790 	uint32_t cfg_tap_val, tx_drv_brdct, tx_equal;
4791 	uint32_t ifir_val, ipost2_val, ipre_driver_val;
4792 	/* Hold rxSeqStart */
4793 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4794 				 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x8000);
4795 
4796 	/* Hold tx_fifo_reset */
4797 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4798 				 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x1);
4799 
4800 	/* Disable CL73 AN */
4801 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
4802 
4803 	/* Disable 100FX Enable and Auto-Detect */
4804 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4805 				  MDIO_WC_REG_FX100_CTRL1, 0xFFFA);
4806 
4807 	/* Disable 100FX Idle detect */
4808 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4809 				 MDIO_WC_REG_FX100_CTRL3, 0x0080);
4810 
4811 	/* Set Block address to Remote PHY & Clear forced_speed[5] */
4812 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4813 				  MDIO_WC_REG_DIGITAL4_MISC3, 0xFF7F);
4814 
4815 	/* Turn off auto-detect & fiber mode */
4816 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4817 				  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4818 				  0xFFEE);
4819 
4820 	/* Set filter_force_link, disable_false_link and parallel_detect */
4821 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4822 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
4823 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4824 			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4825 			 ((val | 0x0006) & 0xFFFE));
4826 
4827 	/* Set XFI / SFI */
4828 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4829 			MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
4830 
4831 	misc1_val &= ~(0x1f);
4832 
4833 	if (is_xfi) {
4834 		misc1_val |= 0x5;
4835 		tap_val = WC_TX_FIR(0x08, 0x37, 0x00);
4836 		tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03, 0);
4837 	} else {
4838 		cfg_tap_val = REG_RD(sc, params->shmem_base +
4839 				     offsetof(struct shmem_region, dev_info.
4840 					      port_hw_config[params->port].
4841 					      sfi_tap_values));
4842 
4843 		tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK;
4844 
4845 		misc1_val |= 0x9;
4846 
4847 		/* TAP values are controlled by nvram, if value there isn't 0 */
4848 		if (tx_equal)
4849 			tap_val = (uint16_t)tx_equal;
4850 		else
4851 			tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02);
4852 
4853 		ifir_val = DEFAULT_TX_DRV_IFIR;
4854 		ipost2_val = DEFAULT_TX_DRV_POST2;
4855 		ipre_driver_val = DEFAULT_TX_DRV_IPRE_DRIVER;
4856 		tx_drv_brdct = DEFAULT_TX_DRV_BRDCT;
4857 
4858 		/* If any of the IFIR/IPRE_DRIVER/POST@ is set, apply all
4859 		 * configuration.
4860 		 */
4861 		if (cfg_tap_val & (PORT_HW_CFG_TX_DRV_IFIR_MASK |
4862 				   PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK |
4863 				   PORT_HW_CFG_TX_DRV_POST2_MASK)) {
4864 			ifir_val = (cfg_tap_val &
4865 				    PORT_HW_CFG_TX_DRV_IFIR_MASK) >>
4866 				PORT_HW_CFG_TX_DRV_IFIR_SHIFT;
4867 			ipre_driver_val = (cfg_tap_val &
4868 					   PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK)
4869 			>> PORT_HW_CFG_TX_DRV_IPREDRIVER_SHIFT;
4870 			ipost2_val = (cfg_tap_val &
4871 				      PORT_HW_CFG_TX_DRV_POST2_MASK) >>
4872 				PORT_HW_CFG_TX_DRV_POST2_SHIFT;
4873 		}
4874 
4875 		if (cfg_tap_val & PORT_HW_CFG_TX_DRV_BROADCAST_MASK) {
4876 			tx_drv_brdct = (cfg_tap_val &
4877 					PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >>
4878 				PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT;
4879 		}
4880 
4881 		tx_driver_val = WC_TX_DRIVER(ipost2_val, tx_drv_brdct,
4882 					     ipre_driver_val, ifir_val);
4883 	}
4884 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4885 			 MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
4886 
4887 	/* Set Transmit PMD settings */
4888 	lane = elink_get_warpcore_lane(phy, params);
4889 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4890 			 MDIO_WC_REG_TX_FIR_TAP,
4891 			 tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
4892 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4893 			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
4894 			 tx_driver_val);
4895 
4896 	/* Enable fiber mode, enable and invert sig_det */
4897 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4898 				 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0xd);
4899 
4900 	/* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
4901 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4902 				 MDIO_WC_REG_DIGITAL4_MISC3, 0x8080);
4903 
4904 	elink_warpcore_set_lpi_passthrough(phy, params);
4905 
4906 	/* 10G XFI Full Duplex */
4907 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4908 			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
4909 
4910 	/* Release tx_fifo_reset */
4911 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4912 				  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3,
4913 				  0xFFFE);
4914 	/* Release rxSeqStart */
4915 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4916 				  MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x7FFF);
4917 }
4918 
4919 static void elink_warpcore_set_20G_force_KR2(struct elink_phy *phy,
4920 					     struct elink_params *params)
4921 {
4922 	uint16_t val;
4923 	struct bxe_softc *sc = params->sc;
4924 	/* Set global registers, so set AER lane to 0 */
4925 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4926 			  MDIO_AER_BLOCK_AER_REG, 0);
4927 
4928 	/* Disable sequencer */
4929 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4930 				  MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, ~(1<<13));
4931 
4932 	elink_set_aer_mmd(params, phy);
4933 
4934 	elink_cl45_read_and_write(sc, phy, MDIO_PMA_DEVAD,
4935 				  MDIO_WC_REG_PMD_KR_CONTROL, ~(1<<1));
4936 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4937 			 MDIO_AN_REG_CTRL, 0);
4938 	/* Turn off CL73 */
4939 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4940 			MDIO_WC_REG_CL73_USERB0_CTRL, &val);
4941 	val &= ~(1<<5);
4942 	val |= (1<<6);
4943 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4944 			 MDIO_WC_REG_CL73_USERB0_CTRL, val);
4945 
4946 	/* Set 20G KR2 force speed */
4947 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4948 				 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x1f);
4949 
4950 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4951 				 MDIO_WC_REG_DIGITAL4_MISC3, (1<<7));
4952 
4953 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4954 			MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &val);
4955 	val &= ~(3<<14);
4956 	val |= (1<<15);
4957 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4958 			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, val);
4959 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4960 			 MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0x835A);
4961 
4962 	/* Enable sequencer (over lane 0) */
4963 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4964 			  MDIO_AER_BLOCK_AER_REG, 0);
4965 
4966 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4967 				 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, (1<<13));
4968 
4969 	elink_set_aer_mmd(params, phy);
4970 }
4971 
4972 static void elink_warpcore_set_20G_DXGXS(struct bxe_softc *sc,
4973 					 struct elink_phy *phy,
4974 					 uint16_t lane)
4975 {
4976 	/* Rx0 anaRxControl1G */
4977 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4978 			 MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
4979 
4980 	/* Rx2 anaRxControl1G */
4981 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4982 			 MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
4983 
4984 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4985 			 MDIO_WC_REG_RX66_SCW0, 0xE070);
4986 
4987 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4988 			 MDIO_WC_REG_RX66_SCW1, 0xC0D0);
4989 
4990 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4991 			 MDIO_WC_REG_RX66_SCW2, 0xA0B0);
4992 
4993 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4994 			 MDIO_WC_REG_RX66_SCW3, 0x8090);
4995 
4996 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4997 			 MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
4998 
4999 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5000 			 MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
5001 
5002 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5003 			 MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
5004 
5005 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5006 			 MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
5007 
5008 	/* Serdes Digital Misc1 */
5009 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5010 			 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
5011 
5012 	/* Serdes Digital4 Misc3 */
5013 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5014 			 MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
5015 
5016 	/* Set Transmit PMD settings */
5017 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5018 			 MDIO_WC_REG_TX_FIR_TAP,
5019 			 (WC_TX_FIR(0x12, 0x2d, 0x00) |
5020 			  MDIO_WC_REG_TX_FIR_TAP_ENABLE));
5021 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5022 			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
5023 			 WC_TX_DRIVER(0x02, 0x02, 0x02, 0));
5024 }
5025 
5026 static void elink_warpcore_set_sgmii_speed(struct elink_phy *phy,
5027 					   struct elink_params *params,
5028 					   uint8_t fiber_mode,
5029 					   uint8_t always_autoneg)
5030 {
5031 	struct bxe_softc *sc = params->sc;
5032 	uint16_t val16, digctrl_kx1, digctrl_kx2;
5033 
5034 	/* Clear XFI clock comp in non-10G single lane mode. */
5035 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5036 				  MDIO_WC_REG_RX66_CONTROL, ~(3<<13));
5037 
5038 	elink_warpcore_set_lpi_passthrough(phy, params);
5039 
5040 	if (always_autoneg || phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
5041 		/* SGMII Autoneg */
5042 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5043 					 MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
5044 					 0x1000);
5045 		ELINK_DEBUG_P0(sc, "set SGMII AUTONEG\n");
5046 	} else {
5047 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5048 				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
5049 		val16 &= 0xcebf;
5050 		switch (phy->req_line_speed) {
5051 		case ELINK_SPEED_10:
5052 			break;
5053 		case ELINK_SPEED_100:
5054 			val16 |= 0x2000;
5055 			break;
5056 		case ELINK_SPEED_1000:
5057 			val16 |= 0x0040;
5058 			break;
5059 		default:
5060 			ELINK_DEBUG_P1(sc,
5061 			   "Speed not supported: 0x%x\n", phy->req_line_speed);
5062 			return;
5063 		}
5064 
5065 		if (phy->req_duplex == DUPLEX_FULL)
5066 			val16 |= 0x0100;
5067 
5068 		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5069 				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
5070 
5071 		ELINK_DEBUG_P1(sc, "set SGMII force speed %d\n",
5072 			       phy->req_line_speed);
5073 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5074 				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
5075 		ELINK_DEBUG_P1(sc, "  (readback) %x\n", val16);
5076 	}
5077 
5078 	/* SGMII Slave mode and disable signal detect */
5079 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5080 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
5081 	if (fiber_mode)
5082 		digctrl_kx1 = 1;
5083 	else
5084 		digctrl_kx1 &= 0xff4a;
5085 
5086 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5087 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
5088 			digctrl_kx1);
5089 
5090 	/* Turn off parallel detect */
5091 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5092 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
5093 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5094 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
5095 			(digctrl_kx2 & ~(1<<2)));
5096 
5097 	/* Re-enable parallel detect */
5098 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5099 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
5100 			(digctrl_kx2 | (1<<2)));
5101 
5102 	/* Enable autodet */
5103 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5104 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
5105 			(digctrl_kx1 | 0x10));
5106 }
5107 
5108 
5109 static void elink_warpcore_reset_lane(struct bxe_softc *sc,
5110 				      struct elink_phy *phy,
5111 				      uint8_t reset)
5112 {
5113 	uint16_t val;
5114 	/* Take lane out of reset after configuration is finished */
5115 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5116 			MDIO_WC_REG_DIGITAL5_MISC6, &val);
5117 	if (reset)
5118 		val |= 0xC000;
5119 	else
5120 		val &= 0x3FFF;
5121 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5122 			 MDIO_WC_REG_DIGITAL5_MISC6, val);
5123 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5124 			 MDIO_WC_REG_DIGITAL5_MISC6, &val);
5125 }
5126 
5127 /* Clear SFI/XFI link settings registers */
5128 static void elink_warpcore_clear_regs(struct elink_phy *phy,
5129 				      struct elink_params *params,
5130 				      uint16_t lane)
5131 {
5132 	struct bxe_softc *sc = params->sc;
5133 	uint16_t i;
5134 	static struct elink_reg_set wc_regs[] = {
5135 		{MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0},
5136 		{MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL1, 0x014a},
5137 		{MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL3, 0x0800},
5138 		{MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL4_MISC3, 0x8008},
5139 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
5140 			0x0195},
5141 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
5142 			0x0007},
5143 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3,
5144 			0x0002},
5145 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000},
5146 		{MDIO_WC_DEVAD, MDIO_WC_REG_TX_FIR_TAP, 0x0000},
5147 		{MDIO_WC_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040},
5148 		{MDIO_WC_DEVAD, MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140}
5149 	};
5150 	/* Set XFI clock comp as default. */
5151 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5152 				 MDIO_WC_REG_RX66_CONTROL, (3<<13));
5153 
5154 	for (i = 0; i < ARRAY_SIZE(wc_regs); i++)
5155 		elink_cl45_write(sc, phy, wc_regs[i].devad, wc_regs[i].reg,
5156 				 wc_regs[i].val);
5157 
5158 	lane = elink_get_warpcore_lane(phy, params);
5159 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5160 			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990);
5161 
5162 }
5163 
5164 static elink_status_t elink_get_mod_abs_int_cfg(struct bxe_softc *sc,
5165 						uint32_t chip_id,
5166 						uint32_t shmem_base, uint8_t port,
5167 						uint8_t *gpio_num, uint8_t *gpio_port)
5168 {
5169 	uint32_t cfg_pin;
5170 	*gpio_num = 0;
5171 	*gpio_port = 0;
5172 	if (CHIP_IS_E3(sc)) {
5173 		cfg_pin = (REG_RD(sc, shmem_base +
5174 				offsetof(struct shmem_region,
5175 				dev_info.port_hw_config[port].e3_sfp_ctrl)) &
5176 				PORT_HW_CFG_E3_MOD_ABS_MASK) >>
5177 				PORT_HW_CFG_E3_MOD_ABS_SHIFT;
5178 
5179 		/* Should not happen. This function called upon interrupt
5180 		 * triggered by GPIO ( since EPIO can only generate interrupts
5181 		 * to MCP).
5182 		 * So if this function was called and none of the GPIOs was set,
5183 		 * it means the shit hit the fan.
5184 		 */
5185 		if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
5186 		    (cfg_pin > PIN_CFG_GPIO3_P1)) {
5187 			ELINK_DEBUG_P1(sc,
5188 			   "No cfg pin %x for module detect indication\n",
5189 			   cfg_pin);
5190 			return ELINK_STATUS_ERROR;
5191 		}
5192 
5193 		*gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
5194 		*gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
5195 	} else {
5196 		*gpio_num = MISC_REGISTERS_GPIO_3;
5197 		*gpio_port = port;
5198 	}
5199 
5200 	return ELINK_STATUS_OK;
5201 }
5202 
5203 static int elink_is_sfp_module_plugged(struct elink_phy *phy,
5204 				       struct elink_params *params)
5205 {
5206 	struct bxe_softc *sc = params->sc;
5207 	uint8_t gpio_num, gpio_port;
5208 	uint32_t gpio_val;
5209 	if (elink_get_mod_abs_int_cfg(sc, params->chip_id,
5210 				      params->shmem_base, params->port,
5211 				      &gpio_num, &gpio_port) != ELINK_STATUS_OK)
5212 		return 0;
5213 	gpio_val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
5214 
5215 	/* Call the handling function in case module is detected */
5216 	if (gpio_val == 0)
5217 		return 1;
5218 	else
5219 		return 0;
5220 }
5221 static int elink_warpcore_get_sigdet(struct elink_phy *phy,
5222 				     struct elink_params *params)
5223 {
5224 	uint16_t gp2_status_reg0, lane;
5225 	struct bxe_softc *sc = params->sc;
5226 
5227 	lane = elink_get_warpcore_lane(phy, params);
5228 
5229 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
5230 				 &gp2_status_reg0);
5231 
5232 	return (gp2_status_reg0 >> (8+lane)) & 0x1;
5233 }
5234 
5235 static void elink_warpcore_config_runtime(struct elink_phy *phy,
5236 					  struct elink_params *params,
5237 					  struct elink_vars *vars)
5238 {
5239 	struct bxe_softc *sc = params->sc;
5240 	uint32_t serdes_net_if;
5241 	uint16_t gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
5242 
5243 	vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
5244 
5245 	if (!vars->turn_to_run_wc_rt)
5246 		return;
5247 
5248 	if (vars->rx_tx_asic_rst) {
5249 		uint16_t lane = elink_get_warpcore_lane(phy, params);
5250 		serdes_net_if = (REG_RD(sc, params->shmem_base +
5251 				offsetof(struct shmem_region, dev_info.
5252 				port_hw_config[params->port].default_cfg)) &
5253 				PORT_HW_CFG_NET_SERDES_IF_MASK);
5254 
5255 		switch (serdes_net_if) {
5256 		case PORT_HW_CFG_NET_SERDES_IF_KR:
5257 			/* Do we get link yet? */
5258 			elink_cl45_read(sc, phy, MDIO_WC_DEVAD, 0x81d1,
5259 					&gp_status1);
5260 			lnkup = (gp_status1 >> (8+lane)) & 0x1;/* 1G */
5261 				/*10G KR*/
5262 			lnkup_kr = (gp_status1 >> (12+lane)) & 0x1;
5263 
5264 			if (lnkup_kr || lnkup) {
5265 				vars->rx_tx_asic_rst = 0;
5266 			} else {
5267 				/* Reset the lane to see if link comes up.*/
5268 				elink_warpcore_reset_lane(sc, phy, 1);
5269 				elink_warpcore_reset_lane(sc, phy, 0);
5270 
5271 				/* Restart Autoneg */
5272 				elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
5273 					MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
5274 
5275 				vars->rx_tx_asic_rst--;
5276 				ELINK_DEBUG_P1(sc, "0x%x retry left\n",
5277 				vars->rx_tx_asic_rst);
5278 			}
5279 			break;
5280 
5281 		default:
5282 			break;
5283 		}
5284 
5285 	} /*params->rx_tx_asic_rst*/
5286 
5287 }
5288 static void elink_warpcore_config_sfi(struct elink_phy *phy,
5289 				      struct elink_params *params)
5290 {
5291 	uint16_t lane = elink_get_warpcore_lane(phy, params);
5292 	struct bxe_softc *sc = params->sc;
5293 	elink_warpcore_clear_regs(phy, params, lane);
5294 	if ((params->req_line_speed[ELINK_LINK_CONFIG_IDX(ELINK_INT_PHY)] ==
5295 	     ELINK_SPEED_10000) &&
5296 	    (phy->media_type != ELINK_ETH_PHY_SFP_1G_FIBER)) {
5297 		ELINK_DEBUG_P0(sc, "Setting 10G SFI\n");
5298 		elink_warpcore_set_10G_XFI(phy, params, 0);
5299 	} else {
5300 		ELINK_DEBUG_P0(sc, "Setting 1G Fiber\n");
5301 		elink_warpcore_set_sgmii_speed(phy, params, 1, 0);
5302 	}
5303 }
5304 
5305 static void elink_sfp_e3_set_transmitter(struct elink_params *params,
5306 					 struct elink_phy *phy,
5307 					 uint8_t tx_en)
5308 {
5309 	struct bxe_softc *sc = params->sc;
5310 	uint32_t cfg_pin;
5311 	uint8_t port = params->port;
5312 
5313 	cfg_pin = REG_RD(sc, params->shmem_base +
5314 			 offsetof(struct shmem_region,
5315 				  dev_info.port_hw_config[port].e3_sfp_ctrl)) &
5316 		PORT_HW_CFG_E3_TX_LASER_MASK;
5317 	/* Set the !tx_en since this pin is DISABLE_TX_LASER */
5318 	ELINK_DEBUG_P1(sc, "Setting WC TX to %d\n", tx_en);
5319 
5320 	/* For 20G, the expected pin to be used is 3 pins after the current */
5321 	elink_set_cfg_pin(sc, cfg_pin, tx_en ^ 1);
5322 	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
5323 		elink_set_cfg_pin(sc, cfg_pin + 3, tx_en ^ 1);
5324 }
5325 
5326 static void elink_warpcore_config_init(struct elink_phy *phy,
5327 				       struct elink_params *params,
5328 				       struct elink_vars *vars)
5329 {
5330 	struct bxe_softc *sc = params->sc;
5331 	uint32_t serdes_net_if;
5332 	uint8_t fiber_mode;
5333 	uint16_t lane = elink_get_warpcore_lane(phy, params);
5334 	serdes_net_if = (REG_RD(sc, params->shmem_base +
5335 			 offsetof(struct shmem_region, dev_info.
5336 				  port_hw_config[params->port].default_cfg)) &
5337 			 PORT_HW_CFG_NET_SERDES_IF_MASK);
5338 	ELINK_DEBUG_P2(sc, "Begin Warpcore init, link_speed %d, "
5339 			   "serdes_net_if = 0x%x\n",
5340 		       vars->line_speed, serdes_net_if);
5341 	elink_set_aer_mmd(params, phy);
5342 	elink_warpcore_reset_lane(sc, phy, 1);
5343 	vars->phy_flags |= PHY_XGXS_FLAG;
5344 	if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
5345 	    (phy->req_line_speed &&
5346 	     ((phy->req_line_speed == ELINK_SPEED_100) ||
5347 	      (phy->req_line_speed == ELINK_SPEED_10)))) {
5348 		vars->phy_flags |= PHY_SGMII_FLAG;
5349 		ELINK_DEBUG_P0(sc, "Setting SGMII mode\n");
5350 		elink_warpcore_clear_regs(phy, params, lane);
5351 		elink_warpcore_set_sgmii_speed(phy, params, 0, 1);
5352 	} else {
5353 		switch (serdes_net_if) {
5354 		case PORT_HW_CFG_NET_SERDES_IF_KR:
5355 			/* Enable KR Auto Neg */
5356 			if (params->loopback_mode != ELINK_LOOPBACK_EXT)
5357 				elink_warpcore_enable_AN_KR(phy, params, vars);
5358 			else {
5359 				ELINK_DEBUG_P0(sc, "Setting KR 10G-Force\n");
5360 				elink_warpcore_set_10G_KR(phy, params, vars);
5361 			}
5362 			break;
5363 
5364 		case PORT_HW_CFG_NET_SERDES_IF_XFI:
5365 			elink_warpcore_clear_regs(phy, params, lane);
5366 			if (vars->line_speed == ELINK_SPEED_10000) {
5367 				ELINK_DEBUG_P0(sc, "Setting 10G XFI\n");
5368 				elink_warpcore_set_10G_XFI(phy, params, 1);
5369 			} else {
5370 				if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
5371 					ELINK_DEBUG_P0(sc, "1G Fiber\n");
5372 					fiber_mode = 1;
5373 				} else {
5374 					ELINK_DEBUG_P0(sc, "10/100/1G SGMII\n");
5375 					fiber_mode = 0;
5376 				}
5377 				elink_warpcore_set_sgmii_speed(phy,
5378 								params,
5379 								fiber_mode,
5380 								0);
5381 			}
5382 
5383 			break;
5384 
5385 		case PORT_HW_CFG_NET_SERDES_IF_SFI:
5386 			/* Issue Module detection if module is plugged, or
5387 			 * enabled transmitter to avoid current leakage in case
5388 			 * no module is connected
5389 			 */
5390 			if ((params->loopback_mode == ELINK_LOOPBACK_NONE) ||
5391 			    (params->loopback_mode == ELINK_LOOPBACK_EXT)) {
5392 				if (elink_is_sfp_module_plugged(phy, params))
5393 					elink_sfp_module_detection(phy, params);
5394 				else
5395 					elink_sfp_e3_set_transmitter(params,
5396 								     phy, 1);
5397 			}
5398 
5399 			elink_warpcore_config_sfi(phy, params);
5400 			break;
5401 
5402 		case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
5403 			if (vars->line_speed != ELINK_SPEED_20000) {
5404 				ELINK_DEBUG_P0(sc, "Speed not supported yet\n");
5405 				return;
5406 			}
5407 			ELINK_DEBUG_P0(sc, "Setting 20G DXGXS\n");
5408 			elink_warpcore_set_20G_DXGXS(sc, phy, lane);
5409 			/* Issue Module detection */
5410 
5411 			elink_sfp_module_detection(phy, params);
5412 			break;
5413 		case PORT_HW_CFG_NET_SERDES_IF_KR2:
5414 			if (!params->loopback_mode) {
5415 				elink_warpcore_enable_AN_KR(phy, params, vars);
5416 			} else {
5417 				ELINK_DEBUG_P0(sc, "Setting KR 20G-Force\n");
5418 				elink_warpcore_set_20G_force_KR2(phy, params);
5419 			}
5420 			break;
5421 		default:
5422 			ELINK_DEBUG_P1(sc,
5423 			   "Unsupported Serdes Net Interface 0x%x\n",
5424 			   serdes_net_if);
5425 			return;
5426 		}
5427 	}
5428 
5429 	/* Take lane out of reset after configuration is finished */
5430 	elink_warpcore_reset_lane(sc, phy, 0);
5431 	ELINK_DEBUG_P0(sc, "Exit config init\n");
5432 }
5433 
5434 static void elink_warpcore_link_reset(struct elink_phy *phy,
5435 				      struct elink_params *params)
5436 {
5437 	struct bxe_softc *sc = params->sc;
5438 	uint16_t val16, lane;
5439 	elink_sfp_e3_set_transmitter(params, phy, 0);
5440 	elink_set_mdio_emac_per_phy(sc, params);
5441 	elink_set_aer_mmd(params, phy);
5442 	/* Global register */
5443 	elink_warpcore_reset_lane(sc, phy, 1);
5444 
5445 	/* Clear loopback settings (if any) */
5446 	/* 10G & 20G */
5447 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5448 				  MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0xBFFF);
5449 
5450 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5451 				  MDIO_WC_REG_IEEE0BLK_MIICNTL, 0xfffe);
5452 
5453 	/* Update those 1-copy registers */
5454 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
5455 			  MDIO_AER_BLOCK_AER_REG, 0);
5456 	/* Enable 1G MDIO (1-copy) */
5457 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5458 				  MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
5459 				  ~0x10);
5460 
5461 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5462 				  MDIO_WC_REG_XGXSBLK1_LANECTRL2, 0xff00);
5463 	lane = elink_get_warpcore_lane(phy, params);
5464 	/* Disable CL36 PCS Tx */
5465 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5466 			MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
5467 	val16 |= (0x11 << lane);
5468 	if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
5469 		val16 |= (0x22 << lane);
5470 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5471 			 MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
5472 
5473 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5474 			MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
5475 	val16 &= ~(0x0303 << (lane << 1));
5476 	val16 |= (0x0101 << (lane << 1));
5477 	if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE) {
5478 		val16 &= ~(0x0c0c << (lane << 1));
5479 		val16 |= (0x0404 << (lane << 1));
5480 	}
5481 
5482 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5483 			 MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
5484 	/* Restore AER */
5485 	elink_set_aer_mmd(params, phy);
5486 
5487 }
5488 
5489 static void elink_set_warpcore_loopback(struct elink_phy *phy,
5490 					struct elink_params *params)
5491 {
5492 	struct bxe_softc *sc = params->sc;
5493 	uint16_t val16;
5494 	uint32_t lane;
5495 	ELINK_DEBUG_P2(sc, "Setting Warpcore loopback type %x, speed %d\n",
5496 		       params->loopback_mode, phy->req_line_speed);
5497 
5498 	if (phy->req_line_speed < ELINK_SPEED_10000 ||
5499 	    phy->supported & ELINK_SUPPORTED_20000baseKR2_Full) {
5500 		/* 10/100/1000/20G-KR2 */
5501 
5502 		/* Update those 1-copy registers */
5503 		CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
5504 				  MDIO_AER_BLOCK_AER_REG, 0);
5505 		/* Enable 1G MDIO (1-copy) */
5506 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5507 					 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
5508 					 0x10);
5509 		/* Set 1G loopback based on lane (1-copy) */
5510 		lane = elink_get_warpcore_lane(phy, params);
5511 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5512 				MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
5513 		val16 |= (1<<lane);
5514 		if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
5515 			val16 |= (2<<lane);
5516 		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5517 				 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
5518 				 val16);
5519 
5520 		/* Switch back to 4-copy registers */
5521 		elink_set_aer_mmd(params, phy);
5522 	} else {
5523 		/* 10G / 20G-DXGXS */
5524 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5525 					 MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
5526 					 0x4000);
5527 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5528 					 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1);
5529 	}
5530 }
5531 
5532 
5533 
5534 static void elink_sync_link(struct elink_params *params,
5535 			     struct elink_vars *vars)
5536 {
5537 	struct bxe_softc *sc = params->sc;
5538 	uint8_t link_10g_plus;
5539 	if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
5540 		vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
5541 	vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
5542 	if (vars->link_up) {
5543 		ELINK_DEBUG_P0(sc, "phy link up\n");
5544 		ELINK_DEBUG_P1(sc, "link status = %x\n", vars->link_status);
5545 
5546 		vars->phy_link_up = 1;
5547 		vars->duplex = DUPLEX_FULL;
5548 		switch (vars->link_status &
5549 			LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
5550 		case ELINK_LINK_10THD:
5551 			vars->duplex = DUPLEX_HALF;
5552 			/* Fall thru */
5553 		case ELINK_LINK_10TFD:
5554 			vars->line_speed = ELINK_SPEED_10;
5555 			break;
5556 
5557 		case ELINK_LINK_100TXHD:
5558 			vars->duplex = DUPLEX_HALF;
5559 			/* Fall thru */
5560 		case ELINK_LINK_100T4:
5561 		case ELINK_LINK_100TXFD:
5562 			vars->line_speed = ELINK_SPEED_100;
5563 			break;
5564 
5565 		case ELINK_LINK_1000THD:
5566 			vars->duplex = DUPLEX_HALF;
5567 			/* Fall thru */
5568 		case ELINK_LINK_1000TFD:
5569 			vars->line_speed = ELINK_SPEED_1000;
5570 			break;
5571 
5572 		case ELINK_LINK_2500THD:
5573 			vars->duplex = DUPLEX_HALF;
5574 			/* Fall thru */
5575 		case ELINK_LINK_2500TFD:
5576 			vars->line_speed = ELINK_SPEED_2500;
5577 			break;
5578 
5579 		case ELINK_LINK_10GTFD:
5580 			vars->line_speed = ELINK_SPEED_10000;
5581 			break;
5582 		case ELINK_LINK_20GTFD:
5583 			vars->line_speed = ELINK_SPEED_20000;
5584 			break;
5585 		default:
5586 			break;
5587 		}
5588 		vars->flow_ctrl = 0;
5589 		if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
5590 			vars->flow_ctrl |= ELINK_FLOW_CTRL_TX;
5591 
5592 		if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
5593 			vars->flow_ctrl |= ELINK_FLOW_CTRL_RX;
5594 
5595 		if (!vars->flow_ctrl)
5596 			vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
5597 
5598 		if (vars->line_speed &&
5599 		    ((vars->line_speed == ELINK_SPEED_10) ||
5600 		     (vars->line_speed == ELINK_SPEED_100))) {
5601 			vars->phy_flags |= PHY_SGMII_FLAG;
5602 		} else {
5603 			vars->phy_flags &= ~PHY_SGMII_FLAG;
5604 		}
5605 		if (vars->line_speed &&
5606 		    USES_WARPCORE(sc) &&
5607 		    (vars->line_speed == ELINK_SPEED_1000))
5608 			vars->phy_flags |= PHY_SGMII_FLAG;
5609 		/* Anything 10 and over uses the bmac */
5610 		link_10g_plus = (vars->line_speed >= ELINK_SPEED_10000);
5611 
5612 		if (link_10g_plus) {
5613 			if (USES_WARPCORE(sc))
5614 				vars->mac_type = ELINK_MAC_TYPE_XMAC;
5615 			else
5616 				vars->mac_type = ELINK_MAC_TYPE_BMAC;
5617 		} else {
5618 			if (USES_WARPCORE(sc))
5619 				vars->mac_type = ELINK_MAC_TYPE_UMAC;
5620 			else
5621 				vars->mac_type = ELINK_MAC_TYPE_EMAC;
5622 		}
5623 	} else { /* Link down */
5624 		ELINK_DEBUG_P0(sc, "phy link down\n");
5625 
5626 		vars->phy_link_up = 0;
5627 
5628 		vars->line_speed = 0;
5629 		vars->duplex = DUPLEX_FULL;
5630 		vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
5631 
5632 		/* Indicate no mac active */
5633 		vars->mac_type = ELINK_MAC_TYPE_NONE;
5634 		if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
5635 			vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
5636 		if (vars->link_status & LINK_STATUS_SFP_TX_FAULT)
5637 			vars->phy_flags |= PHY_SFP_TX_FAULT_FLAG;
5638 	}
5639 }
5640 
5641 void elink_link_status_update(struct elink_params *params,
5642 			      struct elink_vars *vars)
5643 {
5644 	struct bxe_softc *sc = params->sc;
5645 	uint8_t port = params->port;
5646 	uint32_t sync_offset, media_types;
5647 	/* Update PHY configuration */
5648 	set_phy_vars(params, vars);
5649 
5650 	vars->link_status = REG_RD(sc, params->shmem_base +
5651 				   offsetof(struct shmem_region,
5652 					    port_mb[port].link_status));
5653 
5654 	/* Force link UP in non LOOPBACK_EXT loopback mode(s) */
5655 	if (params->loopback_mode != ELINK_LOOPBACK_NONE &&
5656 	    params->loopback_mode != ELINK_LOOPBACK_EXT)
5657 		vars->link_status |= LINK_STATUS_LINK_UP;
5658 
5659 	if (elink_eee_has_cap(params))
5660 		vars->eee_status = REG_RD(sc, params->shmem2_base +
5661 					  offsetof(struct shmem2_region,
5662 						   eee_status[params->port]));
5663 
5664 	vars->phy_flags = PHY_XGXS_FLAG;
5665 	elink_sync_link(params, vars);
5666 	/* Sync media type */
5667 	sync_offset = params->shmem_base +
5668 			offsetof(struct shmem_region,
5669 				 dev_info.port_hw_config[port].media_type);
5670 	media_types = REG_RD(sc, sync_offset);
5671 
5672 	params->phy[ELINK_INT_PHY].media_type =
5673 		(media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
5674 		PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
5675 	params->phy[ELINK_EXT_PHY1].media_type =
5676 		(media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
5677 		PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
5678 	params->phy[ELINK_EXT_PHY2].media_type =
5679 		(media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
5680 		PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
5681 	ELINK_DEBUG_P1(sc, "media_types = 0x%x\n", media_types);
5682 
5683 	/* Sync AEU offset */
5684 	sync_offset = params->shmem_base +
5685 			offsetof(struct shmem_region,
5686 				 dev_info.port_hw_config[port].aeu_int_mask);
5687 
5688 	vars->aeu_int_mask = REG_RD(sc, sync_offset);
5689 
5690 	/* Sync PFC status */
5691 	if (vars->link_status & LINK_STATUS_PFC_ENABLED)
5692 		params->feature_config_flags |=
5693 					ELINK_FEATURE_CONFIG_PFC_ENABLED;
5694 	else
5695 		params->feature_config_flags &=
5696 					~ELINK_FEATURE_CONFIG_PFC_ENABLED;
5697 
5698 	if (SHMEM2_HAS(sc, link_attr_sync))
5699 		params->link_attr_sync = SHMEM2_RD(sc,
5700 						 link_attr_sync[params->port]);
5701 
5702 	ELINK_DEBUG_P3(sc, "link_status 0x%x  phy_link_up %x int_mask 0x%x\n",
5703 		 vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
5704 	ELINK_DEBUG_P3(sc, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
5705 		 vars->line_speed, vars->duplex, vars->flow_ctrl);
5706 }
5707 
5708 static void elink_set_master_ln(struct elink_params *params,
5709 				struct elink_phy *phy)
5710 {
5711 	struct bxe_softc *sc = params->sc;
5712 	uint16_t new_master_ln, ser_lane;
5713 	ser_lane = ((params->lane_config &
5714 		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5715 		    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5716 
5717 	/* Set the master_ln for AN */
5718 	CL22_RD_OVER_CL45(sc, phy,
5719 			  MDIO_REG_BANK_XGXS_BLOCK2,
5720 			  MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
5721 			  &new_master_ln);
5722 
5723 	CL22_WR_OVER_CL45(sc, phy,
5724 			  MDIO_REG_BANK_XGXS_BLOCK2 ,
5725 			  MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
5726 			  (new_master_ln | ser_lane));
5727 }
5728 
5729 static elink_status_t elink_reset_unicore(struct elink_params *params,
5730 			       struct elink_phy *phy,
5731 			       uint8_t set_serdes)
5732 {
5733 	struct bxe_softc *sc = params->sc;
5734 	uint16_t mii_control;
5735 	uint16_t i;
5736 	CL22_RD_OVER_CL45(sc, phy,
5737 			  MDIO_REG_BANK_COMBO_IEEE0,
5738 			  MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
5739 
5740 	/* Reset the unicore */
5741 	CL22_WR_OVER_CL45(sc, phy,
5742 			  MDIO_REG_BANK_COMBO_IEEE0,
5743 			  MDIO_COMBO_IEEE0_MII_CONTROL,
5744 			  (mii_control |
5745 			   MDIO_COMBO_IEEO_MII_CONTROL_RESET));
5746 	if (set_serdes)
5747 		elink_set_serdes_access(sc, params->port);
5748 
5749 	/* Wait for the reset to self clear */
5750 	for (i = 0; i < ELINK_MDIO_ACCESS_TIMEOUT; i++) {
5751 		DELAY(5);
5752 
5753 		/* The reset erased the previous bank value */
5754 		CL22_RD_OVER_CL45(sc, phy,
5755 				  MDIO_REG_BANK_COMBO_IEEE0,
5756 				  MDIO_COMBO_IEEE0_MII_CONTROL,
5757 				  &mii_control);
5758 
5759 		if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
5760 			DELAY(5);
5761 			return ELINK_STATUS_OK;
5762 		}
5763 	}
5764 
5765 	elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED, params->port); // "Warning: PHY was not initialized,"
5766 			     // " Port %d\n",
5767 
5768 	ELINK_DEBUG_P0(sc, "BUG! XGXS is still in reset!\n");
5769 	return ELINK_STATUS_ERROR;
5770 
5771 }
5772 
5773 static void elink_set_swap_lanes(struct elink_params *params,
5774 				 struct elink_phy *phy)
5775 {
5776 	struct bxe_softc *sc = params->sc;
5777 	/* Each two bits represents a lane number:
5778 	 * No swap is 0123 => 0x1b no need to enable the swap
5779 	 */
5780 	uint16_t rx_lane_swap, tx_lane_swap;
5781 
5782 	rx_lane_swap = ((params->lane_config &
5783 			 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
5784 			PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
5785 	tx_lane_swap = ((params->lane_config &
5786 			 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
5787 			PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
5788 
5789 	if (rx_lane_swap != 0x1b) {
5790 		CL22_WR_OVER_CL45(sc, phy,
5791 				  MDIO_REG_BANK_XGXS_BLOCK2,
5792 				  MDIO_XGXS_BLOCK2_RX_LN_SWAP,
5793 				  (rx_lane_swap |
5794 				   MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
5795 				   MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
5796 	} else {
5797 		CL22_WR_OVER_CL45(sc, phy,
5798 				  MDIO_REG_BANK_XGXS_BLOCK2,
5799 				  MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
5800 	}
5801 
5802 	if (tx_lane_swap != 0x1b) {
5803 		CL22_WR_OVER_CL45(sc, phy,
5804 				  MDIO_REG_BANK_XGXS_BLOCK2,
5805 				  MDIO_XGXS_BLOCK2_TX_LN_SWAP,
5806 				  (tx_lane_swap |
5807 				   MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
5808 	} else {
5809 		CL22_WR_OVER_CL45(sc, phy,
5810 				  MDIO_REG_BANK_XGXS_BLOCK2,
5811 				  MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
5812 	}
5813 }
5814 
5815 static void elink_set_parallel_detection(struct elink_phy *phy,
5816 					 struct elink_params *params)
5817 {
5818 	struct bxe_softc *sc = params->sc;
5819 	uint16_t control2;
5820 	CL22_RD_OVER_CL45(sc, phy,
5821 			  MDIO_REG_BANK_SERDES_DIGITAL,
5822 			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
5823 			  &control2);
5824 	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5825 		control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
5826 	else
5827 		control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
5828 	ELINK_DEBUG_P2(sc, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
5829 		phy->speed_cap_mask, control2);
5830 	CL22_WR_OVER_CL45(sc, phy,
5831 			  MDIO_REG_BANK_SERDES_DIGITAL,
5832 			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
5833 			  control2);
5834 
5835 	if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
5836 	     (phy->speed_cap_mask &
5837 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
5838 		ELINK_DEBUG_P0(sc, "XGXS\n");
5839 
5840 		CL22_WR_OVER_CL45(sc, phy,
5841 				 MDIO_REG_BANK_10G_PARALLEL_DETECT,
5842 				 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
5843 				 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
5844 
5845 		CL22_RD_OVER_CL45(sc, phy,
5846 				  MDIO_REG_BANK_10G_PARALLEL_DETECT,
5847 				  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
5848 				  &control2);
5849 
5850 
5851 		control2 |=
5852 		    MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
5853 
5854 		CL22_WR_OVER_CL45(sc, phy,
5855 				  MDIO_REG_BANK_10G_PARALLEL_DETECT,
5856 				  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
5857 				  control2);
5858 
5859 		/* Disable parallel detection of HiG */
5860 		CL22_WR_OVER_CL45(sc, phy,
5861 				  MDIO_REG_BANK_XGXS_BLOCK2,
5862 				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
5863 				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
5864 				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
5865 	}
5866 }
5867 
5868 static void elink_set_autoneg(struct elink_phy *phy,
5869 			      struct elink_params *params,
5870 			      struct elink_vars *vars,
5871 			      uint8_t enable_cl73)
5872 {
5873 	struct bxe_softc *sc = params->sc;
5874 	uint16_t reg_val;
5875 
5876 	/* CL37 Autoneg */
5877 	CL22_RD_OVER_CL45(sc, phy,
5878 			  MDIO_REG_BANK_COMBO_IEEE0,
5879 			  MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
5880 
5881 	/* CL37 Autoneg Enabled */
5882 	if (vars->line_speed == ELINK_SPEED_AUTO_NEG)
5883 		reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
5884 	else /* CL37 Autoneg Disabled */
5885 		reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5886 			     MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
5887 
5888 	CL22_WR_OVER_CL45(sc, phy,
5889 			  MDIO_REG_BANK_COMBO_IEEE0,
5890 			  MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
5891 
5892 	/* Enable/Disable Autodetection */
5893 
5894 	CL22_RD_OVER_CL45(sc, phy,
5895 			  MDIO_REG_BANK_SERDES_DIGITAL,
5896 			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
5897 	reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
5898 		    MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
5899 	reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
5900 	if (vars->line_speed == ELINK_SPEED_AUTO_NEG)
5901 		reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
5902 	else
5903 		reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
5904 
5905 	CL22_WR_OVER_CL45(sc, phy,
5906 			  MDIO_REG_BANK_SERDES_DIGITAL,
5907 			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
5908 
5909 	/* Enable TetonII and BAM autoneg */
5910 	CL22_RD_OVER_CL45(sc, phy,
5911 			  MDIO_REG_BANK_BAM_NEXT_PAGE,
5912 			  MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
5913 			  &reg_val);
5914 	if (vars->line_speed == ELINK_SPEED_AUTO_NEG) {
5915 		/* Enable BAM aneg Mode and TetonII aneg Mode */
5916 		reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
5917 			    MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
5918 	} else {
5919 		/* TetonII and BAM Autoneg Disabled */
5920 		reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
5921 			     MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
5922 	}
5923 	CL22_WR_OVER_CL45(sc, phy,
5924 			  MDIO_REG_BANK_BAM_NEXT_PAGE,
5925 			  MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
5926 			  reg_val);
5927 
5928 	if (enable_cl73) {
5929 		/* Enable Cl73 FSM status bits */
5930 		CL22_WR_OVER_CL45(sc, phy,
5931 				  MDIO_REG_BANK_CL73_USERB0,
5932 				  MDIO_CL73_USERB0_CL73_UCTRL,
5933 				  0xe);
5934 
5935 		/* Enable BAM Station Manager*/
5936 		CL22_WR_OVER_CL45(sc, phy,
5937 			MDIO_REG_BANK_CL73_USERB0,
5938 			MDIO_CL73_USERB0_CL73_BAM_CTRL1,
5939 			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
5940 			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
5941 			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
5942 
5943 		/* Advertise CL73 link speeds */
5944 		CL22_RD_OVER_CL45(sc, phy,
5945 				  MDIO_REG_BANK_CL73_IEEEB1,
5946 				  MDIO_CL73_IEEEB1_AN_ADV2,
5947 				  &reg_val);
5948 		if (phy->speed_cap_mask &
5949 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
5950 			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
5951 		if (phy->speed_cap_mask &
5952 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5953 			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
5954 
5955 		CL22_WR_OVER_CL45(sc, phy,
5956 				  MDIO_REG_BANK_CL73_IEEEB1,
5957 				  MDIO_CL73_IEEEB1_AN_ADV2,
5958 				  reg_val);
5959 
5960 		/* CL73 Autoneg Enabled */
5961 		reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
5962 
5963 	} else /* CL73 Autoneg Disabled */
5964 		reg_val = 0;
5965 
5966 	CL22_WR_OVER_CL45(sc, phy,
5967 			  MDIO_REG_BANK_CL73_IEEEB0,
5968 			  MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
5969 }
5970 
5971 /* Program SerDes, forced speed */
5972 static void elink_program_serdes(struct elink_phy *phy,
5973 				 struct elink_params *params,
5974 				 struct elink_vars *vars)
5975 {
5976 	struct bxe_softc *sc = params->sc;
5977 	uint16_t reg_val;
5978 
5979 	/* Program duplex, disable autoneg and sgmii*/
5980 	CL22_RD_OVER_CL45(sc, phy,
5981 			  MDIO_REG_BANK_COMBO_IEEE0,
5982 			  MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
5983 	reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
5984 		     MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5985 		     MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
5986 	if (phy->req_duplex == DUPLEX_FULL)
5987 		reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
5988 	CL22_WR_OVER_CL45(sc, phy,
5989 			  MDIO_REG_BANK_COMBO_IEEE0,
5990 			  MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
5991 
5992 	/* Program speed
5993 	 *  - needed only if the speed is greater than 1G (2.5G or 10G)
5994 	 */
5995 	CL22_RD_OVER_CL45(sc, phy,
5996 			  MDIO_REG_BANK_SERDES_DIGITAL,
5997 			  MDIO_SERDES_DIGITAL_MISC1, &reg_val);
5998 	/* Clearing the speed value before setting the right speed */
5999 	ELINK_DEBUG_P1(sc, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
6000 
6001 	reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
6002 		     MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
6003 
6004 	if (!((vars->line_speed == ELINK_SPEED_1000) ||
6005 	      (vars->line_speed == ELINK_SPEED_100) ||
6006 	      (vars->line_speed == ELINK_SPEED_10))) {
6007 
6008 		reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
6009 			    MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
6010 		if (vars->line_speed == ELINK_SPEED_10000)
6011 			reg_val |=
6012 				MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
6013 	}
6014 
6015 	CL22_WR_OVER_CL45(sc, phy,
6016 			  MDIO_REG_BANK_SERDES_DIGITAL,
6017 			  MDIO_SERDES_DIGITAL_MISC1, reg_val);
6018 
6019 }
6020 
6021 static void elink_set_brcm_cl37_advertisement(struct elink_phy *phy,
6022 					      struct elink_params *params)
6023 {
6024 	struct bxe_softc *sc = params->sc;
6025 	uint16_t val = 0;
6026 
6027 	/* Set extended capabilities */
6028 	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
6029 		val |= MDIO_OVER_1G_UP1_2_5G;
6030 	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
6031 		val |= MDIO_OVER_1G_UP1_10G;
6032 	CL22_WR_OVER_CL45(sc, phy,
6033 			  MDIO_REG_BANK_OVER_1G,
6034 			  MDIO_OVER_1G_UP1, val);
6035 
6036 	CL22_WR_OVER_CL45(sc, phy,
6037 			  MDIO_REG_BANK_OVER_1G,
6038 			  MDIO_OVER_1G_UP3, 0x400);
6039 }
6040 
6041 static void elink_set_ieee_aneg_advertisement(struct elink_phy *phy,
6042 					      struct elink_params *params,
6043 					      uint16_t ieee_fc)
6044 {
6045 	struct bxe_softc *sc = params->sc;
6046 	uint16_t val;
6047 	/* For AN, we are always publishing full duplex */
6048 
6049 	CL22_WR_OVER_CL45(sc, phy,
6050 			  MDIO_REG_BANK_COMBO_IEEE0,
6051 			  MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
6052 	CL22_RD_OVER_CL45(sc, phy,
6053 			  MDIO_REG_BANK_CL73_IEEEB1,
6054 			  MDIO_CL73_IEEEB1_AN_ADV1, &val);
6055 	val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
6056 	val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
6057 	CL22_WR_OVER_CL45(sc, phy,
6058 			  MDIO_REG_BANK_CL73_IEEEB1,
6059 			  MDIO_CL73_IEEEB1_AN_ADV1, val);
6060 }
6061 
6062 static void elink_restart_autoneg(struct elink_phy *phy,
6063 				  struct elink_params *params,
6064 				  uint8_t enable_cl73)
6065 {
6066 	struct bxe_softc *sc = params->sc;
6067 	uint16_t mii_control;
6068 
6069 	ELINK_DEBUG_P0(sc, "elink_restart_autoneg\n");
6070 	/* Enable and restart BAM/CL37 aneg */
6071 
6072 	if (enable_cl73) {
6073 		CL22_RD_OVER_CL45(sc, phy,
6074 				  MDIO_REG_BANK_CL73_IEEEB0,
6075 				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6076 				  &mii_control);
6077 
6078 		CL22_WR_OVER_CL45(sc, phy,
6079 				  MDIO_REG_BANK_CL73_IEEEB0,
6080 				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6081 				  (mii_control |
6082 				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
6083 				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
6084 	} else {
6085 
6086 		CL22_RD_OVER_CL45(sc, phy,
6087 				  MDIO_REG_BANK_COMBO_IEEE0,
6088 				  MDIO_COMBO_IEEE0_MII_CONTROL,
6089 				  &mii_control);
6090 		ELINK_DEBUG_P1(sc,
6091 			 "elink_restart_autoneg mii_control before = 0x%x\n",
6092 			 mii_control);
6093 		CL22_WR_OVER_CL45(sc, phy,
6094 				  MDIO_REG_BANK_COMBO_IEEE0,
6095 				  MDIO_COMBO_IEEE0_MII_CONTROL,
6096 				  (mii_control |
6097 				   MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
6098 				   MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
6099 	}
6100 }
6101 
6102 static void elink_initialize_sgmii_process(struct elink_phy *phy,
6103 					   struct elink_params *params,
6104 					   struct elink_vars *vars)
6105 {
6106 	struct bxe_softc *sc = params->sc;
6107 	uint16_t control1;
6108 
6109 	/* In SGMII mode, the unicore is always slave */
6110 
6111 	CL22_RD_OVER_CL45(sc, phy,
6112 			  MDIO_REG_BANK_SERDES_DIGITAL,
6113 			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
6114 			  &control1);
6115 	control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
6116 	/* Set sgmii mode (and not fiber) */
6117 	control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
6118 		      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
6119 		      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
6120 	CL22_WR_OVER_CL45(sc, phy,
6121 			  MDIO_REG_BANK_SERDES_DIGITAL,
6122 			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
6123 			  control1);
6124 
6125 	/* If forced speed */
6126 	if (!(vars->line_speed == ELINK_SPEED_AUTO_NEG)) {
6127 		/* Set speed, disable autoneg */
6128 		uint16_t mii_control;
6129 
6130 		CL22_RD_OVER_CL45(sc, phy,
6131 				  MDIO_REG_BANK_COMBO_IEEE0,
6132 				  MDIO_COMBO_IEEE0_MII_CONTROL,
6133 				  &mii_control);
6134 		mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
6135 				 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
6136 				 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
6137 
6138 		switch (vars->line_speed) {
6139 		case ELINK_SPEED_100:
6140 			mii_control |=
6141 				MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
6142 			break;
6143 		case ELINK_SPEED_1000:
6144 			mii_control |=
6145 				MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
6146 			break;
6147 		case ELINK_SPEED_10:
6148 			/* There is nothing to set for 10M */
6149 			break;
6150 		default:
6151 			/* Invalid speed for SGMII */
6152 			ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x\n",
6153 				  vars->line_speed);
6154 			break;
6155 		}
6156 
6157 		/* Setting the full duplex */
6158 		if (phy->req_duplex == DUPLEX_FULL)
6159 			mii_control |=
6160 				MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
6161 		CL22_WR_OVER_CL45(sc, phy,
6162 				  MDIO_REG_BANK_COMBO_IEEE0,
6163 				  MDIO_COMBO_IEEE0_MII_CONTROL,
6164 				  mii_control);
6165 
6166 	} else { /* AN mode */
6167 		/* Enable and restart AN */
6168 		elink_restart_autoneg(phy, params, 0);
6169 	}
6170 }
6171 
6172 /* Link management
6173  */
6174 static elink_status_t elink_direct_parallel_detect_used(struct elink_phy *phy,
6175 					     struct elink_params *params)
6176 {
6177 	struct bxe_softc *sc = params->sc;
6178 	uint16_t pd_10g, status2_1000x;
6179 	if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
6180 		return ELINK_STATUS_OK;
6181 	CL22_RD_OVER_CL45(sc, phy,
6182 			  MDIO_REG_BANK_SERDES_DIGITAL,
6183 			  MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
6184 			  &status2_1000x);
6185 	CL22_RD_OVER_CL45(sc, phy,
6186 			  MDIO_REG_BANK_SERDES_DIGITAL,
6187 			  MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
6188 			  &status2_1000x);
6189 	if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
6190 		ELINK_DEBUG_P1(sc, "1G parallel detect link on port %d\n",
6191 			 params->port);
6192 		return 1;
6193 	}
6194 
6195 	CL22_RD_OVER_CL45(sc, phy,
6196 			  MDIO_REG_BANK_10G_PARALLEL_DETECT,
6197 			  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
6198 			  &pd_10g);
6199 
6200 	if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
6201 		ELINK_DEBUG_P1(sc, "10G parallel detect link on port %d\n",
6202 			 params->port);
6203 		return 1;
6204 	}
6205 	return ELINK_STATUS_OK;
6206 }
6207 
6208 static void elink_update_adv_fc(struct elink_phy *phy,
6209 				struct elink_params *params,
6210 				struct elink_vars *vars,
6211 				uint32_t gp_status)
6212 {
6213 	uint16_t ld_pause;   /* local driver */
6214 	uint16_t lp_pause;   /* link partner */
6215 	uint16_t pause_result;
6216 	struct bxe_softc *sc = params->sc;
6217 	if ((gp_status &
6218 	     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
6219 	      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
6220 	    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
6221 	     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
6222 
6223 		CL22_RD_OVER_CL45(sc, phy,
6224 				  MDIO_REG_BANK_CL73_IEEEB1,
6225 				  MDIO_CL73_IEEEB1_AN_ADV1,
6226 				  &ld_pause);
6227 		CL22_RD_OVER_CL45(sc, phy,
6228 				  MDIO_REG_BANK_CL73_IEEEB1,
6229 				  MDIO_CL73_IEEEB1_AN_LP_ADV1,
6230 				  &lp_pause);
6231 		pause_result = (ld_pause &
6232 				MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) >> 8;
6233 		pause_result |= (lp_pause &
6234 				 MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK) >> 10;
6235 		ELINK_DEBUG_P1(sc, "pause_result CL73 0x%x\n", pause_result);
6236 	} else {
6237 		CL22_RD_OVER_CL45(sc, phy,
6238 				  MDIO_REG_BANK_COMBO_IEEE0,
6239 				  MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
6240 				  &ld_pause);
6241 		CL22_RD_OVER_CL45(sc, phy,
6242 			MDIO_REG_BANK_COMBO_IEEE0,
6243 			MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
6244 			&lp_pause);
6245 		pause_result = (ld_pause &
6246 				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
6247 		pause_result |= (lp_pause &
6248 				 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
6249 		ELINK_DEBUG_P1(sc, "pause_result CL37 0x%x\n", pause_result);
6250 	}
6251 	elink_pause_resolve(phy, params, vars, pause_result);
6252 
6253 }
6254 
6255 static void elink_flow_ctrl_resolve(struct elink_phy *phy,
6256 				    struct elink_params *params,
6257 				    struct elink_vars *vars,
6258 				    uint32_t gp_status)
6259 {
6260 	struct bxe_softc *sc = params->sc;
6261 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
6262 
6263 	/* Resolve from gp_status in case of AN complete and not sgmii */
6264 	if (phy->req_flow_ctrl != ELINK_FLOW_CTRL_AUTO) {
6265 		/* Update the advertised flow-controled of LD/LP in AN */
6266 		if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6267 			elink_update_adv_fc(phy, params, vars, gp_status);
6268 		/* But set the flow-control result as the requested one */
6269 		vars->flow_ctrl = phy->req_flow_ctrl;
6270 	} else if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
6271 		vars->flow_ctrl = params->req_fc_auto_adv;
6272 	else if ((gp_status & ELINK_MDIO_AN_CL73_OR_37_COMPLETE) &&
6273 		 (!(vars->phy_flags & PHY_SGMII_FLAG))) {
6274 		if (elink_direct_parallel_detect_used(phy, params)) {
6275 			vars->flow_ctrl = params->req_fc_auto_adv;
6276 			return;
6277 		}
6278 		elink_update_adv_fc(phy, params, vars, gp_status);
6279 	}
6280 	ELINK_DEBUG_P1(sc, "flow_ctrl 0x%x\n", vars->flow_ctrl);
6281 }
6282 
6283 static void elink_check_fallback_to_cl37(struct elink_phy *phy,
6284 					 struct elink_params *params)
6285 {
6286 	struct bxe_softc *sc = params->sc;
6287 	uint16_t rx_status, ustat_val, cl37_fsm_received;
6288 	ELINK_DEBUG_P0(sc, "elink_check_fallback_to_cl37\n");
6289 	/* Step 1: Make sure signal is detected */
6290 	CL22_RD_OVER_CL45(sc, phy,
6291 			  MDIO_REG_BANK_RX0,
6292 			  MDIO_RX0_RX_STATUS,
6293 			  &rx_status);
6294 	if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
6295 	    (MDIO_RX0_RX_STATUS_SIGDET)) {
6296 		ELINK_DEBUG_P1(sc, "Signal is not detected. Restoring CL73."
6297 			     "rx_status(0x80b0) = 0x%x\n", rx_status);
6298 		CL22_WR_OVER_CL45(sc, phy,
6299 				  MDIO_REG_BANK_CL73_IEEEB0,
6300 				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6301 				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
6302 		return;
6303 	}
6304 	/* Step 2: Check CL73 state machine */
6305 	CL22_RD_OVER_CL45(sc, phy,
6306 			  MDIO_REG_BANK_CL73_USERB0,
6307 			  MDIO_CL73_USERB0_CL73_USTAT1,
6308 			  &ustat_val);
6309 	if ((ustat_val &
6310 	     (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
6311 	      MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
6312 	    (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
6313 	      MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
6314 		ELINK_DEBUG_P1(sc, "CL73 state-machine is not stable. "
6315 			     "ustat_val(0x8371) = 0x%x\n", ustat_val);
6316 		return;
6317 	}
6318 	/* Step 3: Check CL37 Message Pages received to indicate LP
6319 	 * supports only CL37
6320 	 */
6321 	CL22_RD_OVER_CL45(sc, phy,
6322 			  MDIO_REG_BANK_REMOTE_PHY,
6323 			  MDIO_REMOTE_PHY_MISC_RX_STATUS,
6324 			  &cl37_fsm_received);
6325 	if ((cl37_fsm_received &
6326 	     (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
6327 	     MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
6328 	    (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
6329 	      MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
6330 		ELINK_DEBUG_P1(sc, "No CL37 FSM were received. "
6331 			     "misc_rx_status(0x8330) = 0x%x\n",
6332 			 cl37_fsm_received);
6333 		return;
6334 	}
6335 	/* The combined cl37/cl73 fsm state information indicating that
6336 	 * we are connected to a device which does not support cl73, but
6337 	 * does support cl37 BAM. In this case we disable cl73 and
6338 	 * restart cl37 auto-neg
6339 	 */
6340 
6341 	/* Disable CL73 */
6342 	CL22_WR_OVER_CL45(sc, phy,
6343 			  MDIO_REG_BANK_CL73_IEEEB0,
6344 			  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6345 			  0);
6346 	/* Restart CL37 autoneg */
6347 	elink_restart_autoneg(phy, params, 0);
6348 	ELINK_DEBUG_P0(sc, "Disabling CL73, and restarting CL37 autoneg\n");
6349 }
6350 
6351 static void elink_xgxs_an_resolve(struct elink_phy *phy,
6352 				  struct elink_params *params,
6353 				  struct elink_vars *vars,
6354 				  uint32_t gp_status)
6355 {
6356 	if (gp_status & ELINK_MDIO_AN_CL73_OR_37_COMPLETE)
6357 		vars->link_status |=
6358 			LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6359 
6360 	if (elink_direct_parallel_detect_used(phy, params))
6361 		vars->link_status |=
6362 			LINK_STATUS_PARALLEL_DETECTION_USED;
6363 }
6364 static elink_status_t elink_get_link_speed_duplex(struct elink_phy *phy,
6365 				     struct elink_params *params,
6366 				      struct elink_vars *vars,
6367 				      uint16_t is_link_up,
6368 				      uint16_t speed_mask,
6369 				      uint16_t is_duplex)
6370 {
6371 	struct bxe_softc *sc = params->sc;
6372 	if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6373 		vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
6374 	if (is_link_up) {
6375 		ELINK_DEBUG_P0(sc, "phy link up\n");
6376 
6377 		vars->phy_link_up = 1;
6378 		vars->link_status |= LINK_STATUS_LINK_UP;
6379 
6380 		switch (speed_mask) {
6381 		case ELINK_GP_STATUS_10M:
6382 			vars->line_speed = ELINK_SPEED_10;
6383 			if (is_duplex == DUPLEX_FULL)
6384 				vars->link_status |= ELINK_LINK_10TFD;
6385 			else
6386 				vars->link_status |= ELINK_LINK_10THD;
6387 			break;
6388 
6389 		case ELINK_GP_STATUS_100M:
6390 			vars->line_speed = ELINK_SPEED_100;
6391 			if (is_duplex == DUPLEX_FULL)
6392 				vars->link_status |= ELINK_LINK_100TXFD;
6393 			else
6394 				vars->link_status |= ELINK_LINK_100TXHD;
6395 			break;
6396 
6397 		case ELINK_GP_STATUS_1G:
6398 		case ELINK_GP_STATUS_1G_KX:
6399 			vars->line_speed = ELINK_SPEED_1000;
6400 			if (is_duplex == DUPLEX_FULL)
6401 				vars->link_status |= ELINK_LINK_1000TFD;
6402 			else
6403 				vars->link_status |= ELINK_LINK_1000THD;
6404 			break;
6405 
6406 		case ELINK_GP_STATUS_2_5G:
6407 			vars->line_speed = ELINK_SPEED_2500;
6408 			if (is_duplex == DUPLEX_FULL)
6409 				vars->link_status |= ELINK_LINK_2500TFD;
6410 			else
6411 				vars->link_status |= ELINK_LINK_2500THD;
6412 			break;
6413 
6414 		case ELINK_GP_STATUS_5G:
6415 		case ELINK_GP_STATUS_6G:
6416 			ELINK_DEBUG_P1(sc,
6417 				 "link speed unsupported  gp_status 0x%x\n",
6418 				  speed_mask);
6419 			return ELINK_STATUS_ERROR;
6420 
6421 		case ELINK_GP_STATUS_10G_KX4:
6422 		case ELINK_GP_STATUS_10G_HIG:
6423 		case ELINK_GP_STATUS_10G_CX4:
6424 		case ELINK_GP_STATUS_10G_KR:
6425 		case ELINK_GP_STATUS_10G_SFI:
6426 		case ELINK_GP_STATUS_10G_XFI:
6427 			vars->line_speed = ELINK_SPEED_10000;
6428 			vars->link_status |= ELINK_LINK_10GTFD;
6429 			break;
6430 		case ELINK_GP_STATUS_20G_DXGXS:
6431 		case ELINK_GP_STATUS_20G_KR2:
6432 			vars->line_speed = ELINK_SPEED_20000;
6433 			vars->link_status |= ELINK_LINK_20GTFD;
6434 			break;
6435 		default:
6436 			ELINK_DEBUG_P1(sc,
6437 				  "link speed unsupported gp_status 0x%x\n",
6438 				  speed_mask);
6439 			return ELINK_STATUS_ERROR;
6440 		}
6441 	} else { /* link_down */
6442 		ELINK_DEBUG_P0(sc, "phy link down\n");
6443 
6444 		vars->phy_link_up = 0;
6445 
6446 		vars->duplex = DUPLEX_FULL;
6447 		vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
6448 		vars->mac_type = ELINK_MAC_TYPE_NONE;
6449 	}
6450 	ELINK_DEBUG_P2(sc, " in elink_get_link_speed_duplex vars->link_status = %x, vars->duplex = %x\n",
6451 			vars->link_status, vars->duplex);
6452 	ELINK_DEBUG_P2(sc, " phy_link_up %x line_speed %d\n",
6453 		    vars->phy_link_up, vars->line_speed);
6454 	return ELINK_STATUS_OK;
6455 }
6456 
6457 static elink_status_t elink_link_settings_status(struct elink_phy *phy,
6458 				      struct elink_params *params,
6459 				      struct elink_vars *vars)
6460 {
6461 	struct bxe_softc *sc = params->sc;
6462 
6463 	uint16_t gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
6464 	elink_status_t rc = ELINK_STATUS_OK;
6465 
6466 	/* Read gp_status */
6467 	CL22_RD_OVER_CL45(sc, phy,
6468 			  MDIO_REG_BANK_GP_STATUS,
6469 			  MDIO_GP_STATUS_TOP_AN_STATUS1,
6470 			  &gp_status);
6471 	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS) {
6472 		duplex = DUPLEX_FULL;
6473 		ELINK_DEBUG_P1(sc, "duplex status read from phy is = %x\n",
6474 				duplex);
6475 	} else {
6476 		ELINK_DEBUG_P1(sc, "phy status does not allow interface to be FULL_DUPLEX : %x\n",
6477 			gp_status);
6478 	}
6479 
6480 
6481 	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
6482 		link_up = 1;
6483 	speed_mask = gp_status & ELINK_GP_STATUS_SPEED_MASK;
6484 	ELINK_DEBUG_P3(sc, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n",
6485 		       gp_status, link_up, speed_mask);
6486 	rc = elink_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
6487 					 duplex);
6488 	if (rc == ELINK_STATUS_ERROR)
6489 		return rc;
6490 
6491 	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
6492 		if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
6493 			vars->duplex = duplex;
6494 			elink_flow_ctrl_resolve(phy, params, vars, gp_status);
6495 			if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6496 				elink_xgxs_an_resolve(phy, params, vars,
6497 						      gp_status);
6498 		}
6499 	} else { /* Link_down */
6500 		if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
6501 		    ELINK_SINGLE_MEDIA_DIRECT(params)) {
6502 			/* Check signal is detected */
6503 			elink_check_fallback_to_cl37(phy, params);
6504 		}
6505 	}
6506 
6507 	/* Read LP advertised speeds*/
6508 	if (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6509 	    (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)) {
6510 		uint16_t val;
6511 
6512 		CL22_RD_OVER_CL45(sc, phy, MDIO_REG_BANK_CL73_IEEEB1,
6513 				  MDIO_CL73_IEEEB1_AN_LP_ADV2, &val);
6514 
6515 		if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
6516 			vars->link_status |=
6517 				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
6518 		if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
6519 			   MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
6520 			vars->link_status |=
6521 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6522 
6523 		CL22_RD_OVER_CL45(sc, phy, MDIO_REG_BANK_OVER_1G,
6524 				  MDIO_OVER_1G_LP_UP1, &val);
6525 
6526 		if (val & MDIO_OVER_1G_UP1_2_5G)
6527 			vars->link_status |=
6528 				LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
6529 		if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
6530 			vars->link_status |=
6531 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6532 	}
6533 
6534 	ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
6535 		   vars->duplex, vars->flow_ctrl, vars->link_status);
6536 	return rc;
6537 }
6538 
6539 static elink_status_t elink_warpcore_read_status(struct elink_phy *phy,
6540 				     struct elink_params *params,
6541 				     struct elink_vars *vars)
6542 {
6543 	struct bxe_softc *sc = params->sc;
6544 	uint8_t lane;
6545 	uint16_t gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
6546 	elink_status_t rc = ELINK_STATUS_OK;
6547 	lane = elink_get_warpcore_lane(phy, params);
6548 	/* Read gp_status */
6549 	if ((params->loopback_mode) &&
6550 	    (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)) {
6551 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6552 				MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up);
6553 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6554 				MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up);
6555 		link_up &= 0x1;
6556 		ELINK_DEBUG_P1(sc, "params->loopback_mode link_up read = %x\n",
6557 				link_up);
6558 	} else if ((phy->req_line_speed > ELINK_SPEED_10000) &&
6559 		(phy->supported & ELINK_SUPPORTED_20000baseMLD2_Full)) {
6560 		uint16_t temp_link_up;
6561 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6562 				1, &temp_link_up);
6563 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6564 				1, &link_up);
6565 		ELINK_DEBUG_P2(sc, "PCS RX link status = 0x%x-->0x%x\n",
6566 			       temp_link_up, link_up);
6567 		link_up &= (1<<2);
6568 		if (link_up)
6569 			elink_ext_phy_resolve_fc(phy, params, vars);
6570 	} else {
6571 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6572 				MDIO_WC_REG_GP2_STATUS_GP_2_1,
6573 				&gp_status1);
6574 		ELINK_DEBUG_P1(sc, "0x81d1 = 0x%x\n", gp_status1);
6575 		/* Check for either KR, 1G, or AN up. */
6576 		link_up = ((gp_status1 >> 8) |
6577 			   (gp_status1 >> 12) |
6578 			   (gp_status1)) &
6579 			(1 << lane);
6580 		if (phy->supported & ELINK_SUPPORTED_20000baseKR2_Full) {
6581 			uint16_t an_link;
6582 			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6583 					MDIO_AN_REG_STATUS, &an_link);
6584 			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6585 					MDIO_AN_REG_STATUS, &an_link);
6586 			link_up |= (an_link & (1<<2));
6587 			ELINK_DEBUG_P2(sc,"an_link = %x, link_up = %x\n", an_link,
6588 						link_up);
6589 		}
6590 		if (link_up && ELINK_SINGLE_MEDIA_DIRECT(params)) {
6591 			uint16_t pd, gp_status4;
6592 			if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
6593 				/* Check Autoneg complete */
6594 				elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6595 						MDIO_WC_REG_GP2_STATUS_GP_2_4,
6596 						&gp_status4);
6597 				if (gp_status4 & ((1<<12)<<lane))
6598 					vars->link_status |=
6599 					LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6600 
6601 				/* Check parallel detect used */
6602 				elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6603 						MDIO_WC_REG_PAR_DET_10G_STATUS,
6604 						&pd);
6605 				if (pd & (1<<15))
6606 					vars->link_status |=
6607 					LINK_STATUS_PARALLEL_DETECTION_USED;
6608 				ELINK_DEBUG_P2(sc, "pd = %x, link_status = %x\n",
6609 						pd, vars->link_status);
6610 			}
6611 			elink_ext_phy_resolve_fc(phy, params, vars);
6612 			vars->duplex = duplex;
6613 			ELINK_DEBUG_P3(sc, " ELINK_SINGLE_MEDIA_DIRECT duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
6614 					vars->duplex, vars->flow_ctrl, vars->link_status);
6615 		}
6616 	}
6617 	ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
6618 			vars->duplex, vars->flow_ctrl, vars->link_status);
6619 	if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) &&
6620 	    ELINK_SINGLE_MEDIA_DIRECT(params)) {
6621 		uint16_t val;
6622 
6623 		elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6624 				MDIO_AN_REG_LP_AUTO_NEG2, &val);
6625 
6626 		if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
6627 			vars->link_status |=
6628 				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
6629 		if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
6630 			   MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
6631 			vars->link_status |=
6632 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6633 		ELINK_DEBUG_P2(sc, "val = %x, link_status = %x\n",
6634 				val, vars->link_status);
6635 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6636 				MDIO_WC_REG_DIGITAL3_LP_UP1, &val);
6637 
6638 		if (val & MDIO_OVER_1G_UP1_2_5G)
6639 			vars->link_status |=
6640 				LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
6641 		if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
6642 			vars->link_status |=
6643 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6644 		ELINK_DEBUG_P2(sc, "val = %x, link_status = %x\n",
6645 				val, vars->link_status);
6646 
6647 	}
6648 
6649 
6650 	if (lane < 2) {
6651 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6652 				MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
6653 	} else {
6654 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6655 				MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
6656 	}
6657 	ELINK_DEBUG_P2(sc, "lane %d gp_speed 0x%x\n", lane, gp_speed);
6658 
6659 	if ((lane & 1) == 0)
6660 		gp_speed <<= 8;
6661 	gp_speed &= 0x3f00;
6662 	link_up = !!link_up;
6663 
6664 	/* Reset the TX FIFO to fix SGMII issue */
6665 	rc = elink_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
6666 					 duplex);
6667 
6668 	/* In case of KR link down, start up the recovering procedure */
6669 	if ((!link_up) && (phy->media_type == ELINK_ETH_PHY_KR) &&
6670 	    (!(phy->flags & ELINK_FLAGS_WC_DUAL_MODE)))
6671 		vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
6672 
6673 	ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
6674 		   vars->duplex, vars->flow_ctrl, vars->link_status);
6675 	return rc;
6676 }
6677 static void elink_set_gmii_tx_driver(struct elink_params *params)
6678 {
6679 	struct bxe_softc *sc = params->sc;
6680 	struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
6681 	uint16_t lp_up2;
6682 	uint16_t tx_driver;
6683 	uint16_t bank;
6684 
6685 	/* Read precomp */
6686 	CL22_RD_OVER_CL45(sc, phy,
6687 			  MDIO_REG_BANK_OVER_1G,
6688 			  MDIO_OVER_1G_LP_UP2, &lp_up2);
6689 
6690 	/* Bits [10:7] at lp_up2, positioned at [15:12] */
6691 	lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
6692 		   MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
6693 		  MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
6694 
6695 	if (lp_up2 == 0)
6696 		return;
6697 
6698 	for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
6699 	      bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
6700 		CL22_RD_OVER_CL45(sc, phy,
6701 				  bank,
6702 				  MDIO_TX0_TX_DRIVER, &tx_driver);
6703 
6704 		/* Replace tx_driver bits [15:12] */
6705 		if (lp_up2 !=
6706 		    (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
6707 			tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
6708 			tx_driver |= lp_up2;
6709 			CL22_WR_OVER_CL45(sc, phy,
6710 					  bank,
6711 					  MDIO_TX0_TX_DRIVER, tx_driver);
6712 		}
6713 	}
6714 }
6715 
6716 static elink_status_t elink_emac_program(struct elink_params *params,
6717 			      struct elink_vars *vars)
6718 {
6719 	struct bxe_softc *sc = params->sc;
6720 	uint8_t port = params->port;
6721 	uint16_t mode = 0;
6722 
6723 	ELINK_DEBUG_P0(sc, "setting link speed & duplex\n");
6724 	elink_bits_dis(sc, GRCBASE_EMAC0 + port*0x400 +
6725 		       EMAC_REG_EMAC_MODE,
6726 		       (EMAC_MODE_25G_MODE |
6727 			EMAC_MODE_PORT_MII_10M |
6728 			EMAC_MODE_HALF_DUPLEX));
6729 	switch (vars->line_speed) {
6730 	case ELINK_SPEED_10:
6731 		mode |= EMAC_MODE_PORT_MII_10M;
6732 		break;
6733 
6734 	case ELINK_SPEED_100:
6735 		mode |= EMAC_MODE_PORT_MII;
6736 		break;
6737 
6738 	case ELINK_SPEED_1000:
6739 		mode |= EMAC_MODE_PORT_GMII;
6740 		break;
6741 
6742 	case ELINK_SPEED_2500:
6743 		mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
6744 		break;
6745 
6746 	default:
6747 		/* 10G not valid for EMAC */
6748 		ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x\n",
6749 			   vars->line_speed);
6750 		return ELINK_STATUS_ERROR;
6751 	}
6752 
6753 	if (vars->duplex == DUPLEX_HALF)
6754 		mode |= EMAC_MODE_HALF_DUPLEX;
6755 	elink_bits_en(sc,
6756 		      GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
6757 		      mode);
6758 
6759 	elink_set_led(params, vars, ELINK_LED_MODE_OPER, vars->line_speed);
6760 	return ELINK_STATUS_OK;
6761 }
6762 
6763 static void elink_set_preemphasis(struct elink_phy *phy,
6764 				  struct elink_params *params)
6765 {
6766 
6767 	uint16_t bank, i = 0;
6768 	struct bxe_softc *sc = params->sc;
6769 
6770 	for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
6771 	      bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
6772 			CL22_WR_OVER_CL45(sc, phy,
6773 					  bank,
6774 					  MDIO_RX0_RX_EQ_BOOST,
6775 					  phy->rx_preemphasis[i]);
6776 	}
6777 
6778 	for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
6779 		      bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
6780 			CL22_WR_OVER_CL45(sc, phy,
6781 					  bank,
6782 					  MDIO_TX0_TX_DRIVER,
6783 					  phy->tx_preemphasis[i]);
6784 	}
6785 }
6786 
6787 static void elink_xgxs_config_init(struct elink_phy *phy,
6788 				   struct elink_params *params,
6789 				   struct elink_vars *vars)
6790 {
6791 	struct bxe_softc *sc = params->sc;
6792 	uint8_t enable_cl73 = (ELINK_SINGLE_MEDIA_DIRECT(params) ||
6793 			  (params->loopback_mode == ELINK_LOOPBACK_XGXS));
6794 	if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
6795 		if (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6796 		    (params->feature_config_flags &
6797 		     ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
6798 			elink_set_preemphasis(phy, params);
6799 
6800 		/* Forced speed requested? */
6801 		if (vars->line_speed != ELINK_SPEED_AUTO_NEG ||
6802 		    (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6803 		     params->loopback_mode == ELINK_LOOPBACK_EXT)) {
6804 			ELINK_DEBUG_P0(sc, "not SGMII, no AN\n");
6805 
6806 			/* Disable autoneg */
6807 			elink_set_autoneg(phy, params, vars, 0);
6808 
6809 			/* Program speed and duplex */
6810 			elink_program_serdes(phy, params, vars);
6811 
6812 		} else { /* AN_mode */
6813 			ELINK_DEBUG_P0(sc, "not SGMII, AN\n");
6814 
6815 			/* AN enabled */
6816 			elink_set_brcm_cl37_advertisement(phy, params);
6817 
6818 			/* Program duplex & pause advertisement (for aneg) */
6819 			elink_set_ieee_aneg_advertisement(phy, params,
6820 							  vars->ieee_fc);
6821 
6822 			/* Enable autoneg */
6823 			elink_set_autoneg(phy, params, vars, enable_cl73);
6824 
6825 			/* Enable and restart AN */
6826 			elink_restart_autoneg(phy, params, enable_cl73);
6827 		}
6828 
6829 	} else { /* SGMII mode */
6830 		ELINK_DEBUG_P0(sc, "SGMII\n");
6831 
6832 		elink_initialize_sgmii_process(phy, params, vars);
6833 	}
6834 }
6835 
6836 static elink_status_t elink_prepare_xgxs(struct elink_phy *phy,
6837 			  struct elink_params *params,
6838 			  struct elink_vars *vars)
6839 {
6840 	elink_status_t rc;
6841 	vars->phy_flags |= PHY_XGXS_FLAG;
6842 	if ((phy->req_line_speed &&
6843 	     ((phy->req_line_speed == ELINK_SPEED_100) ||
6844 	      (phy->req_line_speed == ELINK_SPEED_10))) ||
6845 	    (!phy->req_line_speed &&
6846 	     (phy->speed_cap_mask >=
6847 	      PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
6848 	     (phy->speed_cap_mask <
6849 	      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
6850 	    (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD))
6851 		vars->phy_flags |= PHY_SGMII_FLAG;
6852 	else
6853 		vars->phy_flags &= ~PHY_SGMII_FLAG;
6854 
6855 	elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
6856 	elink_set_aer_mmd(params, phy);
6857 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
6858 		elink_set_master_ln(params, phy);
6859 
6860 	rc = elink_reset_unicore(params, phy, 0);
6861 	/* Reset the SerDes and wait for reset bit return low */
6862 	if (rc != ELINK_STATUS_OK)
6863 		return rc;
6864 
6865 	elink_set_aer_mmd(params, phy);
6866 	/* Setting the masterLn_def again after the reset */
6867 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
6868 		elink_set_master_ln(params, phy);
6869 		elink_set_swap_lanes(params, phy);
6870 	}
6871 
6872 	return rc;
6873 }
6874 
6875 static uint16_t elink_wait_reset_complete(struct bxe_softc *sc,
6876 				     struct elink_phy *phy,
6877 				     struct elink_params *params)
6878 {
6879 	uint16_t cnt, ctrl;
6880 	/* Wait for soft reset to get cleared up to 1 sec */
6881 	for (cnt = 0; cnt < 1000; cnt++) {
6882 		if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
6883 			elink_cl22_read(sc, phy,
6884 				MDIO_PMA_REG_CTRL, &ctrl);
6885 		else
6886 			elink_cl45_read(sc, phy,
6887 				MDIO_PMA_DEVAD,
6888 				MDIO_PMA_REG_CTRL, &ctrl);
6889 		if (!(ctrl & (1<<15)))
6890 			break;
6891 		DELAY(1000 * 1);
6892 	}
6893 
6894 	if (cnt == 1000)
6895 		elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED, params->port); // "Warning: PHY was not initialized,"
6896 				     // " Port %d\n",
6897 
6898 	ELINK_DEBUG_P2(sc, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
6899 	return cnt;
6900 }
6901 
6902 static void elink_link_int_enable(struct elink_params *params)
6903 {
6904 	uint8_t port = params->port;
6905 	uint32_t mask;
6906 	struct bxe_softc *sc = params->sc;
6907 
6908 	/* Setting the status to report on link up for either XGXS or SerDes */
6909 	if (CHIP_IS_E3(sc)) {
6910 		mask = ELINK_NIG_MASK_XGXS0_LINK_STATUS;
6911 		if (!(ELINK_SINGLE_MEDIA_DIRECT(params)))
6912 			mask |= ELINK_NIG_MASK_MI_INT;
6913 	} else if (params->switch_cfg == ELINK_SWITCH_CFG_10G) {
6914 		mask = (ELINK_NIG_MASK_XGXS0_LINK10G |
6915 			ELINK_NIG_MASK_XGXS0_LINK_STATUS);
6916 		ELINK_DEBUG_P0(sc, "enabled XGXS interrupt\n");
6917 		if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) &&
6918 			params->phy[ELINK_INT_PHY].type !=
6919 				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
6920 			mask |= ELINK_NIG_MASK_MI_INT;
6921 			ELINK_DEBUG_P0(sc, "enabled external phy int\n");
6922 		}
6923 
6924 	} else { /* SerDes */
6925 		mask = ELINK_NIG_MASK_SERDES0_LINK_STATUS;
6926 		ELINK_DEBUG_P0(sc, "enabled SerDes interrupt\n");
6927 		if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) &&
6928 			params->phy[ELINK_INT_PHY].type !=
6929 				PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
6930 			mask |= ELINK_NIG_MASK_MI_INT;
6931 			ELINK_DEBUG_P0(sc, "enabled external phy int\n");
6932 		}
6933 	}
6934 	elink_bits_en(sc,
6935 		      NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6936 		      mask);
6937 
6938 	ELINK_DEBUG_P3(sc, "port %x, is_xgxs %x, int_status 0x%x\n", port,
6939 		 (params->switch_cfg == ELINK_SWITCH_CFG_10G),
6940 		 REG_RD(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
6941 	ELINK_DEBUG_P3(sc, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
6942 		 REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6943 		 REG_RD(sc, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
6944 		 REG_RD(sc, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
6945 	ELINK_DEBUG_P2(sc, " 10G %x, XGXS_LINK %x\n",
6946 	   REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6947 	   REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
6948 }
6949 
6950 static void elink_rearm_latch_signal(struct bxe_softc *sc, uint8_t port,
6951 				     uint8_t exp_mi_int)
6952 {
6953 	uint32_t latch_status = 0;
6954 
6955 	/* Disable the MI INT ( external phy int ) by writing 1 to the
6956 	 * status register. Link down indication is high-active-signal,
6957 	 * so in this case we need to write the status to clear the XOR
6958 	 */
6959 	/* Read Latched signals */
6960 	latch_status = REG_RD(sc,
6961 				    NIG_REG_LATCH_STATUS_0 + port*8);
6962 	ELINK_DEBUG_P1(sc, "latch_status = 0x%x\n", latch_status);
6963 	/* Handle only those with latched-signal=up.*/
6964 	if (exp_mi_int)
6965 		elink_bits_en(sc,
6966 			      NIG_REG_STATUS_INTERRUPT_PORT0
6967 			      + port*4,
6968 			      ELINK_NIG_STATUS_EMAC0_MI_INT);
6969 	else
6970 		elink_bits_dis(sc,
6971 			       NIG_REG_STATUS_INTERRUPT_PORT0
6972 			       + port*4,
6973 			       ELINK_NIG_STATUS_EMAC0_MI_INT);
6974 
6975 	if (latch_status & 1) {
6976 
6977 		/* For all latched-signal=up : Re-Arm Latch signals */
6978 		REG_WR(sc, NIG_REG_LATCH_STATUS_0 + port*8,
6979 		       (latch_status & 0xfffe) | (latch_status & 1));
6980 	}
6981 	/* For all latched-signal=up,Write original_signal to status */
6982 }
6983 
6984 static void elink_link_int_ack(struct elink_params *params,
6985 			       struct elink_vars *vars, uint8_t is_10g_plus)
6986 {
6987 	struct bxe_softc *sc = params->sc;
6988 	uint8_t port = params->port;
6989 	uint32_t mask;
6990 	/* First reset all status we assume only one line will be
6991 	 * change at a time
6992 	 */
6993 	elink_bits_dis(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
6994 		       (ELINK_NIG_STATUS_XGXS0_LINK10G |
6995 			ELINK_NIG_STATUS_XGXS0_LINK_STATUS |
6996 			ELINK_NIG_STATUS_SERDES0_LINK_STATUS));
6997 	if (vars->phy_link_up) {
6998 		if (USES_WARPCORE(sc))
6999 			mask = ELINK_NIG_STATUS_XGXS0_LINK_STATUS;
7000 		else {
7001 			if (is_10g_plus)
7002 				mask = ELINK_NIG_STATUS_XGXS0_LINK10G;
7003 			else if (params->switch_cfg == ELINK_SWITCH_CFG_10G) {
7004 				/* Disable the link interrupt by writing 1 to
7005 				 * the relevant lane in the status register
7006 				 */
7007 				uint32_t ser_lane =
7008 					((params->lane_config &
7009 				    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
7010 				    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
7011 				mask = ((1 << ser_lane) <<
7012 				       ELINK_NIG_STATUS_XGXS0_LINK_STATUS_SIZE);
7013 			} else
7014 				mask = ELINK_NIG_STATUS_SERDES0_LINK_STATUS;
7015 		}
7016 		ELINK_DEBUG_P1(sc, "Ack link up interrupt with mask 0x%x\n",
7017 			       mask);
7018 		elink_bits_en(sc,
7019 			      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
7020 			      mask);
7021 	}
7022 }
7023 
7024 static elink_status_t elink_format_ver(uint32_t num, uint8_t *str, uint16_t *len)
7025 {
7026 	uint8_t *str_ptr = str;
7027 	uint32_t mask = 0xf0000000;
7028 	uint8_t shift = 8*4;
7029 	uint8_t digit;
7030 	uint8_t remove_leading_zeros = 1;
7031 	if (*len < 10) {
7032 		/* Need more than 10chars for this format */
7033 		*str_ptr = '\0';
7034 		(*len)--;
7035 		return ELINK_STATUS_ERROR;
7036 	}
7037 	while (shift > 0) {
7038 
7039 		shift -= 4;
7040 		digit = ((num & mask) >> shift);
7041 		if (digit == 0 && remove_leading_zeros) {
7042 			mask = mask >> 4;
7043 			continue;
7044 		} else if (digit < 0xa)
7045 			*str_ptr = digit + '0';
7046 		else
7047 			*str_ptr = digit - 0xa + 'a';
7048 		remove_leading_zeros = 0;
7049 		str_ptr++;
7050 		(*len)--;
7051 		mask = mask >> 4;
7052 		if (shift == 4*4) {
7053 			*str_ptr = '.';
7054 			str_ptr++;
7055 			(*len)--;
7056 			remove_leading_zeros = 1;
7057 		}
7058 	}
7059 	return ELINK_STATUS_OK;
7060 }
7061 
7062 
7063 static elink_status_t elink_null_format_ver(uint32_t spirom_ver, uint8_t *str, uint16_t *len)
7064 {
7065 	str[0] = '\0';
7066 	(*len)--;
7067 	return ELINK_STATUS_OK;
7068 }
7069 
7070 elink_status_t elink_get_ext_phy_fw_version(struct elink_params *params, uint8_t *version,
7071 				 uint16_t len)
7072 {
7073 	struct bxe_softc *sc;
7074 	uint32_t spirom_ver = 0;
7075 	elink_status_t status = ELINK_STATUS_OK;
7076 	uint8_t *ver_p = version;
7077 	uint16_t remain_len = len;
7078 	if (version == NULL || params == NULL)
7079 		return ELINK_STATUS_ERROR;
7080 	sc = params->sc;
7081 
7082 	/* Extract first external phy*/
7083 	version[0] = '\0';
7084 	spirom_ver = REG_RD(sc, params->phy[ELINK_EXT_PHY1].ver_addr);
7085 
7086 	if (params->phy[ELINK_EXT_PHY1].format_fw_ver) {
7087 		status |= params->phy[ELINK_EXT_PHY1].format_fw_ver(spirom_ver,
7088 							      ver_p,
7089 							      &remain_len);
7090 		ver_p += (len - remain_len);
7091 	}
7092 	if ((params->num_phys == ELINK_MAX_PHYS) &&
7093 	    (params->phy[ELINK_EXT_PHY2].ver_addr != 0)) {
7094 		spirom_ver = REG_RD(sc, params->phy[ELINK_EXT_PHY2].ver_addr);
7095 		if (params->phy[ELINK_EXT_PHY2].format_fw_ver) {
7096 			*ver_p = '/';
7097 			ver_p++;
7098 			remain_len--;
7099 			status |= params->phy[ELINK_EXT_PHY2].format_fw_ver(
7100 				spirom_ver,
7101 				ver_p,
7102 				&remain_len);
7103 			ver_p = version + (len - remain_len);
7104 		}
7105 	}
7106 	*ver_p = '\0';
7107 	return status;
7108 }
7109 
7110 static void elink_set_xgxs_loopback(struct elink_phy *phy,
7111 				    struct elink_params *params)
7112 {
7113 	uint8_t port = params->port;
7114 	struct bxe_softc *sc = params->sc;
7115 
7116 	if (phy->req_line_speed != ELINK_SPEED_1000) {
7117 		uint32_t md_devad = 0;
7118 
7119 		ELINK_DEBUG_P0(sc, "XGXS 10G loopback enable\n");
7120 
7121 		if (!CHIP_IS_E3(sc)) {
7122 			/* Change the uni_phy_addr in the nig */
7123 			md_devad = REG_RD(sc, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
7124 					       port*0x18));
7125 
7126 			REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
7127 			       0x5);
7128 		}
7129 
7130 		elink_cl45_write(sc, phy,
7131 				 5,
7132 				 (MDIO_REG_BANK_AER_BLOCK +
7133 				  (MDIO_AER_BLOCK_AER_REG & 0xf)),
7134 				 0x2800);
7135 
7136 		elink_cl45_write(sc, phy,
7137 				 5,
7138 				 (MDIO_REG_BANK_CL73_IEEEB0 +
7139 				  (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
7140 				 0x6041);
7141 		DELAY(1000 * 200);
7142 		/* Set aer mmd back */
7143 		elink_set_aer_mmd(params, phy);
7144 
7145 		if (!CHIP_IS_E3(sc)) {
7146 			/* And md_devad */
7147 			REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
7148 			       md_devad);
7149 		}
7150 	} else {
7151 		uint16_t mii_ctrl;
7152 		ELINK_DEBUG_P0(sc, "XGXS 1G loopback enable\n");
7153 		elink_cl45_read(sc, phy, 5,
7154 				(MDIO_REG_BANK_COMBO_IEEE0 +
7155 				(MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
7156 				&mii_ctrl);
7157 		elink_cl45_write(sc, phy, 5,
7158 				 (MDIO_REG_BANK_COMBO_IEEE0 +
7159 				 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
7160 				 mii_ctrl |
7161 				 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
7162 	}
7163 }
7164 
7165 elink_status_t elink_set_led(struct elink_params *params,
7166 		  struct elink_vars *vars, uint8_t mode, uint32_t speed)
7167 {
7168 	uint8_t port = params->port;
7169 	uint16_t hw_led_mode = params->hw_led_mode;
7170 	elink_status_t rc = ELINK_STATUS_OK;
7171 	uint8_t phy_idx;
7172 	uint32_t tmp;
7173 	uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
7174 	struct bxe_softc *sc = params->sc;
7175 	ELINK_DEBUG_P2(sc, "elink_set_led: port %x, mode %d\n", port, mode);
7176 	ELINK_DEBUG_P2(sc, "speed 0x%x, hw_led_mode 0x%x\n",
7177 		 speed, hw_led_mode);
7178 	/* In case */
7179 	for (phy_idx = ELINK_EXT_PHY1; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
7180 		if (params->phy[phy_idx].set_link_led) {
7181 			params->phy[phy_idx].set_link_led(
7182 				&params->phy[phy_idx], params, mode);
7183 		}
7184 	}
7185 #ifdef ELINK_INCLUDE_EMUL
7186 	if (params->feature_config_flags &
7187 	    ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC)
7188 		return rc;
7189 #endif
7190 
7191 	switch (mode) {
7192 	case ELINK_LED_MODE_FRONT_PANEL_OFF:
7193 	case ELINK_LED_MODE_OFF:
7194 		REG_WR(sc, NIG_REG_LED_10G_P0 + port*4, 0);
7195 		REG_WR(sc, NIG_REG_LED_MODE_P0 + port*4,
7196 		       SHARED_HW_CFG_LED_MAC1);
7197 
7198 		tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7199 		if (params->phy[ELINK_EXT_PHY1].type ==
7200 			PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
7201 			tmp &= ~(EMAC_LED_1000MB_OVERRIDE |
7202 				EMAC_LED_100MB_OVERRIDE |
7203 				EMAC_LED_10MB_OVERRIDE);
7204 		else
7205 			tmp |= EMAC_LED_OVERRIDE;
7206 
7207 		elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED, tmp);
7208 		break;
7209 
7210 	case ELINK_LED_MODE_OPER:
7211 		/* For all other phys, OPER mode is same as ON, so in case
7212 		 * link is down, do nothing
7213 		 */
7214 		if (!vars->link_up)
7215 			break;
7216 	case ELINK_LED_MODE_ON:
7217 		if (((params->phy[ELINK_EXT_PHY1].type ==
7218 			  PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
7219 			 (params->phy[ELINK_EXT_PHY1].type ==
7220 			  PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722)) &&
7221 		    CHIP_IS_E2(sc) && params->num_phys == 2) {
7222 			/* This is a work-around for E2+8727 Configurations */
7223 			if (mode == ELINK_LED_MODE_ON ||
7224 				speed == ELINK_SPEED_10000){
7225 				REG_WR(sc, NIG_REG_LED_MODE_P0 + port*4, 0);
7226 				REG_WR(sc, NIG_REG_LED_10G_P0 + port*4, 1);
7227 
7228 				tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7229 				elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED,
7230 					(tmp | EMAC_LED_OVERRIDE));
7231 				/* Return here without enabling traffic
7232 				 * LED blink and setting rate in ON mode.
7233 				 * In oper mode, enabling LED blink
7234 				 * and setting rate is needed.
7235 				 */
7236 				if (mode == ELINK_LED_MODE_ON)
7237 					return rc;
7238 			}
7239 		} else if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
7240 			/* This is a work-around for HW issue found when link
7241 			 * is up in CL73
7242 			 */
7243 			if ((!CHIP_IS_E3(sc)) ||
7244 			    (CHIP_IS_E3(sc) &&
7245 			     mode == ELINK_LED_MODE_ON))
7246 				REG_WR(sc, NIG_REG_LED_10G_P0 + port*4, 1);
7247 
7248 			if (CHIP_IS_E1x(sc) ||
7249 			    CHIP_IS_E2(sc) ||
7250 			    (mode == ELINK_LED_MODE_ON))
7251 				REG_WR(sc, NIG_REG_LED_MODE_P0 + port*4, 0);
7252 			else
7253 				REG_WR(sc, NIG_REG_LED_MODE_P0 + port*4,
7254 				       hw_led_mode);
7255 		} else if ((params->phy[ELINK_EXT_PHY1].type ==
7256 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) &&
7257 			   (mode == ELINK_LED_MODE_ON)) {
7258 			REG_WR(sc, NIG_REG_LED_MODE_P0 + port*4, 0);
7259 			tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7260 			elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED, tmp |
7261 				EMAC_LED_OVERRIDE | EMAC_LED_1000MB_OVERRIDE);
7262 			/* Break here; otherwise, it'll disable the
7263 			 * intended override.
7264 			 */
7265 			break;
7266 		} else {
7267 			uint32_t nig_led_mode = ((params->hw_led_mode <<
7268 					     SHARED_HW_CFG_LED_MODE_SHIFT) ==
7269 					    SHARED_HW_CFG_LED_EXTPHY2) ?
7270 				(SHARED_HW_CFG_LED_PHY1 >>
7271 				 SHARED_HW_CFG_LED_MODE_SHIFT) : hw_led_mode;
7272 			REG_WR(sc, NIG_REG_LED_MODE_P0 + port*4,
7273 			       nig_led_mode);
7274 		}
7275 
7276 		REG_WR(sc, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
7277 		/* Set blinking rate to ~15.9Hz */
7278 		if (CHIP_IS_E3(sc))
7279 			REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
7280 			       LED_BLINK_RATE_VAL_E3);
7281 		else
7282 			REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
7283 			       LED_BLINK_RATE_VAL_E1X_E2);
7284 		REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
7285 		       port*4, 1);
7286 		tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7287 		elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED,
7288 			(tmp & (~EMAC_LED_OVERRIDE)));
7289 
7290 		if (CHIP_IS_E1(sc) &&
7291 		    ((speed == ELINK_SPEED_2500) ||
7292 		     (speed == ELINK_SPEED_1000) ||
7293 		     (speed == ELINK_SPEED_100) ||
7294 		     (speed == ELINK_SPEED_10))) {
7295 			/* For speeds less than 10G LED scheme is different */
7296 			REG_WR(sc, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
7297 			       + port*4, 1);
7298 			REG_WR(sc, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
7299 			       port*4, 0);
7300 			REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
7301 			       port*4, 1);
7302 		}
7303 		break;
7304 
7305 	default:
7306 		rc = ELINK_STATUS_ERROR;
7307 		ELINK_DEBUG_P1(sc, "elink_set_led: Invalid led mode %d\n",
7308 			 mode);
7309 		break;
7310 	}
7311 	return rc;
7312 
7313 }
7314 
7315 /* This function comes to reflect the actual link state read DIRECTLY from the
7316  * HW
7317  */
7318 elink_status_t elink_test_link(struct elink_params *params, struct elink_vars *vars,
7319 		    uint8_t is_serdes)
7320 {
7321 	struct bxe_softc *sc = params->sc;
7322 	uint16_t gp_status = 0, phy_index = 0;
7323 	uint8_t ext_phy_link_up = 0, serdes_phy_type;
7324 	struct elink_vars temp_vars;
7325 	struct elink_phy *int_phy = &params->phy[ELINK_INT_PHY];
7326 #ifdef ELINK_INCLUDE_FPGA
7327 	if (CHIP_REV_IS_FPGA(sc))
7328 		return ELINK_STATUS_OK;
7329 #endif
7330 #ifdef ELINK_INCLUDE_EMUL
7331 	if (CHIP_REV_IS_EMUL(sc))
7332 		return ELINK_STATUS_OK;
7333 #endif
7334 
7335 	if (CHIP_IS_E3(sc)) {
7336 		uint16_t link_up;
7337 		if (params->req_line_speed[ELINK_LINK_CONFIG_IDX(ELINK_INT_PHY)]
7338 		    > ELINK_SPEED_10000) {
7339 			/* Check 20G link */
7340 			elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7341 					1, &link_up);
7342 			elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7343 					1, &link_up);
7344 			link_up &= (1<<2);
7345 		} else {
7346 			/* Check 10G link and below*/
7347 			uint8_t lane = elink_get_warpcore_lane(int_phy, params);
7348 			elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7349 					MDIO_WC_REG_GP2_STATUS_GP_2_1,
7350 					&gp_status);
7351 			gp_status = ((gp_status >> 8) & 0xf) |
7352 				((gp_status >> 12) & 0xf);
7353 			link_up = gp_status & (1 << lane);
7354 		}
7355 		if (!link_up)
7356 			return ELINK_STATUS_NO_LINK;
7357 	} else {
7358 		CL22_RD_OVER_CL45(sc, int_phy,
7359 			  MDIO_REG_BANK_GP_STATUS,
7360 			  MDIO_GP_STATUS_TOP_AN_STATUS1,
7361 			  &gp_status);
7362 	/* Link is up only if both local phy and external phy are up */
7363 	if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
7364 		return ELINK_STATUS_NO_LINK;
7365 	}
7366 	/* In XGXS loopback mode, do not check external PHY */
7367 	if (params->loopback_mode == ELINK_LOOPBACK_XGXS)
7368 		return ELINK_STATUS_OK;
7369 
7370 	switch (params->num_phys) {
7371 	case 1:
7372 		/* No external PHY */
7373 		return ELINK_STATUS_OK;
7374 	case 2:
7375 		ext_phy_link_up = params->phy[ELINK_EXT_PHY1].read_status(
7376 			&params->phy[ELINK_EXT_PHY1],
7377 			params, &temp_vars);
7378 		break;
7379 	case 3: /* Dual Media */
7380 		for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7381 		      phy_index++) {
7382 			serdes_phy_type = ((params->phy[phy_index].media_type ==
7383 					    ELINK_ETH_PHY_SFPP_10G_FIBER) ||
7384 					   (params->phy[phy_index].media_type ==
7385 					    ELINK_ETH_PHY_SFP_1G_FIBER) ||
7386 					   (params->phy[phy_index].media_type ==
7387 					    ELINK_ETH_PHY_XFP_FIBER) ||
7388 					   (params->phy[phy_index].media_type ==
7389 					    ELINK_ETH_PHY_DA_TWINAX));
7390 
7391 			if (is_serdes != serdes_phy_type)
7392 				continue;
7393 			if (params->phy[phy_index].read_status) {
7394 				ext_phy_link_up |=
7395 					params->phy[phy_index].read_status(
7396 						&params->phy[phy_index],
7397 						params, &temp_vars);
7398 			}
7399 		}
7400 		break;
7401 	}
7402 	if (ext_phy_link_up)
7403 		return ELINK_STATUS_OK;
7404 	return ELINK_STATUS_NO_LINK;
7405 }
7406 
7407 static elink_status_t elink_link_initialize(struct elink_params *params,
7408 				 struct elink_vars *vars)
7409 {
7410 	uint8_t phy_index, non_ext_phy;
7411 	struct bxe_softc *sc = params->sc;
7412 	/* In case of external phy existence, the line speed would be the
7413 	 * line speed linked up by the external phy. In case it is direct
7414 	 * only, then the line_speed during initialization will be
7415 	 * equal to the req_line_speed
7416 	 */
7417 	vars->line_speed = params->phy[ELINK_INT_PHY].req_line_speed;
7418 
7419 	/* Initialize the internal phy in case this is a direct board
7420 	 * (no external phys), or this board has external phy which requires
7421 	 * to first.
7422 	 */
7423 	if (!USES_WARPCORE(sc))
7424 		elink_prepare_xgxs(&params->phy[ELINK_INT_PHY], params, vars);
7425 	/* init ext phy and enable link state int */
7426 	non_ext_phy = (ELINK_SINGLE_MEDIA_DIRECT(params) ||
7427 		       (params->loopback_mode == ELINK_LOOPBACK_XGXS));
7428 
7429 	if (non_ext_phy ||
7430 	    (params->phy[ELINK_EXT_PHY1].flags & ELINK_FLAGS_INIT_XGXS_FIRST) ||
7431 	    (params->loopback_mode == ELINK_LOOPBACK_EXT_PHY)) {
7432 		struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
7433 		if (vars->line_speed == ELINK_SPEED_AUTO_NEG &&
7434 		    (CHIP_IS_E1x(sc) ||
7435 		     CHIP_IS_E2(sc)))
7436 			elink_set_parallel_detection(phy, params);
7437 		if (params->phy[ELINK_INT_PHY].config_init)
7438 			params->phy[ELINK_INT_PHY].config_init(phy, params, vars);
7439 	}
7440 
7441 	/* Re-read this value in case it was changed inside config_init due to
7442 	 * limitations of optic module
7443 	 */
7444 	vars->line_speed = params->phy[ELINK_INT_PHY].req_line_speed;
7445 
7446 	/* Init external phy*/
7447 	if (non_ext_phy) {
7448 		if (params->phy[ELINK_INT_PHY].supported &
7449 		    ELINK_SUPPORTED_FIBRE)
7450 			vars->link_status |= LINK_STATUS_SERDES_LINK;
7451 	} else {
7452 		for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7453 		      phy_index++) {
7454 			/* No need to initialize second phy in case of first
7455 			 * phy only selection. In case of second phy, we do
7456 			 * need to initialize the first phy, since they are
7457 			 * connected.
7458 			 */
7459 			if (params->phy[phy_index].supported &
7460 			    ELINK_SUPPORTED_FIBRE)
7461 				vars->link_status |= LINK_STATUS_SERDES_LINK;
7462 
7463 			if (phy_index == ELINK_EXT_PHY2 &&
7464 			    (elink_phy_selection(params) ==
7465 			     PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
7466 				ELINK_DEBUG_P0(sc,
7467 				   "Not initializing second phy\n");
7468 				continue;
7469 			}
7470 			params->phy[phy_index].config_init(
7471 				&params->phy[phy_index],
7472 				params, vars);
7473 		}
7474 	}
7475 	/* Reset the interrupt indication after phy was initialized */
7476 	elink_bits_dis(sc, NIG_REG_STATUS_INTERRUPT_PORT0 +
7477 		       params->port*4,
7478 		       (ELINK_NIG_STATUS_XGXS0_LINK10G |
7479 			ELINK_NIG_STATUS_XGXS0_LINK_STATUS |
7480 			ELINK_NIG_STATUS_SERDES0_LINK_STATUS |
7481 			ELINK_NIG_MASK_MI_INT));
7482 	return ELINK_STATUS_OK;
7483 }
7484 
7485 static void elink_int_link_reset(struct elink_phy *phy,
7486 				 struct elink_params *params)
7487 {
7488 	/* Reset the SerDes/XGXS */
7489 	REG_WR(params->sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
7490 	       (0x1ff << (params->port*16)));
7491 }
7492 
7493 static void elink_common_ext_link_reset(struct elink_phy *phy,
7494 					struct elink_params *params)
7495 {
7496 	struct bxe_softc *sc = params->sc;
7497 	uint8_t gpio_port;
7498 	/* HW reset */
7499 	if (CHIP_IS_E2(sc))
7500 		gpio_port = SC_PATH(sc);
7501 	else
7502 		gpio_port = params->port;
7503 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
7504 		       MISC_REGISTERS_GPIO_OUTPUT_LOW,
7505 		       gpio_port);
7506 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
7507 		       MISC_REGISTERS_GPIO_OUTPUT_LOW,
7508 		       gpio_port);
7509 	ELINK_DEBUG_P0(sc, "reset external PHY\n");
7510 }
7511 
7512 static elink_status_t elink_update_link_down(struct elink_params *params,
7513 				  struct elink_vars *vars)
7514 {
7515 	struct bxe_softc *sc = params->sc;
7516 	uint8_t port = params->port;
7517 
7518 	ELINK_DEBUG_P1(sc, "Port %x: Link is down\n", port);
7519 	elink_set_led(params, vars, ELINK_LED_MODE_OFF, 0);
7520 	vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG;
7521 	/* Indicate no mac active */
7522 	vars->mac_type = ELINK_MAC_TYPE_NONE;
7523 
7524 	/* Update shared memory */
7525 	vars->link_status &= ~ELINK_LINK_UPDATE_MASK;
7526 	vars->line_speed = 0;
7527 	elink_update_mng(params, vars->link_status);
7528 
7529 	/* Activate nig drain */
7530 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
7531 
7532 	/* Disable emac */
7533 	if (!CHIP_IS_E3(sc))
7534 		REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port*4, 0);
7535 
7536 	DELAY(1000 * 10);
7537 	/* Reset BigMac/Xmac */
7538 	if (CHIP_IS_E1x(sc) ||
7539 	    CHIP_IS_E2(sc))
7540 		elink_set_bmac_rx(sc, params->chip_id, params->port, 0);
7541 
7542 	if (CHIP_IS_E3(sc)) {
7543 		/* Prevent LPI Generation by chip */
7544 		REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2),
7545 		       0);
7546 		REG_WR(sc, MISC_REG_CPMU_LP_MASK_ENT_P0 + (params->port << 2),
7547 		       0);
7548 		vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
7549 				      SHMEM_EEE_ACTIVE_BIT);
7550 
7551 		elink_update_mng_eee(params, vars->eee_status);
7552 		elink_set_xmac_rxtx(params, 0);
7553 		elink_set_umac_rxtx(params, 0);
7554 	}
7555 
7556 	return ELINK_STATUS_OK;
7557 }
7558 
7559 static elink_status_t elink_update_link_up(struct elink_params *params,
7560 				struct elink_vars *vars,
7561 				uint8_t link_10g)
7562 {
7563 	struct bxe_softc *sc = params->sc;
7564 	uint8_t phy_idx, port = params->port;
7565 	elink_status_t rc = ELINK_STATUS_OK;
7566 
7567 	vars->link_status |= (LINK_STATUS_LINK_UP |
7568 			      LINK_STATUS_PHYSICAL_LINK_FLAG);
7569 	vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
7570 
7571 	if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
7572 		vars->link_status |=
7573 			LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
7574 
7575 	if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
7576 		vars->link_status |=
7577 			LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
7578 	if (USES_WARPCORE(sc)) {
7579 		if (link_10g) {
7580 			if (elink_xmac_enable(params, vars, 0) ==
7581 			    ELINK_STATUS_NO_LINK) {
7582 				ELINK_DEBUG_P0(sc, "Found errors on XMAC\n");
7583 				vars->link_up = 0;
7584 				vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
7585 				vars->link_status &= ~LINK_STATUS_LINK_UP;
7586 			}
7587 		} else
7588 			elink_umac_enable(params, vars, 0);
7589 		elink_set_led(params, vars,
7590 			      ELINK_LED_MODE_OPER, vars->line_speed);
7591 
7592 		if ((vars->eee_status & SHMEM_EEE_ACTIVE_BIT) &&
7593 		    (vars->eee_status & SHMEM_EEE_LPI_REQUESTED_BIT)) {
7594 			ELINK_DEBUG_P0(sc, "Enabling LPI assertion\n");
7595 			REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 +
7596 			       (params->port << 2), 1);
7597 			REG_WR(sc, MISC_REG_CPMU_LP_DR_ENABLE, 1);
7598 			REG_WR(sc, MISC_REG_CPMU_LP_MASK_ENT_P0 +
7599 			       (params->port << 2), 0xfc20);
7600 		}
7601 	}
7602 	if ((CHIP_IS_E1x(sc) ||
7603 	     CHIP_IS_E2(sc))) {
7604 		if (link_10g) {
7605 			if (elink_bmac_enable(params, vars, 0, 1) ==
7606 			    ELINK_STATUS_NO_LINK) {
7607 				ELINK_DEBUG_P0(sc, "Found errors on BMAC\n");
7608 				vars->link_up = 0;
7609 				vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
7610 				vars->link_status &= ~LINK_STATUS_LINK_UP;
7611 			}
7612 
7613 			elink_set_led(params, vars,
7614 				      ELINK_LED_MODE_OPER, ELINK_SPEED_10000);
7615 		} else {
7616 			rc = elink_emac_program(params, vars);
7617 			elink_emac_enable(params, vars, 0);
7618 
7619 			/* AN complete? */
7620 			if ((vars->link_status &
7621 			     LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
7622 			    && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
7623 			    ELINK_SINGLE_MEDIA_DIRECT(params))
7624 				elink_set_gmii_tx_driver(params);
7625 		}
7626 	}
7627 
7628 	/* PBF - link up */
7629 	if (CHIP_IS_E1x(sc))
7630 		rc |= elink_pbf_update(params, vars->flow_ctrl,
7631 				       vars->line_speed);
7632 
7633 	/* Disable drain */
7634 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
7635 
7636 	/* Update shared memory */
7637 	elink_update_mng(params, vars->link_status);
7638 	elink_update_mng_eee(params, vars->eee_status);
7639 	/* Check remote fault */
7640 	for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
7641 		if (params->phy[phy_idx].flags & ELINK_FLAGS_TX_ERROR_CHECK) {
7642 			elink_check_half_open_conn(params, vars, 0);
7643 			break;
7644 		}
7645 	}
7646 	DELAY(1000 * 20);
7647 	return rc;
7648 }
7649 
7650 static void elink_chng_link_count(struct elink_params *params, uint8_t clear)
7651 {
7652 	struct bxe_softc *sc = params->sc;
7653 	uint32_t addr, val;
7654 
7655 	/* Verify the link_change_count is supported by the MFW */
7656 	if (!(SHMEM2_HAS(sc, link_change_count)))
7657 		return;
7658 
7659 	addr = params->shmem2_base +
7660 		offsetof(struct shmem2_region, link_change_count[params->port]);
7661 	if (clear)
7662 		val = 0;
7663 	else
7664 		val = REG_RD(sc, addr) + 1;
7665 	REG_WR(sc, addr, val);
7666 }
7667 
7668 /* The elink_link_update function should be called upon link
7669  * interrupt.
7670  * Link is considered up as follows:
7671  * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
7672  *   to be up
7673  * - SINGLE_MEDIA - The link between the 577xx and the external
7674  *   phy (XGXS) need to up as well as the external link of the
7675  *   phy (PHY_EXT1)
7676  * - DUAL_MEDIA - The link between the 577xx and the first
7677  *   external phy needs to be up, and at least one of the 2
7678  *   external phy link must be up.
7679  */
7680 elink_status_t elink_link_update(struct elink_params *params, struct elink_vars *vars)
7681 {
7682 	struct bxe_softc *sc = params->sc;
7683 	struct elink_vars phy_vars[ELINK_MAX_PHYS];
7684 	uint8_t port = params->port;
7685 	uint8_t link_10g_plus, phy_index;
7686 	uint32_t prev_link_status = vars->link_status;
7687 	uint8_t ext_phy_link_up = 0, cur_link_up;
7688 	elink_status_t rc = ELINK_STATUS_OK;
7689 	uint16_t ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
7690 	uint8_t active_external_phy = ELINK_INT_PHY;
7691 	vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
7692 	vars->link_status &= ~ELINK_LINK_UPDATE_MASK;
7693 	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
7694 	      phy_index++) {
7695 		phy_vars[phy_index].flow_ctrl = 0;
7696 		phy_vars[phy_index].link_status = 0;
7697 		phy_vars[phy_index].line_speed = 0;
7698 		phy_vars[phy_index].duplex = DUPLEX_FULL;
7699 		phy_vars[phy_index].phy_link_up = 0;
7700 		phy_vars[phy_index].link_up = 0;
7701 		phy_vars[phy_index].fault_detected = 0;
7702 		/* different consideration, since vars holds inner state */
7703 		phy_vars[phy_index].eee_status = vars->eee_status;
7704 	}
7705 
7706 	if (USES_WARPCORE(sc))
7707 		elink_set_aer_mmd(params, &params->phy[ELINK_INT_PHY]);
7708 
7709 	ELINK_DEBUG_P3(sc, "port %x, XGXS?%x, int_status 0x%x\n",
7710 		 port, (vars->phy_flags & PHY_XGXS_FLAG),
7711 		 REG_RD(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
7712 
7713 	ELINK_DEBUG_P3(sc, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
7714 		 REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
7715 		 REG_RD(sc, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18) > 0,
7716 		 REG_RD(sc, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
7717 
7718 	ELINK_DEBUG_P2(sc, " 10G %x, XGXS_LINK %x\n",
7719 	  REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
7720 	  REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
7721 
7722 	/* Disable emac */
7723 	if (!CHIP_IS_E3(sc))
7724 		REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port*4, 0);
7725 
7726 	/* Step 1:
7727 	 * Check external link change only for external phys, and apply
7728 	 * priority selection between them in case the link on both phys
7729 	 * is up. Note that instead of the common vars, a temporary
7730 	 * vars argument is used since each phy may have different link/
7731 	 * speed/duplex result
7732 	 */
7733 	for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7734 	      phy_index++) {
7735 		struct elink_phy *phy = &params->phy[phy_index];
7736 		if (!phy->read_status)
7737 			continue;
7738 		/* Read link status and params of this ext phy */
7739 		cur_link_up = phy->read_status(phy, params,
7740 					       &phy_vars[phy_index]);
7741 		if (cur_link_up) {
7742 			ELINK_DEBUG_P1(sc, "phy in index %d link is up\n",
7743 				   phy_index);
7744 		} else {
7745 			ELINK_DEBUG_P1(sc, "phy in index %d link is down\n",
7746 				   phy_index);
7747 			continue;
7748 		}
7749 
7750 		if (!ext_phy_link_up) {
7751 			ext_phy_link_up = 1;
7752 			active_external_phy = phy_index;
7753 		} else {
7754 			switch (elink_phy_selection(params)) {
7755 			case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
7756 			case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
7757 			/* In this option, the first PHY makes sure to pass the
7758 			 * traffic through itself only.
7759 			 * Its not clear how to reset the link on the second phy
7760 			 */
7761 				active_external_phy = ELINK_EXT_PHY1;
7762 				break;
7763 			case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
7764 			/* In this option, the first PHY makes sure to pass the
7765 			 * traffic through the second PHY.
7766 			 */
7767 				active_external_phy = ELINK_EXT_PHY2;
7768 				break;
7769 			default:
7770 			/* Link indication on both PHYs with the following cases
7771 			 * is invalid:
7772 			 * - FIRST_PHY means that second phy wasn't initialized,
7773 			 * hence its link is expected to be down
7774 			 * - SECOND_PHY means that first phy should not be able
7775 			 * to link up by itself (using configuration)
7776 			 * - DEFAULT should be overriden during initialiazation
7777 			 */
7778 				ELINK_DEBUG_P1(sc, "Invalid link indication"
7779 					   "mpc=0x%x. DISABLING LINK !!!\n",
7780 					   params->multi_phy_config);
7781 				ext_phy_link_up = 0;
7782 				break;
7783 			}
7784 		}
7785 	}
7786 	prev_line_speed = vars->line_speed;
7787 	/* Step 2:
7788 	 * Read the status of the internal phy. In case of
7789 	 * DIRECT_SINGLE_MEDIA board, this link is the external link,
7790 	 * otherwise this is the link between the 577xx and the first
7791 	 * external phy
7792 	 */
7793 	if (params->phy[ELINK_INT_PHY].read_status)
7794 		params->phy[ELINK_INT_PHY].read_status(
7795 			&params->phy[ELINK_INT_PHY],
7796 			params, vars);
7797 	/* The INT_PHY flow control reside in the vars. This include the
7798 	 * case where the speed or flow control are not set to AUTO.
7799 	 * Otherwise, the active external phy flow control result is set
7800 	 * to the vars. The ext_phy_line_speed is needed to check if the
7801 	 * speed is different between the internal phy and external phy.
7802 	 * This case may be result of intermediate link speed change.
7803 	 */
7804 	if (active_external_phy > ELINK_INT_PHY) {
7805 		vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
7806 		/* Link speed is taken from the XGXS. AN and FC result from
7807 		 * the external phy.
7808 		 */
7809 		vars->link_status |= phy_vars[active_external_phy].link_status;
7810 
7811 		/* if active_external_phy is first PHY and link is up - disable
7812 		 * disable TX on second external PHY
7813 		 */
7814 		if (active_external_phy == ELINK_EXT_PHY1) {
7815 			if (params->phy[ELINK_EXT_PHY2].phy_specific_func) {
7816 				ELINK_DEBUG_P0(sc,
7817 				   "Disabling TX on EXT_PHY2\n");
7818 				params->phy[ELINK_EXT_PHY2].phy_specific_func(
7819 					&params->phy[ELINK_EXT_PHY2],
7820 					params, ELINK_DISABLE_TX);
7821 			}
7822 		}
7823 
7824 		ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
7825 		vars->duplex = phy_vars[active_external_phy].duplex;
7826 		if (params->phy[active_external_phy].supported &
7827 		    ELINK_SUPPORTED_FIBRE)
7828 			vars->link_status |= LINK_STATUS_SERDES_LINK;
7829 		else
7830 			vars->link_status &= ~LINK_STATUS_SERDES_LINK;
7831 
7832 		vars->eee_status = phy_vars[active_external_phy].eee_status;
7833 
7834 		ELINK_DEBUG_P1(sc, "Active external phy selected: %x\n",
7835 			   active_external_phy);
7836 	}
7837 
7838         ELINK_DEBUG_P3(sc, "vars : phy_flags = %x, mac_type = %x, phy_link_up = %x\n",
7839                        vars->phy_flags, vars->mac_type, vars->phy_link_up);
7840         ELINK_DEBUG_P3(sc, "vars : link_up = %x, line_speed = %x, duplex = %x\n",
7841                        vars->link_up, vars->line_speed, vars->duplex);
7842         ELINK_DEBUG_P3(sc, "vars : flow_ctrl = %x, ieee_fc = %x, link_status = %x\n",
7843                        vars->flow_ctrl, vars->ieee_fc, vars->link_status);
7844         ELINK_DEBUG_P3(sc, "vars : eee_status = %x, fault_detected = %x, check_kr2_recovery_cnt = %x\n",
7845                        vars->eee_status, vars->fault_detected, vars->check_kr2_recovery_cnt);
7846         ELINK_DEBUG_P3(sc, "vars : periodic_flags = %x, aeu_int_mask = %x, rx_tx_asic_rst = %x\n",
7847                        vars->periodic_flags, vars->aeu_int_mask, vars->rx_tx_asic_rst);
7848         ELINK_DEBUG_P2(sc, "vars : turn_to_run_wc_rt = %x, rsrv2 = %x\n",
7849                        vars->turn_to_run_wc_rt, vars->rsrv2);
7850 
7851 	for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7852 	      phy_index++) {
7853 		if (params->phy[phy_index].flags &
7854 		    ELINK_FLAGS_REARM_LATCH_SIGNAL) {
7855 			elink_rearm_latch_signal(sc, port,
7856 						 phy_index ==
7857 						 active_external_phy);
7858 			break;
7859 		}
7860 	}
7861 	ELINK_DEBUG_P3(sc, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
7862 		   " ext_phy_line_speed = %d\n", vars->flow_ctrl,
7863 		   vars->link_status, ext_phy_line_speed);
7864 	/* Upon link speed change set the NIG into drain mode. Comes to
7865 	 * deals with possible FIFO glitch due to clk change when speed
7866 	 * is decreased without link down indicator
7867 	 */
7868 
7869 	if (vars->phy_link_up) {
7870 		if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
7871 		    (ext_phy_line_speed != vars->line_speed)) {
7872 			ELINK_DEBUG_P2(sc, "Internal link speed %d is"
7873 				   " different than the external"
7874 				   " link speed %d\n", vars->line_speed,
7875 				   ext_phy_line_speed);
7876 			vars->phy_link_up = 0;
7877 			ELINK_DEBUG_P0(sc, "phy_link_up set to 0\n");
7878 		} else if (prev_line_speed != vars->line_speed) {
7879 			REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4,
7880 			       0);
7881 			DELAY(1000 * 1);
7882 		}
7883 	}
7884 
7885 	/* Anything 10 and over uses the bmac */
7886 	link_10g_plus = (vars->line_speed >= ELINK_SPEED_10000);
7887 
7888 	elink_link_int_ack(params, vars, link_10g_plus);
7889 
7890 	/* In case external phy link is up, and internal link is down
7891 	 * (not initialized yet probably after link initialization, it
7892 	 * needs to be initialized.
7893 	 * Note that after link down-up as result of cable plug, the xgxs
7894 	 * link would probably become up again without the need
7895 	 * initialize it
7896 	 */
7897 	if (!(ELINK_SINGLE_MEDIA_DIRECT(params))) {
7898 		ELINK_DEBUG_P3(sc, "ext_phy_link_up = %d, int_link_up = %d,"
7899 			   " init_preceding = %d\n", ext_phy_link_up,
7900 			   vars->phy_link_up,
7901 			   params->phy[ELINK_EXT_PHY1].flags &
7902 			   ELINK_FLAGS_INIT_XGXS_FIRST);
7903 		if (!(params->phy[ELINK_EXT_PHY1].flags &
7904 		      ELINK_FLAGS_INIT_XGXS_FIRST)
7905 		    && ext_phy_link_up && !vars->phy_link_up) {
7906 			vars->line_speed = ext_phy_line_speed;
7907 			if (vars->line_speed < ELINK_SPEED_1000)
7908 				vars->phy_flags |= PHY_SGMII_FLAG;
7909 			else
7910 				vars->phy_flags &= ~PHY_SGMII_FLAG;
7911 
7912 			if (params->phy[ELINK_INT_PHY].config_init)
7913 				params->phy[ELINK_INT_PHY].config_init(
7914 					&params->phy[ELINK_INT_PHY], params,
7915 						vars);
7916 		}
7917 	}
7918 	/* Link is up only if both local phy and external phy (in case of
7919 	 * non-direct board) are up and no fault detected on active PHY.
7920 	 */
7921 	vars->link_up = (vars->phy_link_up &&
7922 			 (ext_phy_link_up ||
7923 			  ELINK_SINGLE_MEDIA_DIRECT(params)) &&
7924 			 (phy_vars[active_external_phy].fault_detected == 0));
7925 
7926 	if(vars->link_up) {
7927                 ELINK_DEBUG_P0(sc, "local phy and external phy are up\n");
7928         } else {
7929                 ELINK_DEBUG_P0(sc, "either local phy or external phy or both are down\n");
7930         }
7931 
7932 	/* Update the PFC configuration in case it was changed */
7933 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
7934 		vars->link_status |= LINK_STATUS_PFC_ENABLED;
7935 	else
7936 		vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
7937 
7938 	if (vars->link_up)
7939 		rc = elink_update_link_up(params, vars, link_10g_plus);
7940 	else
7941 		rc = elink_update_link_down(params, vars);
7942 
7943 	if ((prev_link_status ^ vars->link_status) & LINK_STATUS_LINK_UP)
7944 		elink_chng_link_count(params, 0);
7945 
7946 	/* Update MCP link status was changed */
7947 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_BC_SUPPORTS_AFEX)
7948 		elink_cb_fw_command(sc, DRV_MSG_CODE_LINK_STATUS_CHANGED, 0);
7949 
7950 	return rc;
7951 }
7952 
7953 /*****************************************************************************/
7954 /*			    External Phy section			     */
7955 /*****************************************************************************/
7956 void elink_ext_phy_hw_reset(struct bxe_softc *sc, uint8_t port)
7957 {
7958 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
7959 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
7960 	DELAY(1000 * 1);
7961 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
7962 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
7963 }
7964 
7965 static void elink_save_spirom_version(struct bxe_softc *sc, uint8_t port,
7966 				      uint32_t spirom_ver, uint32_t ver_addr)
7967 {
7968 	ELINK_DEBUG_P3(sc, "FW version 0x%x:0x%x for port %d\n",
7969 		 (uint16_t)(spirom_ver>>16), (uint16_t)spirom_ver, port);
7970 
7971 	if (ver_addr)
7972 		REG_WR(sc, ver_addr, spirom_ver);
7973 }
7974 
7975 static void elink_save_bcm_spirom_ver(struct bxe_softc *sc,
7976 				      struct elink_phy *phy,
7977 				      uint8_t port)
7978 {
7979 	uint16_t fw_ver1, fw_ver2;
7980 
7981 	elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
7982 			MDIO_PMA_REG_ROM_VER1, &fw_ver1);
7983 	elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
7984 			MDIO_PMA_REG_ROM_VER2, &fw_ver2);
7985 	elink_save_spirom_version(sc, port, (uint32_t)(fw_ver1<<16 | fw_ver2),
7986 				  phy->ver_addr);
7987 }
7988 
7989 static void elink_ext_phy_10G_an_resolve(struct bxe_softc *sc,
7990 				       struct elink_phy *phy,
7991 				       struct elink_vars *vars)
7992 {
7993 	uint16_t val;
7994 	elink_cl45_read(sc, phy,
7995 			MDIO_AN_DEVAD,
7996 			MDIO_AN_REG_STATUS, &val);
7997 	elink_cl45_read(sc, phy,
7998 			MDIO_AN_DEVAD,
7999 			MDIO_AN_REG_STATUS, &val);
8000 	if (val & (1<<5))
8001 		vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
8002 	if ((val & (1<<0)) == 0)
8003 		vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
8004 }
8005 
8006 /******************************************************************/
8007 /*		common BCM8073/BCM8727 PHY SECTION		  */
8008 /******************************************************************/
8009 static void elink_8073_resolve_fc(struct elink_phy *phy,
8010 				  struct elink_params *params,
8011 				  struct elink_vars *vars)
8012 {
8013 	struct bxe_softc *sc = params->sc;
8014 	if (phy->req_line_speed == ELINK_SPEED_10 ||
8015 	    phy->req_line_speed == ELINK_SPEED_100) {
8016 		vars->flow_ctrl = phy->req_flow_ctrl;
8017 		return;
8018 	}
8019 
8020 	if (elink_ext_phy_resolve_fc(phy, params, vars) &&
8021 	    (vars->flow_ctrl == ELINK_FLOW_CTRL_NONE)) {
8022 		uint16_t pause_result;
8023 		uint16_t ld_pause;		/* local */
8024 		uint16_t lp_pause;		/* link partner */
8025 		elink_cl45_read(sc, phy,
8026 				MDIO_AN_DEVAD,
8027 				MDIO_AN_REG_CL37_FC_LD, &ld_pause);
8028 
8029 		elink_cl45_read(sc, phy,
8030 				MDIO_AN_DEVAD,
8031 				MDIO_AN_REG_CL37_FC_LP, &lp_pause);
8032 		pause_result = (ld_pause &
8033 				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
8034 		pause_result |= (lp_pause &
8035 				 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
8036 
8037 		elink_pause_resolve(phy, params, vars, pause_result);
8038 		ELINK_DEBUG_P1(sc, "Ext PHY CL37 pause result 0x%x\n",
8039 			   pause_result);
8040 	}
8041 }
8042 static elink_status_t elink_8073_8727_external_rom_boot(struct bxe_softc *sc,
8043 					     struct elink_phy *phy,
8044 					     uint8_t port)
8045 {
8046 	uint32_t count = 0;
8047 	uint16_t fw_ver1, fw_msgout;
8048 	elink_status_t rc = ELINK_STATUS_OK;
8049 
8050 	/* Boot port from external ROM  */
8051 	/* EDC grst */
8052 	elink_cl45_write(sc, phy,
8053 			 MDIO_PMA_DEVAD,
8054 			 MDIO_PMA_REG_GEN_CTRL,
8055 			 0x0001);
8056 
8057 	/* Ucode reboot and rst */
8058 	elink_cl45_write(sc, phy,
8059 			 MDIO_PMA_DEVAD,
8060 			 MDIO_PMA_REG_GEN_CTRL,
8061 			 0x008c);
8062 
8063 	elink_cl45_write(sc, phy,
8064 			 MDIO_PMA_DEVAD,
8065 			 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
8066 
8067 	/* Reset internal microprocessor */
8068 	elink_cl45_write(sc, phy,
8069 			 MDIO_PMA_DEVAD,
8070 			 MDIO_PMA_REG_GEN_CTRL,
8071 			 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
8072 
8073 	/* Release srst bit */
8074 	elink_cl45_write(sc, phy,
8075 			 MDIO_PMA_DEVAD,
8076 			 MDIO_PMA_REG_GEN_CTRL,
8077 			 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
8078 
8079 	/* Delay 100ms per the PHY specifications */
8080 	DELAY(1000 * 100);
8081 
8082 	/* 8073 sometimes taking longer to download */
8083 	do {
8084 		count++;
8085 		if (count > 300) {
8086 			ELINK_DEBUG_P2(sc,
8087 				 "elink_8073_8727_external_rom_boot port %x:"
8088 				 "Download failed. fw version = 0x%x\n",
8089 				 port, fw_ver1);
8090 			rc = ELINK_STATUS_ERROR;
8091 			break;
8092 		}
8093 
8094 		elink_cl45_read(sc, phy,
8095 				MDIO_PMA_DEVAD,
8096 				MDIO_PMA_REG_ROM_VER1, &fw_ver1);
8097 		elink_cl45_read(sc, phy,
8098 				MDIO_PMA_DEVAD,
8099 				MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
8100 
8101 		DELAY(1000 * 1);
8102 	} while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
8103 			((fw_msgout & 0xff) != 0x03 && (phy->type ==
8104 			PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
8105 
8106 	/* Clear ser_boot_ctl bit */
8107 	elink_cl45_write(sc, phy,
8108 			 MDIO_PMA_DEVAD,
8109 			 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
8110 	elink_save_bcm_spirom_ver(sc, phy, port);
8111 
8112 	ELINK_DEBUG_P2(sc,
8113 		 "elink_8073_8727_external_rom_boot port %x:"
8114 		 "Download complete. fw version = 0x%x\n",
8115 		 port, fw_ver1);
8116 
8117 	return rc;
8118 }
8119 
8120 /******************************************************************/
8121 /*			BCM8073 PHY SECTION			  */
8122 /******************************************************************/
8123 static elink_status_t elink_8073_is_snr_needed(struct bxe_softc *sc, struct elink_phy *phy)
8124 {
8125 	/* This is only required for 8073A1, version 102 only */
8126 	uint16_t val;
8127 
8128 	/* Read 8073 HW revision*/
8129 	elink_cl45_read(sc, phy,
8130 			MDIO_PMA_DEVAD,
8131 			MDIO_PMA_REG_8073_CHIP_REV, &val);
8132 
8133 	if (val != 1) {
8134 		/* No need to workaround in 8073 A1 */
8135 		return ELINK_STATUS_OK;
8136 	}
8137 
8138 	elink_cl45_read(sc, phy,
8139 			MDIO_PMA_DEVAD,
8140 			MDIO_PMA_REG_ROM_VER2, &val);
8141 
8142 	/* SNR should be applied only for version 0x102 */
8143 	if (val != 0x102)
8144 		return ELINK_STATUS_OK;
8145 
8146 	return 1;
8147 }
8148 
8149 static elink_status_t elink_8073_xaui_wa(struct bxe_softc *sc, struct elink_phy *phy)
8150 {
8151 	uint16_t val, cnt, cnt1 ;
8152 
8153 	elink_cl45_read(sc, phy,
8154 			MDIO_PMA_DEVAD,
8155 			MDIO_PMA_REG_8073_CHIP_REV, &val);
8156 
8157 	if (val > 0) {
8158 		/* No need to workaround in 8073 A1 */
8159 		return ELINK_STATUS_OK;
8160 	}
8161 	/* XAUI workaround in 8073 A0: */
8162 
8163 	/* After loading the boot ROM and restarting Autoneg, poll
8164 	 * Dev1, Reg $C820:
8165 	 */
8166 
8167 	for (cnt = 0; cnt < 1000; cnt++) {
8168 		elink_cl45_read(sc, phy,
8169 				MDIO_PMA_DEVAD,
8170 				MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
8171 				&val);
8172 		  /* If bit [14] = 0 or bit [13] = 0, continue on with
8173 		   * system initialization (XAUI work-around not required, as
8174 		   * these bits indicate 2.5G or 1G link up).
8175 		   */
8176 		if (!(val & (1<<14)) || !(val & (1<<13))) {
8177 			ELINK_DEBUG_P0(sc, "XAUI work-around not required\n");
8178 			return ELINK_STATUS_OK;
8179 		} else if (!(val & (1<<15))) {
8180 			ELINK_DEBUG_P0(sc, "bit 15 went off\n");
8181 			/* If bit 15 is 0, then poll Dev1, Reg $C841 until it's
8182 			 * MSB (bit15) goes to 1 (indicating that the XAUI
8183 			 * workaround has completed), then continue on with
8184 			 * system initialization.
8185 			 */
8186 			for (cnt1 = 0; cnt1 < 1000; cnt1++) {
8187 				elink_cl45_read(sc, phy,
8188 					MDIO_PMA_DEVAD,
8189 					MDIO_PMA_REG_8073_XAUI_WA, &val);
8190 				if (val & (1<<15)) {
8191 					ELINK_DEBUG_P0(sc,
8192 					  "XAUI workaround has completed\n");
8193 					return ELINK_STATUS_OK;
8194 				 }
8195 				 DELAY(1000 * 3);
8196 			}
8197 			break;
8198 		}
8199 		DELAY(1000 * 3);
8200 	}
8201 	ELINK_DEBUG_P0(sc, "Warning: XAUI work-around timeout !!!\n");
8202 	return ELINK_STATUS_ERROR;
8203 }
8204 
8205 static void elink_807x_force_10G(struct bxe_softc *sc, struct elink_phy *phy)
8206 {
8207 	/* Force KR or KX */
8208 	elink_cl45_write(sc, phy,
8209 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
8210 	elink_cl45_write(sc, phy,
8211 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
8212 	elink_cl45_write(sc, phy,
8213 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
8214 	elink_cl45_write(sc, phy,
8215 			 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
8216 }
8217 
8218 static void elink_8073_set_pause_cl37(struct elink_params *params,
8219 				      struct elink_phy *phy,
8220 				      struct elink_vars *vars)
8221 {
8222 	uint16_t cl37_val;
8223 	struct bxe_softc *sc = params->sc;
8224 	elink_cl45_read(sc, phy,
8225 			MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
8226 
8227 	cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
8228 	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
8229 	elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
8230 	if ((vars->ieee_fc &
8231 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
8232 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
8233 		cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
8234 	}
8235 	if ((vars->ieee_fc &
8236 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
8237 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
8238 		cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
8239 	}
8240 	if ((vars->ieee_fc &
8241 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
8242 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
8243 		cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
8244 	}
8245 	ELINK_DEBUG_P1(sc,
8246 		 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
8247 
8248 	elink_cl45_write(sc, phy,
8249 			 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
8250 	DELAY(1000 * 500);
8251 }
8252 
8253 static void elink_8073_specific_func(struct elink_phy *phy,
8254 				     struct elink_params *params,
8255 				     uint32_t action)
8256 {
8257 	struct bxe_softc *sc = params->sc;
8258 	switch (action) {
8259 	case ELINK_PHY_INIT:
8260 		/* Enable LASI */
8261 		elink_cl45_write(sc, phy,
8262 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, (1<<2));
8263 		elink_cl45_write(sc, phy,
8264 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,  0x0004);
8265 		break;
8266 	}
8267 }
8268 
8269 static elink_status_t elink_8073_config_init(struct elink_phy *phy,
8270 				  struct elink_params *params,
8271 				  struct elink_vars *vars)
8272 {
8273 	struct bxe_softc *sc = params->sc;
8274 	uint16_t val = 0, tmp1;
8275 	uint8_t gpio_port;
8276 	ELINK_DEBUG_P0(sc, "Init 8073\n");
8277 
8278 	if (CHIP_IS_E2(sc))
8279 		gpio_port = SC_PATH(sc);
8280 	else
8281 		gpio_port = params->port;
8282 	/* Restore normal power mode*/
8283 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8284 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
8285 
8286 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
8287 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
8288 
8289 	elink_8073_specific_func(phy, params, ELINK_PHY_INIT);
8290 	elink_8073_set_pause_cl37(params, phy, vars);
8291 
8292 	elink_cl45_read(sc, phy,
8293 			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
8294 
8295 	elink_cl45_read(sc, phy,
8296 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
8297 
8298 	ELINK_DEBUG_P1(sc, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
8299 
8300 	/* Swap polarity if required - Must be done only in non-1G mode */
8301 	if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
8302 		/* Configure the 8073 to swap _P and _N of the KR lines */
8303 		ELINK_DEBUG_P0(sc, "Swapping polarity for the 8073\n");
8304 		/* 10G Rx/Tx and 1G Tx signal polarity swap */
8305 		elink_cl45_read(sc, phy,
8306 				MDIO_PMA_DEVAD,
8307 				MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
8308 		elink_cl45_write(sc, phy,
8309 				 MDIO_PMA_DEVAD,
8310 				 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
8311 				 (val | (3<<9)));
8312 	}
8313 
8314 
8315 	/* Enable CL37 BAM */
8316 	if (REG_RD(sc, params->shmem_base +
8317 			 offsetof(struct shmem_region, dev_info.
8318 				  port_hw_config[params->port].default_cfg)) &
8319 	    PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
8320 
8321 		elink_cl45_read(sc, phy,
8322 				MDIO_AN_DEVAD,
8323 				MDIO_AN_REG_8073_BAM, &val);
8324 		elink_cl45_write(sc, phy,
8325 				 MDIO_AN_DEVAD,
8326 				 MDIO_AN_REG_8073_BAM, val | 1);
8327 		ELINK_DEBUG_P0(sc, "Enable CL37 BAM on KR\n");
8328 	}
8329 	if (params->loopback_mode == ELINK_LOOPBACK_EXT) {
8330 		elink_807x_force_10G(sc, phy);
8331 		ELINK_DEBUG_P0(sc, "Forced speed 10G on 807X\n");
8332 		return ELINK_STATUS_OK;
8333 	} else {
8334 		elink_cl45_write(sc, phy,
8335 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
8336 	}
8337 	if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG) {
8338 		if (phy->req_line_speed == ELINK_SPEED_10000) {
8339 			val = (1<<7);
8340 		} else if (phy->req_line_speed ==  ELINK_SPEED_2500) {
8341 			val = (1<<5);
8342 			/* Note that 2.5G works only when used with 1G
8343 			 * advertisement
8344 			 */
8345 		} else
8346 			val = (1<<5);
8347 	} else {
8348 		val = 0;
8349 		if (phy->speed_cap_mask &
8350 			PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
8351 			val |= (1<<7);
8352 
8353 		/* Note that 2.5G works only when used with 1G advertisement */
8354 		if (phy->speed_cap_mask &
8355 			(PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
8356 			 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
8357 			val |= (1<<5);
8358 		ELINK_DEBUG_P1(sc, "807x autoneg val = 0x%x\n", val);
8359 	}
8360 
8361 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
8362 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
8363 
8364 	if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
8365 	     (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)) ||
8366 	    (phy->req_line_speed == ELINK_SPEED_2500)) {
8367 		uint16_t phy_ver;
8368 		/* Allow 2.5G for A1 and above */
8369 		elink_cl45_read(sc, phy,
8370 				MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
8371 				&phy_ver);
8372 		ELINK_DEBUG_P0(sc, "Add 2.5G\n");
8373 		if (phy_ver > 0)
8374 			tmp1 |= 1;
8375 		else
8376 			tmp1 &= 0xfffe;
8377 	} else {
8378 		ELINK_DEBUG_P0(sc, "Disable 2.5G\n");
8379 		tmp1 &= 0xfffe;
8380 	}
8381 
8382 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
8383 	/* Add support for CL37 (passive mode) II */
8384 
8385 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
8386 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
8387 			 (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
8388 				  0x20 : 0x40)));
8389 
8390 	/* Add support for CL37 (passive mode) III */
8391 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8392 
8393 	/* The SNR will improve about 2db by changing BW and FEE main
8394 	 * tap. Rest commands are executed after link is up
8395 	 * Change FFE main cursor to 5 in EDC register
8396 	 */
8397 	if (elink_8073_is_snr_needed(sc, phy))
8398 		elink_cl45_write(sc, phy,
8399 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
8400 				 0xFB0C);
8401 
8402 	/* Enable FEC (Forware Error Correction) Request in the AN */
8403 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
8404 	tmp1 |= (1<<15);
8405 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
8406 
8407 	elink_ext_phy_set_pause(params, phy, vars);
8408 
8409 	/* Restart autoneg */
8410 	DELAY(1000 * 500);
8411 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8412 	ELINK_DEBUG_P2(sc, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
8413 		   ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
8414 	return ELINK_STATUS_OK;
8415 }
8416 
8417 static uint8_t elink_8073_read_status(struct elink_phy *phy,
8418 				 struct elink_params *params,
8419 				 struct elink_vars *vars)
8420 {
8421 	struct bxe_softc *sc = params->sc;
8422 	uint8_t link_up = 0;
8423 	uint16_t val1, val2;
8424 	uint16_t link_status = 0;
8425 	uint16_t an1000_status = 0;
8426 
8427 	elink_cl45_read(sc, phy,
8428 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
8429 
8430 	ELINK_DEBUG_P1(sc, "8703 LASI status 0x%x\n", val1);
8431 
8432 	/* Clear the interrupt LASI status register */
8433 	elink_cl45_read(sc, phy,
8434 			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
8435 	elink_cl45_read(sc, phy,
8436 			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
8437 	ELINK_DEBUG_P2(sc, "807x PCS status 0x%x->0x%x\n", val2, val1);
8438 	/* Clear MSG-OUT */
8439 	elink_cl45_read(sc, phy,
8440 			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
8441 
8442 	/* Check the LASI */
8443 	elink_cl45_read(sc, phy,
8444 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
8445 
8446 	ELINK_DEBUG_P1(sc, "KR 0x9003 0x%x\n", val2);
8447 
8448 	/* Check the link status */
8449 	elink_cl45_read(sc, phy,
8450 			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
8451 	ELINK_DEBUG_P1(sc, "KR PCS status 0x%x\n", val2);
8452 
8453 	elink_cl45_read(sc, phy,
8454 			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
8455 	elink_cl45_read(sc, phy,
8456 			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
8457 	link_up = ((val1 & 4) == 4);
8458 	ELINK_DEBUG_P1(sc, "PMA_REG_STATUS=0x%x\n", val1);
8459 
8460 	if (link_up &&
8461 	     ((phy->req_line_speed != ELINK_SPEED_10000))) {
8462 		if (elink_8073_xaui_wa(sc, phy) != 0)
8463 			return 0;
8464 	}
8465 	elink_cl45_read(sc, phy,
8466 			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
8467 	elink_cl45_read(sc, phy,
8468 			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
8469 
8470 	/* Check the link status on 1.1.2 */
8471 	elink_cl45_read(sc, phy,
8472 			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
8473 	elink_cl45_read(sc, phy,
8474 			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
8475 	ELINK_DEBUG_P3(sc, "KR PMA status 0x%x->0x%x,"
8476 		   "an_link_status=0x%x\n", val2, val1, an1000_status);
8477 
8478 	link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
8479 	if (link_up && elink_8073_is_snr_needed(sc, phy)) {
8480 		/* The SNR will improve about 2dbby changing the BW and FEE main
8481 		 * tap. The 1st write to change FFE main tap is set before
8482 		 * restart AN. Change PLL Bandwidth in EDC register
8483 		 */
8484 		elink_cl45_write(sc, phy,
8485 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
8486 				 0x26BC);
8487 
8488 		/* Change CDR Bandwidth in EDC register */
8489 		elink_cl45_write(sc, phy,
8490 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
8491 				 0x0333);
8492 	}
8493 	elink_cl45_read(sc, phy,
8494 			MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
8495 			&link_status);
8496 
8497 	/* Bits 0..2 --> speed detected, bits 13..15--> link is down */
8498 	if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
8499 		link_up = 1;
8500 		vars->line_speed = ELINK_SPEED_10000;
8501 		ELINK_DEBUG_P1(sc, "port %x: External link up in 10G\n",
8502 			   params->port);
8503 	} else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
8504 		link_up = 1;
8505 		vars->line_speed = ELINK_SPEED_2500;
8506 		ELINK_DEBUG_P1(sc, "port %x: External link up in 2.5G\n",
8507 			   params->port);
8508 	} else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
8509 		link_up = 1;
8510 		vars->line_speed = ELINK_SPEED_1000;
8511 		ELINK_DEBUG_P1(sc, "port %x: External link up in 1G\n",
8512 			   params->port);
8513 	} else {
8514 		link_up = 0;
8515 		ELINK_DEBUG_P1(sc, "port %x: External link is down\n",
8516 			   params->port);
8517 	}
8518 
8519 	if (link_up) {
8520 		/* Swap polarity if required */
8521 		if (params->lane_config &
8522 		    PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
8523 			/* Configure the 8073 to swap P and N of the KR lines */
8524 			elink_cl45_read(sc, phy,
8525 					MDIO_XS_DEVAD,
8526 					MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
8527 			/* Set bit 3 to invert Rx in 1G mode and clear this bit
8528 			 * when it`s in 10G mode.
8529 			 */
8530 			if (vars->line_speed == ELINK_SPEED_1000) {
8531 				ELINK_DEBUG_P0(sc, "Swapping 1G polarity for"
8532 					      "the 8073\n");
8533 				val1 |= (1<<3);
8534 			} else
8535 				val1 &= ~(1<<3);
8536 
8537 			elink_cl45_write(sc, phy,
8538 					 MDIO_XS_DEVAD,
8539 					 MDIO_XS_REG_8073_RX_CTRL_PCIE,
8540 					 val1);
8541 		}
8542 		elink_ext_phy_10G_an_resolve(sc, phy, vars);
8543 		elink_8073_resolve_fc(phy, params, vars);
8544 		vars->duplex = DUPLEX_FULL;
8545 	}
8546 
8547 	if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
8548 		elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
8549 				MDIO_AN_REG_LP_AUTO_NEG2, &val1);
8550 
8551 		if (val1 & (1<<5))
8552 			vars->link_status |=
8553 				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
8554 		if (val1 & (1<<7))
8555 			vars->link_status |=
8556 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
8557 	}
8558 
8559 	return link_up;
8560 }
8561 
8562 static void elink_8073_link_reset(struct elink_phy *phy,
8563 				  struct elink_params *params)
8564 {
8565 	struct bxe_softc *sc = params->sc;
8566 	uint8_t gpio_port;
8567 	if (CHIP_IS_E2(sc))
8568 		gpio_port = SC_PATH(sc);
8569 	else
8570 		gpio_port = params->port;
8571 	ELINK_DEBUG_P1(sc, "Setting 8073 port %d into low power mode\n",
8572 	   gpio_port);
8573 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8574 		       MISC_REGISTERS_GPIO_OUTPUT_LOW,
8575 		       gpio_port);
8576 }
8577 
8578 /******************************************************************/
8579 /*			BCM8705 PHY SECTION			  */
8580 /******************************************************************/
8581 static elink_status_t elink_8705_config_init(struct elink_phy *phy,
8582 				  struct elink_params *params,
8583 				  struct elink_vars *vars)
8584 {
8585 	struct bxe_softc *sc = params->sc;
8586 	ELINK_DEBUG_P0(sc, "init 8705\n");
8587 	/* Restore normal power mode*/
8588 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8589 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8590 	/* HW reset */
8591 	elink_ext_phy_hw_reset(sc, params->port);
8592 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
8593 	elink_wait_reset_complete(sc, phy, params);
8594 
8595 	elink_cl45_write(sc, phy,
8596 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
8597 	elink_cl45_write(sc, phy,
8598 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
8599 	elink_cl45_write(sc, phy,
8600 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
8601 	elink_cl45_write(sc, phy,
8602 			 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
8603 	/* BCM8705 doesn't have microcode, hence the 0 */
8604 	elink_save_spirom_version(sc, params->port, params->shmem_base, 0);
8605 	return ELINK_STATUS_OK;
8606 }
8607 
8608 static uint8_t elink_8705_read_status(struct elink_phy *phy,
8609 				 struct elink_params *params,
8610 				 struct elink_vars *vars)
8611 {
8612 	uint8_t link_up = 0;
8613 	uint16_t val1, rx_sd;
8614 	struct bxe_softc *sc = params->sc;
8615 	ELINK_DEBUG_P0(sc, "read status 8705\n");
8616 	elink_cl45_read(sc, phy,
8617 		      MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
8618 	ELINK_DEBUG_P1(sc, "8705 LASI status 0x%x\n", val1);
8619 
8620 	elink_cl45_read(sc, phy,
8621 		      MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
8622 	ELINK_DEBUG_P1(sc, "8705 LASI status 0x%x\n", val1);
8623 
8624 	elink_cl45_read(sc, phy,
8625 		      MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
8626 
8627 	elink_cl45_read(sc, phy,
8628 		      MDIO_PMA_DEVAD, 0xc809, &val1);
8629 	elink_cl45_read(sc, phy,
8630 		      MDIO_PMA_DEVAD, 0xc809, &val1);
8631 
8632 	ELINK_DEBUG_P1(sc, "8705 1.c809 val=0x%x\n", val1);
8633 	link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
8634 	if (link_up) {
8635 		vars->line_speed = ELINK_SPEED_10000;
8636 		elink_ext_phy_resolve_fc(phy, params, vars);
8637 	}
8638 	return link_up;
8639 }
8640 
8641 /******************************************************************/
8642 /*			SFP+ module Section			  */
8643 /******************************************************************/
8644 static void elink_set_disable_pmd_transmit(struct elink_params *params,
8645 					   struct elink_phy *phy,
8646 					   uint8_t pmd_dis)
8647 {
8648 	struct bxe_softc *sc = params->sc;
8649 	/* Disable transmitter only for bootcodes which can enable it afterwards
8650 	 * (for D3 link)
8651 	 */
8652 	if (pmd_dis) {
8653 		if (params->feature_config_flags &
8654 		     ELINK_FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED) {
8655 			ELINK_DEBUG_P0(sc, "Disabling PMD transmitter\n");
8656 		} else {
8657 			ELINK_DEBUG_P0(sc, "NOT disabling PMD transmitter\n");
8658 			return;
8659 		}
8660 	} else
8661 		ELINK_DEBUG_P0(sc, "Enabling PMD transmitter\n");
8662 	elink_cl45_write(sc, phy,
8663 			 MDIO_PMA_DEVAD,
8664 			 MDIO_PMA_REG_TX_DISABLE, pmd_dis);
8665 }
8666 
8667 static uint8_t elink_get_gpio_port(struct elink_params *params)
8668 {
8669 	uint8_t gpio_port;
8670 	uint32_t swap_val, swap_override;
8671 	struct bxe_softc *sc = params->sc;
8672 	if (CHIP_IS_E2(sc))
8673 		gpio_port = SC_PATH(sc);
8674 	else
8675 		gpio_port = params->port;
8676 	swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
8677 	swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
8678 	return gpio_port ^ (swap_val && swap_override);
8679 }
8680 
8681 static void elink_sfp_e1e2_set_transmitter(struct elink_params *params,
8682 					   struct elink_phy *phy,
8683 					   uint8_t tx_en)
8684 {
8685 	uint16_t val;
8686 	uint8_t port = params->port;
8687 	struct bxe_softc *sc = params->sc;
8688 	uint32_t tx_en_mode;
8689 
8690 	/* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
8691 	tx_en_mode = REG_RD(sc, params->shmem_base +
8692 			    offsetof(struct shmem_region,
8693 				     dev_info.port_hw_config[port].sfp_ctrl)) &
8694 		PORT_HW_CFG_TX_LASER_MASK;
8695 	ELINK_DEBUG_P3(sc, "Setting transmitter tx_en=%x for port %x "
8696 			   "mode = %x\n", tx_en, port, tx_en_mode);
8697 	switch (tx_en_mode) {
8698 	case PORT_HW_CFG_TX_LASER_MDIO:
8699 
8700 		elink_cl45_read(sc, phy,
8701 				MDIO_PMA_DEVAD,
8702 				MDIO_PMA_REG_PHY_IDENTIFIER,
8703 				&val);
8704 
8705 		if (tx_en)
8706 			val &= ~(1<<15);
8707 		else
8708 			val |= (1<<15);
8709 
8710 		elink_cl45_write(sc, phy,
8711 				 MDIO_PMA_DEVAD,
8712 				 MDIO_PMA_REG_PHY_IDENTIFIER,
8713 				 val);
8714 	break;
8715 	case PORT_HW_CFG_TX_LASER_GPIO0:
8716 	case PORT_HW_CFG_TX_LASER_GPIO1:
8717 	case PORT_HW_CFG_TX_LASER_GPIO2:
8718 	case PORT_HW_CFG_TX_LASER_GPIO3:
8719 	{
8720 		uint16_t gpio_pin;
8721 		uint8_t gpio_port, gpio_mode;
8722 		if (tx_en)
8723 			gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
8724 		else
8725 			gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
8726 
8727 		gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
8728 		gpio_port = elink_get_gpio_port(params);
8729 		elink_cb_gpio_write(sc, gpio_pin, gpio_mode, gpio_port);
8730 		break;
8731 	}
8732 	default:
8733 		ELINK_DEBUG_P1(sc, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode);
8734 		break;
8735 	}
8736 }
8737 
8738 static void elink_sfp_set_transmitter(struct elink_params *params,
8739 				      struct elink_phy *phy,
8740 				      uint8_t tx_en)
8741 {
8742 	struct bxe_softc *sc = params->sc;
8743 	ELINK_DEBUG_P1(sc, "Setting SFP+ transmitter to %d\n", tx_en);
8744 	if (CHIP_IS_E3(sc))
8745 		elink_sfp_e3_set_transmitter(params, phy, tx_en);
8746 	else
8747 		elink_sfp_e1e2_set_transmitter(params, phy, tx_en);
8748 }
8749 
8750 static elink_status_t elink_8726_read_sfp_module_eeprom(struct elink_phy *phy,
8751 					     struct elink_params *params,
8752 					     uint8_t dev_addr, uint16_t addr, uint8_t byte_cnt,
8753 					     uint8_t *o_buf, uint8_t is_init)
8754 {
8755 	struct bxe_softc *sc = params->sc;
8756 	uint16_t val = 0;
8757 	uint16_t i;
8758 	if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8759 		ELINK_DEBUG_P0(sc,
8760 		   "Reading from eeprom is limited to 0xf\n");
8761 		return ELINK_STATUS_ERROR;
8762 	}
8763 	/* Set the read command byte count */
8764 	elink_cl45_write(sc, phy,
8765 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
8766 			 (byte_cnt | (dev_addr << 8)));
8767 
8768 	/* Set the read command address */
8769 	elink_cl45_write(sc, phy,
8770 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
8771 			 addr);
8772 
8773 	/* Activate read command */
8774 	elink_cl45_write(sc, phy,
8775 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8776 			 0x2c0f);
8777 
8778 	/* Wait up to 500us for command complete status */
8779 	for (i = 0; i < 100; i++) {
8780 		elink_cl45_read(sc, phy,
8781 				MDIO_PMA_DEVAD,
8782 				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8783 		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8784 		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
8785 			break;
8786 		DELAY(5);
8787 	}
8788 
8789 	if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
8790 		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
8791 		ELINK_DEBUG_P1(sc,
8792 			 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
8793 			 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
8794 		return ELINK_STATUS_ERROR;
8795 	}
8796 
8797 	/* Read the buffer */
8798 	for (i = 0; i < byte_cnt; i++) {
8799 		elink_cl45_read(sc, phy,
8800 				MDIO_PMA_DEVAD,
8801 				MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
8802 		o_buf[i] = (uint8_t)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
8803 	}
8804 
8805 	for (i = 0; i < 100; i++) {
8806 		elink_cl45_read(sc, phy,
8807 				MDIO_PMA_DEVAD,
8808 				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8809 		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8810 		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
8811 			return ELINK_STATUS_OK;
8812 		DELAY(1000 * 1);
8813 	}
8814 	return ELINK_STATUS_ERROR;
8815 }
8816 
8817 static void elink_warpcore_power_module(struct elink_params *params,
8818 					uint8_t power)
8819 {
8820 	uint32_t pin_cfg;
8821 	struct bxe_softc *sc = params->sc;
8822 
8823 	pin_cfg = (REG_RD(sc, params->shmem_base +
8824 			  offsetof(struct shmem_region,
8825 			dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
8826 			PORT_HW_CFG_E3_PWR_DIS_MASK) >>
8827 			PORT_HW_CFG_E3_PWR_DIS_SHIFT;
8828 
8829 	if (pin_cfg == PIN_CFG_NA)
8830 		return;
8831 	ELINK_DEBUG_P2(sc, "Setting SFP+ module power to %d using pin cfg %d\n",
8832 		       power, pin_cfg);
8833 	/* Low ==> corresponding SFP+ module is powered
8834 	 * high ==> the SFP+ module is powered down
8835 	 */
8836 	elink_set_cfg_pin(sc, pin_cfg, power ^ 1);
8837 }
8838 static elink_status_t elink_warpcore_read_sfp_module_eeprom(struct elink_phy *phy,
8839 						 struct elink_params *params,
8840 						 uint8_t dev_addr,
8841 						 uint16_t addr, uint8_t byte_cnt,
8842 						 uint8_t *o_buf, uint8_t is_init)
8843 {
8844 	elink_status_t rc = ELINK_STATUS_OK;
8845 	uint8_t i, j = 0, cnt = 0;
8846 	uint32_t data_array[4];
8847 	uint16_t addr32;
8848 	struct bxe_softc *sc = params->sc;
8849 
8850 	if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8851 		ELINK_DEBUG_P0(sc,
8852 		   "Reading from eeprom is limited to 16 bytes\n");
8853 		return ELINK_STATUS_ERROR;
8854 	}
8855 
8856 	/* 4 byte aligned address */
8857 	addr32 = addr & (~0x3);
8858 	do {
8859 		if ((!is_init) && (cnt == I2C_WA_PWR_ITER)) {
8860 			elink_warpcore_power_module(params, 0);
8861 			/* Note that 100us are not enough here */
8862 			DELAY(1000 * 1);
8863 			elink_warpcore_power_module(params, 1);
8864 		}
8865 
8866 		elink_bsc_module_sel(params);
8867 		rc = elink_bsc_read(sc, dev_addr, addr32, 0, byte_cnt,
8868 				    data_array);
8869 	} while ((rc != ELINK_STATUS_OK) && (++cnt < I2C_WA_RETRY_CNT));
8870 
8871 	if (rc == ELINK_STATUS_OK) {
8872 		for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
8873 			o_buf[j] = *((uint8_t *)data_array + i);
8874 			j++;
8875 		}
8876 	}
8877 
8878 	return rc;
8879 }
8880 
8881 static elink_status_t elink_8727_read_sfp_module_eeprom(struct elink_phy *phy,
8882 					     struct elink_params *params,
8883 					     uint8_t dev_addr, uint16_t addr, uint8_t byte_cnt,
8884 					     uint8_t *o_buf, uint8_t is_init)
8885 {
8886 	struct bxe_softc *sc = params->sc;
8887 	uint16_t val, i;
8888 
8889 	if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8890 		ELINK_DEBUG_P0(sc,
8891 		   "Reading from eeprom is limited to 0xf\n");
8892 		return ELINK_STATUS_ERROR;
8893 	}
8894 
8895 	/* Set 2-wire transfer rate of SFP+ module EEPROM
8896 	 * to 100Khz since some DACs(direct attached cables) do
8897 	 * not work at 400Khz.
8898 	 */
8899 	elink_cl45_write(sc, phy,
8900 			 MDIO_PMA_DEVAD,
8901 			 MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
8902 			 ((dev_addr << 8) | 1));
8903 
8904 	/* Need to read from 1.8000 to clear it */
8905 	elink_cl45_read(sc, phy,
8906 			MDIO_PMA_DEVAD,
8907 			MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8908 			&val);
8909 
8910 	/* Set the read command byte count */
8911 	elink_cl45_write(sc, phy,
8912 			 MDIO_PMA_DEVAD,
8913 			 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
8914 			 ((byte_cnt < 2) ? 2 : byte_cnt));
8915 
8916 	/* Set the read command address */
8917 	elink_cl45_write(sc, phy,
8918 			 MDIO_PMA_DEVAD,
8919 			 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
8920 			 addr);
8921 	/* Set the destination address */
8922 	elink_cl45_write(sc, phy,
8923 			 MDIO_PMA_DEVAD,
8924 			 0x8004,
8925 			 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
8926 
8927 	/* Activate read command */
8928 	elink_cl45_write(sc, phy,
8929 			 MDIO_PMA_DEVAD,
8930 			 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8931 			 0x8002);
8932 	/* Wait appropriate time for two-wire command to finish before
8933 	 * polling the status register
8934 	 */
8935 	DELAY(1000 * 1);
8936 
8937 	/* Wait up to 500us for command complete status */
8938 	for (i = 0; i < 100; i++) {
8939 		elink_cl45_read(sc, phy,
8940 				MDIO_PMA_DEVAD,
8941 				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8942 		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8943 		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
8944 			break;
8945 		DELAY(5);
8946 	}
8947 
8948 	if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
8949 		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
8950 		ELINK_DEBUG_P1(sc,
8951 			 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
8952 			 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
8953 		return ELINK_STATUS_TIMEOUT;
8954 	}
8955 
8956 	/* Read the buffer */
8957 	for (i = 0; i < byte_cnt; i++) {
8958 		elink_cl45_read(sc, phy,
8959 				MDIO_PMA_DEVAD,
8960 				MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
8961 		o_buf[i] = (uint8_t)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
8962 	}
8963 
8964 	for (i = 0; i < 100; i++) {
8965 		elink_cl45_read(sc, phy,
8966 				MDIO_PMA_DEVAD,
8967 				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8968 		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8969 		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
8970 			return ELINK_STATUS_OK;
8971 		DELAY(1000 * 1);
8972 	}
8973 
8974 	return ELINK_STATUS_ERROR;
8975 }
8976 elink_status_t elink_read_sfp_module_eeprom(struct elink_phy *phy,
8977 				 struct elink_params *params, uint8_t dev_addr,
8978 				 uint16_t addr, uint16_t byte_cnt, uint8_t *o_buf)
8979 {
8980 	elink_status_t rc = 0;
8981 	struct bxe_softc *sc = params->sc;
8982 	uint8_t xfer_size;
8983 	uint8_t *user_data = o_buf;
8984 	read_sfp_module_eeprom_func_p read_func;
8985 	if ((dev_addr != 0xa0) && (dev_addr != 0xa2)) {
8986 		ELINK_DEBUG_P1(sc, "invalid dev_addr 0x%x\n", dev_addr);
8987 		return ELINK_STATUS_ERROR;
8988 	}
8989 
8990 	switch (phy->type) {
8991 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
8992 		read_func = elink_8726_read_sfp_module_eeprom;
8993 		break;
8994 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
8995 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
8996 		read_func = elink_8727_read_sfp_module_eeprom;
8997 		break;
8998 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
8999 		read_func = elink_warpcore_read_sfp_module_eeprom;
9000 		break;
9001 	default:
9002 		return ELINK_OP_NOT_SUPPORTED;
9003 	}
9004 
9005 	while (!rc && (byte_cnt > 0)) {
9006 		xfer_size = (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) ?
9007 			ELINK_SFP_EEPROM_PAGE_SIZE : byte_cnt;
9008 		rc = read_func(phy, params, dev_addr, addr, xfer_size,
9009 			       user_data, 0);
9010 		byte_cnt -= xfer_size;
9011 		user_data += xfer_size;
9012 		addr += xfer_size;
9013 	}
9014 	return rc;
9015 }
9016 
9017 static elink_status_t elink_get_edc_mode(struct elink_phy *phy,
9018 			      struct elink_params *params,
9019 			      uint16_t *edc_mode)
9020 {
9021 	struct bxe_softc *sc = params->sc;
9022 	uint32_t sync_offset = 0, phy_idx, media_types;
9023 	uint8_t val[ELINK_SFP_EEPROM_FC_TX_TECH_ADDR + 1], check_limiting_mode = 0;
9024 	*edc_mode = ELINK_EDC_MODE_LIMITING;
9025 	phy->media_type = ELINK_ETH_PHY_UNSPECIFIED;
9026 	/* First check for copper cable */
9027 	if (elink_read_sfp_module_eeprom(phy,
9028 					 params,
9029 					 ELINK_I2C_DEV_ADDR_A0,
9030 					 0,
9031 					 ELINK_SFP_EEPROM_FC_TX_TECH_ADDR + 1,
9032 					 (uint8_t *)val) != 0) {
9033 		ELINK_DEBUG_P0(sc, "Failed to read from SFP+ module EEPROM\n");
9034 		return ELINK_STATUS_ERROR;
9035 	}
9036 	params->link_attr_sync &= ~LINK_SFP_EEPROM_COMP_CODE_MASK;
9037 	params->link_attr_sync |= val[ELINK_SFP_EEPROM_10G_COMP_CODE_ADDR] <<
9038 		LINK_SFP_EEPROM_COMP_CODE_SHIFT;
9039 	elink_update_link_attr(params, params->link_attr_sync);
9040 	switch (val[ELINK_SFP_EEPROM_CON_TYPE_ADDR]) {
9041 	case ELINK_SFP_EEPROM_CON_TYPE_VAL_COPPER:
9042 	{
9043 		uint8_t copper_module_type;
9044 		phy->media_type = ELINK_ETH_PHY_DA_TWINAX;
9045 		/* Check if its active cable (includes SFP+ module)
9046 		 * of passive cable
9047 		 */
9048 		copper_module_type = val[ELINK_SFP_EEPROM_FC_TX_TECH_ADDR];
9049 		if (copper_module_type &
9050 		    ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
9051 			ELINK_DEBUG_P0(sc, "Active Copper cable detected\n");
9052 			if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
9053 				*edc_mode = ELINK_EDC_MODE_ACTIVE_DAC;
9054 			else
9055 				check_limiting_mode = 1;
9056 		} else {
9057 			*edc_mode = ELINK_EDC_MODE_PASSIVE_DAC;
9058 			/* Even in case PASSIVE_DAC indication is not set,
9059 			 * treat it as a passive DAC cable, since some cables
9060 			 * don't have this indication.
9061 			 */
9062 			if (copper_module_type &
9063 			    ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
9064 				ELINK_DEBUG_P0(sc,
9065 					       "Passive Copper cable detected\n");
9066 			} else {
9067 				ELINK_DEBUG_P0(sc,
9068 					       "Unknown copper-cable-type\n");
9069 			}
9070 		}
9071 		break;
9072 	}
9073 	case ELINK_SFP_EEPROM_CON_TYPE_VAL_UNKNOWN:
9074 	case ELINK_SFP_EEPROM_CON_TYPE_VAL_LC:
9075 	case ELINK_SFP_EEPROM_CON_TYPE_VAL_RJ45:
9076 		check_limiting_mode = 1;
9077 		/* Module is considered as 1G in case it's NOT compliant with
9078 		 * any 10G ethernet protocol, but is 1G Ethernet compliant.
9079 		 */
9080 		if (((val[ELINK_SFP_EEPROM_10G_COMP_CODE_ADDR] &
9081 		      (ELINK_SFP_EEPROM_10G_COMP_CODE_SR_MASK |
9082 		       ELINK_SFP_EEPROM_10G_COMP_CODE_LR_MASK |
9083 		       ELINK_SFP_EEPROM_10G_COMP_CODE_LRM_MASK)) == 0) &&
9084 		    (val[ELINK_SFP_EEPROM_1G_COMP_CODE_ADDR] != 0)) {
9085 			ELINK_DEBUG_P0(sc, "1G SFP module detected\n");
9086 			phy->media_type = ELINK_ETH_PHY_SFP_1G_FIBER;
9087 			if (phy->req_line_speed != ELINK_SPEED_1000) {
9088 				uint8_t gport = params->port;
9089 				phy->req_line_speed = ELINK_SPEED_1000;
9090 				if (!CHIP_IS_E1x(sc)) {
9091 					gport = SC_PATH(sc) +
9092 					(params->port << 1);
9093 				}
9094 				elink_cb_event_log(sc, ELINK_LOG_ID_NON_10G_MODULE, gport); //"Warning: Link speed was forced to 1000Mbps."
9095 				     // " Current SFP module in port %d is not"
9096 				     // " compliant with 10G Ethernet\n",
9097 			}
9098 
9099 			if (val[ELINK_SFP_EEPROM_1G_COMP_CODE_ADDR] &
9100 			    ELINK_SFP_EEPROM_1G_COMP_CODE_BASE_T) {
9101 				/* Some 1G-baseT modules will not link up,
9102 				 * unless TX_EN is toggled with long delay in
9103 				 * between.
9104 				 */
9105 				elink_sfp_set_transmitter(params, phy, 0);
9106 				DELAY(1000 * 40);
9107 				elink_sfp_set_transmitter(params, phy, 1);
9108 			}
9109 		} else {
9110 			int idx, cfg_idx = 0;
9111 			ELINK_DEBUG_P0(sc, "10G Optic module detected\n");
9112 			for (idx = ELINK_INT_PHY; idx < ELINK_MAX_PHYS; idx++) {
9113 				if (params->phy[idx].type == phy->type) {
9114 					cfg_idx = ELINK_LINK_CONFIG_IDX(idx);
9115 					break;
9116 				}
9117 			}
9118 			phy->media_type = ELINK_ETH_PHY_SFPP_10G_FIBER;
9119 			phy->req_line_speed = params->req_line_speed[cfg_idx];
9120 		}
9121 		break;
9122 	default:
9123 		ELINK_DEBUG_P1(sc, "Unable to determine module type 0x%x !!!\n",
9124 			 val[ELINK_SFP_EEPROM_CON_TYPE_ADDR]);
9125 		return ELINK_STATUS_ERROR;
9126 	}
9127 	sync_offset = params->shmem_base +
9128 		offsetof(struct shmem_region,
9129 			 dev_info.port_hw_config[params->port].media_type);
9130 	media_types = REG_RD(sc, sync_offset);
9131 	/* Update media type for non-PMF sync */
9132 	for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
9133 		if (&(params->phy[phy_idx]) == phy) {
9134 			media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
9135 				(PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
9136 			media_types |= ((phy->media_type &
9137 					PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
9138 				(PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
9139 			break;
9140 		}
9141 	}
9142 	REG_WR(sc, sync_offset, media_types);
9143 	if (check_limiting_mode) {
9144 		uint8_t options[ELINK_SFP_EEPROM_OPTIONS_SIZE];
9145 		if (elink_read_sfp_module_eeprom(phy,
9146 						 params,
9147 						 ELINK_I2C_DEV_ADDR_A0,
9148 						 ELINK_SFP_EEPROM_OPTIONS_ADDR,
9149 						 ELINK_SFP_EEPROM_OPTIONS_SIZE,
9150 						 options) != 0) {
9151 			ELINK_DEBUG_P0(sc,
9152 			   "Failed to read Option field from module EEPROM\n");
9153 			return ELINK_STATUS_ERROR;
9154 		}
9155 		if ((options[0] & ELINK_SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
9156 			*edc_mode = ELINK_EDC_MODE_LINEAR;
9157 		else
9158 			*edc_mode = ELINK_EDC_MODE_LIMITING;
9159 	}
9160 	ELINK_DEBUG_P1(sc, "EDC mode is set to 0x%x\n", *edc_mode);
9161 	return ELINK_STATUS_OK;
9162 }
9163 /* This function read the relevant field from the module (SFP+), and verify it
9164  * is compliant with this board
9165  */
9166 static elink_status_t elink_verify_sfp_module(struct elink_phy *phy,
9167 				   struct elink_params *params)
9168 {
9169 	struct bxe_softc *sc = params->sc;
9170 	uint32_t val, cmd;
9171 	uint32_t fw_resp, fw_cmd_param;
9172 	char vendor_name[ELINK_SFP_EEPROM_VENDOR_NAME_SIZE+1];
9173 	char vendor_pn[ELINK_SFP_EEPROM_PART_NO_SIZE+1];
9174 	phy->flags &= ~ELINK_FLAGS_SFP_NOT_APPROVED;
9175 	val = REG_RD(sc, params->shmem_base +
9176 			 offsetof(struct shmem_region, dev_info.
9177 				  port_feature_config[params->port].config));
9178 	if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9179 	    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
9180 		ELINK_DEBUG_P0(sc, "NOT enforcing module verification\n");
9181 		return ELINK_STATUS_OK;
9182 	}
9183 
9184 	if (params->feature_config_flags &
9185 	    ELINK_FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
9186 		/* Use specific phy request */
9187 		cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
9188 	} else if (params->feature_config_flags &
9189 		   ELINK_FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
9190 		/* Use first phy request only in case of non-dual media*/
9191 		if (ELINK_DUAL_MEDIA(params)) {
9192 			ELINK_DEBUG_P0(sc,
9193 			   "FW does not support OPT MDL verification\n");
9194 			return ELINK_STATUS_ERROR;
9195 		}
9196 		cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
9197 	} else {
9198 		/* No support in OPT MDL detection */
9199 		ELINK_DEBUG_P0(sc,
9200 		   "FW does not support OPT MDL verification\n");
9201 		return ELINK_STATUS_ERROR;
9202 	}
9203 
9204 	fw_cmd_param = ELINK_FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
9205 	fw_resp = elink_cb_fw_command(sc, cmd, fw_cmd_param);
9206 	if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
9207 		ELINK_DEBUG_P0(sc, "Approved module\n");
9208 		return ELINK_STATUS_OK;
9209 	}
9210 
9211 	/* Format the warning message */
9212 	if (elink_read_sfp_module_eeprom(phy,
9213 					 params,
9214 					 ELINK_I2C_DEV_ADDR_A0,
9215 					 ELINK_SFP_EEPROM_VENDOR_NAME_ADDR,
9216 					 ELINK_SFP_EEPROM_VENDOR_NAME_SIZE,
9217 					 (uint8_t *)vendor_name))
9218 		vendor_name[0] = '\0';
9219 	else
9220 		vendor_name[ELINK_SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
9221 	if (elink_read_sfp_module_eeprom(phy,
9222 					 params,
9223 					 ELINK_I2C_DEV_ADDR_A0,
9224 					 ELINK_SFP_EEPROM_PART_NO_ADDR,
9225 					 ELINK_SFP_EEPROM_PART_NO_SIZE,
9226 					 (uint8_t *)vendor_pn))
9227 		vendor_pn[0] = '\0';
9228 	else
9229 		vendor_pn[ELINK_SFP_EEPROM_PART_NO_SIZE] = '\0';
9230 
9231 	elink_cb_event_log(sc, ELINK_LOG_ID_UNQUAL_IO_MODULE, params->port, vendor_name, vendor_pn); // "Warning: Unqualified SFP+ module detected,"
9232 			     // " Port %d from %s part number %s\n",
9233 
9234 	if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
9235 	    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_WARNING_MSG)
9236 		phy->flags |= ELINK_FLAGS_SFP_NOT_APPROVED;
9237 	return ELINK_STATUS_ERROR;
9238 }
9239 
9240 static elink_status_t elink_wait_for_sfp_module_initialized(struct elink_phy *phy,
9241 						 struct elink_params *params)
9242 
9243 {
9244 	uint8_t val;
9245 	elink_status_t rc;
9246 	struct bxe_softc *sc = params->sc;
9247 	uint16_t timeout;
9248 	/* Initialization time after hot-plug may take up to 300ms for
9249 	 * some phys type ( e.g. JDSU )
9250 	 */
9251 
9252 	for (timeout = 0; timeout < 60; timeout++) {
9253 		if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
9254 			rc = elink_warpcore_read_sfp_module_eeprom(
9255 				phy, params, ELINK_I2C_DEV_ADDR_A0, 1, 1, &val,
9256 				1);
9257 		else
9258 			rc = elink_read_sfp_module_eeprom(phy, params,
9259 							  ELINK_I2C_DEV_ADDR_A0,
9260 							  1, 1, &val);
9261 		if (rc == 0) {
9262 			ELINK_DEBUG_P1(sc,
9263 			   "SFP+ module initialization took %d ms\n",
9264 			   timeout * 5);
9265 			return ELINK_STATUS_OK;
9266 		}
9267 		DELAY(1000 * 5);
9268 	}
9269 	rc = elink_read_sfp_module_eeprom(phy, params, ELINK_I2C_DEV_ADDR_A0,
9270 					  1, 1, &val);
9271 	return rc;
9272 }
9273 
9274 static void elink_8727_power_module(struct bxe_softc *sc,
9275 				    struct elink_phy *phy,
9276 				    uint8_t is_power_up) {
9277 	/* Make sure GPIOs are not using for LED mode */
9278 	uint16_t val;
9279 	/* In the GPIO register, bit 4 is use to determine if the GPIOs are
9280 	 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
9281 	 * output
9282 	 * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
9283 	 * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
9284 	 * where the 1st bit is the over-current(only input), and 2nd bit is
9285 	 * for power( only output )
9286 	 *
9287 	 * In case of NOC feature is disabled and power is up, set GPIO control
9288 	 *  as input to enable listening of over-current indication
9289 	 */
9290 	if (phy->flags & ELINK_FLAGS_NOC)
9291 		return;
9292 	if (is_power_up)
9293 		val = (1<<4);
9294 	else
9295 		/* Set GPIO control to OUTPUT, and set the power bit
9296 		 * to according to the is_power_up
9297 		 */
9298 		val = (1<<1);
9299 
9300 	elink_cl45_write(sc, phy,
9301 			 MDIO_PMA_DEVAD,
9302 			 MDIO_PMA_REG_8727_GPIO_CTRL,
9303 			 val);
9304 }
9305 
9306 static elink_status_t elink_8726_set_limiting_mode(struct bxe_softc *sc,
9307 					struct elink_phy *phy,
9308 					uint16_t edc_mode)
9309 {
9310 	uint16_t cur_limiting_mode;
9311 
9312 	elink_cl45_read(sc, phy,
9313 			MDIO_PMA_DEVAD,
9314 			MDIO_PMA_REG_ROM_VER2,
9315 			&cur_limiting_mode);
9316 	ELINK_DEBUG_P1(sc, "Current Limiting mode is 0x%x\n",
9317 		 cur_limiting_mode);
9318 
9319 	if (edc_mode == ELINK_EDC_MODE_LIMITING) {
9320 		ELINK_DEBUG_P0(sc, "Setting LIMITING MODE\n");
9321 		elink_cl45_write(sc, phy,
9322 				 MDIO_PMA_DEVAD,
9323 				 MDIO_PMA_REG_ROM_VER2,
9324 				 ELINK_EDC_MODE_LIMITING);
9325 	} else { /* LRM mode ( default )*/
9326 
9327 		ELINK_DEBUG_P0(sc, "Setting LRM MODE\n");
9328 
9329 		/* Changing to LRM mode takes quite few seconds. So do it only
9330 		 * if current mode is limiting (default is LRM)
9331 		 */
9332 		if (cur_limiting_mode != ELINK_EDC_MODE_LIMITING)
9333 			return ELINK_STATUS_OK;
9334 
9335 		elink_cl45_write(sc, phy,
9336 				 MDIO_PMA_DEVAD,
9337 				 MDIO_PMA_REG_LRM_MODE,
9338 				 0);
9339 		elink_cl45_write(sc, phy,
9340 				 MDIO_PMA_DEVAD,
9341 				 MDIO_PMA_REG_ROM_VER2,
9342 				 0x128);
9343 		elink_cl45_write(sc, phy,
9344 				 MDIO_PMA_DEVAD,
9345 				 MDIO_PMA_REG_MISC_CTRL0,
9346 				 0x4008);
9347 		elink_cl45_write(sc, phy,
9348 				 MDIO_PMA_DEVAD,
9349 				 MDIO_PMA_REG_LRM_MODE,
9350 				 0xaaaa);
9351 	}
9352 	return ELINK_STATUS_OK;
9353 }
9354 
9355 static elink_status_t elink_8727_set_limiting_mode(struct bxe_softc *sc,
9356 					struct elink_phy *phy,
9357 					uint16_t edc_mode)
9358 {
9359 	uint16_t phy_identifier;
9360 	uint16_t rom_ver2_val;
9361 	elink_cl45_read(sc, phy,
9362 			MDIO_PMA_DEVAD,
9363 			MDIO_PMA_REG_PHY_IDENTIFIER,
9364 			&phy_identifier);
9365 
9366 	elink_cl45_write(sc, phy,
9367 			 MDIO_PMA_DEVAD,
9368 			 MDIO_PMA_REG_PHY_IDENTIFIER,
9369 			 (phy_identifier & ~(1<<9)));
9370 
9371 	elink_cl45_read(sc, phy,
9372 			MDIO_PMA_DEVAD,
9373 			MDIO_PMA_REG_ROM_VER2,
9374 			&rom_ver2_val);
9375 	/* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
9376 	elink_cl45_write(sc, phy,
9377 			 MDIO_PMA_DEVAD,
9378 			 MDIO_PMA_REG_ROM_VER2,
9379 			 (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
9380 
9381 	elink_cl45_write(sc, phy,
9382 			 MDIO_PMA_DEVAD,
9383 			 MDIO_PMA_REG_PHY_IDENTIFIER,
9384 			 (phy_identifier | (1<<9)));
9385 
9386 	return ELINK_STATUS_OK;
9387 }
9388 
9389 static void elink_8727_specific_func(struct elink_phy *phy,
9390 				     struct elink_params *params,
9391 				     uint32_t action)
9392 {
9393 	struct bxe_softc *sc = params->sc;
9394 	uint16_t val;
9395 	switch (action) {
9396 	case ELINK_DISABLE_TX:
9397 		elink_sfp_set_transmitter(params, phy, 0);
9398 		break;
9399 	case ELINK_ENABLE_TX:
9400 		if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED))
9401 			elink_sfp_set_transmitter(params, phy, 1);
9402 		break;
9403 	case ELINK_PHY_INIT:
9404 		elink_cl45_write(sc, phy,
9405 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9406 				 (1<<2) | (1<<5));
9407 		elink_cl45_write(sc, phy,
9408 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
9409 				 0);
9410 		elink_cl45_write(sc, phy,
9411 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x0006);
9412 		/* Make MOD_ABS give interrupt on change */
9413 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9414 				MDIO_PMA_REG_8727_PCS_OPT_CTRL,
9415 				&val);
9416 		val |= (1<<12);
9417 		if (phy->flags & ELINK_FLAGS_NOC)
9418 			val |= (3<<5);
9419 		/* Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
9420 		 * status which reflect SFP+ module over-current
9421 		 */
9422 		if (!(phy->flags & ELINK_FLAGS_NOC))
9423 			val &= 0xff8f; /* Reset bits 4-6 */
9424 		elink_cl45_write(sc, phy,
9425 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
9426 				 val);
9427 		break;
9428 	default:
9429 		ELINK_DEBUG_P1(sc, "Function 0x%x not supported by 8727\n",
9430 		   action);
9431 		return;
9432 	}
9433 }
9434 
9435 static void elink_set_e1e2_module_fault_led(struct elink_params *params,
9436 					   uint8_t gpio_mode)
9437 {
9438 	struct bxe_softc *sc = params->sc;
9439 
9440 	uint32_t fault_led_gpio = REG_RD(sc, params->shmem_base +
9441 			    offsetof(struct shmem_region,
9442 			dev_info.port_hw_config[params->port].sfp_ctrl)) &
9443 		PORT_HW_CFG_FAULT_MODULE_LED_MASK;
9444 	switch (fault_led_gpio) {
9445 	case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
9446 		return;
9447 	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
9448 	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
9449 	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
9450 	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
9451 	{
9452 		uint8_t gpio_port = elink_get_gpio_port(params);
9453 		uint16_t gpio_pin = fault_led_gpio -
9454 			PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
9455 		ELINK_DEBUG_P3(sc, "Set fault module-detected led "
9456 				   "pin %x port %x mode %x\n",
9457 			       gpio_pin, gpio_port, gpio_mode);
9458 		elink_cb_gpio_write(sc, gpio_pin, gpio_mode, gpio_port);
9459 	}
9460 	break;
9461 	default:
9462 		ELINK_DEBUG_P1(sc, "Error: Invalid fault led mode 0x%x\n",
9463 			       fault_led_gpio);
9464 	}
9465 }
9466 
9467 static void elink_set_e3_module_fault_led(struct elink_params *params,
9468 					  uint8_t gpio_mode)
9469 {
9470 	uint32_t pin_cfg;
9471 	uint8_t port = params->port;
9472 	struct bxe_softc *sc = params->sc;
9473 	pin_cfg = (REG_RD(sc, params->shmem_base +
9474 			 offsetof(struct shmem_region,
9475 				  dev_info.port_hw_config[port].e3_sfp_ctrl)) &
9476 		PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >>
9477 		PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT;
9478 	ELINK_DEBUG_P2(sc, "Setting Fault LED to %d using pin cfg %d\n",
9479 		       gpio_mode, pin_cfg);
9480 	elink_set_cfg_pin(sc, pin_cfg, gpio_mode);
9481 }
9482 
9483 static void elink_set_sfp_module_fault_led(struct elink_params *params,
9484 					   uint8_t gpio_mode)
9485 {
9486 	struct bxe_softc *sc = params->sc;
9487 	ELINK_DEBUG_P1(sc, "Setting SFP+ module fault LED to %d\n", gpio_mode);
9488 	if (CHIP_IS_E3(sc)) {
9489 		/* Low ==> if SFP+ module is supported otherwise
9490 		 * High ==> if SFP+ module is not on the approved vendor list
9491 		 */
9492 		elink_set_e3_module_fault_led(params, gpio_mode);
9493 	} else
9494 		elink_set_e1e2_module_fault_led(params, gpio_mode);
9495 }
9496 
9497 static void elink_warpcore_hw_reset(struct elink_phy *phy,
9498 				    struct elink_params *params)
9499 {
9500 	struct bxe_softc *sc = params->sc;
9501 	elink_warpcore_power_module(params, 0);
9502 	/* Put Warpcore in low power mode */
9503 	REG_WR(sc, MISC_REG_WC0_RESET, 0x0c0e);
9504 
9505 	/* Put LCPLL in low power mode */
9506 	REG_WR(sc, MISC_REG_LCPLL_E40_PWRDWN, 1);
9507 	REG_WR(sc, MISC_REG_LCPLL_E40_RESETB_ANA, 0);
9508 	REG_WR(sc, MISC_REG_LCPLL_E40_RESETB_DIG, 0);
9509 }
9510 
9511 static void elink_power_sfp_module(struct elink_params *params,
9512 				   struct elink_phy *phy,
9513 				   uint8_t power)
9514 {
9515 	struct bxe_softc *sc = params->sc;
9516 	ELINK_DEBUG_P1(sc, "Setting SFP+ power to %x\n", power);
9517 
9518 	switch (phy->type) {
9519 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
9520 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
9521 		elink_8727_power_module(params->sc, phy, power);
9522 		break;
9523 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
9524 		elink_warpcore_power_module(params, power);
9525 		break;
9526 	default:
9527 		break;
9528 	}
9529 }
9530 static void elink_warpcore_set_limiting_mode(struct elink_params *params,
9531 					     struct elink_phy *phy,
9532 					     uint16_t edc_mode)
9533 {
9534 	uint16_t val = 0;
9535 	uint16_t mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
9536 	struct bxe_softc *sc = params->sc;
9537 
9538 	uint8_t lane = elink_get_warpcore_lane(phy, params);
9539 	/* This is a global register which controls all lanes */
9540 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
9541 			MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
9542 	val &= ~(0xf << (lane << 2));
9543 
9544 	switch (edc_mode) {
9545 	case ELINK_EDC_MODE_LINEAR:
9546 	case ELINK_EDC_MODE_LIMITING:
9547 		mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
9548 		break;
9549 	case ELINK_EDC_MODE_PASSIVE_DAC:
9550 	case ELINK_EDC_MODE_ACTIVE_DAC:
9551 		mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC;
9552 		break;
9553 	default:
9554 		break;
9555 	}
9556 
9557 	val |= (mode << (lane << 2));
9558 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
9559 			 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val);
9560 	/* A must read */
9561 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
9562 			MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
9563 
9564 	/* Restart microcode to re-read the new mode */
9565 	elink_warpcore_reset_lane(sc, phy, 1);
9566 	elink_warpcore_reset_lane(sc, phy, 0);
9567 
9568 }
9569 
9570 static void elink_set_limiting_mode(struct elink_params *params,
9571 				    struct elink_phy *phy,
9572 				    uint16_t edc_mode)
9573 {
9574 	switch (phy->type) {
9575 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
9576 		elink_8726_set_limiting_mode(params->sc, phy, edc_mode);
9577 		break;
9578 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
9579 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
9580 		elink_8727_set_limiting_mode(params->sc, phy, edc_mode);
9581 		break;
9582 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
9583 		elink_warpcore_set_limiting_mode(params, phy, edc_mode);
9584 		break;
9585 	}
9586 }
9587 
9588 elink_status_t elink_sfp_module_detection(struct elink_phy *phy,
9589 			       struct elink_params *params)
9590 {
9591 	struct bxe_softc *sc = params->sc;
9592 	uint16_t edc_mode;
9593 	elink_status_t rc = ELINK_STATUS_OK;
9594 
9595 	uint32_t val = REG_RD(sc, params->shmem_base +
9596 			     offsetof(struct shmem_region, dev_info.
9597 				     port_feature_config[params->port].config));
9598 	/* Enabled transmitter by default */
9599 	elink_sfp_set_transmitter(params, phy, 1);
9600 	ELINK_DEBUG_P1(sc, "SFP+ module plugged in/out detected on port %d\n",
9601 		 params->port);
9602 	/* Power up module */
9603 	elink_power_sfp_module(params, phy, 1);
9604 	if (elink_get_edc_mode(phy, params, &edc_mode) != 0) {
9605 		ELINK_DEBUG_P0(sc, "Failed to get valid module type\n");
9606 		return ELINK_STATUS_ERROR;
9607 	} else if (elink_verify_sfp_module(phy, params) != 0) {
9608 		/* Check SFP+ module compatibility */
9609 		ELINK_DEBUG_P0(sc, "Module verification failed!!\n");
9610 		rc = ELINK_STATUS_ERROR;
9611 		/* Turn on fault module-detected led */
9612 		elink_set_sfp_module_fault_led(params,
9613 					       MISC_REGISTERS_GPIO_HIGH);
9614 
9615 		/* Check if need to power down the SFP+ module */
9616 		if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9617 		     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) {
9618 			ELINK_DEBUG_P0(sc, "Shutdown SFP+ module!!\n");
9619 			elink_power_sfp_module(params, phy, 0);
9620 			return rc;
9621 		}
9622 	} else {
9623 		/* Turn off fault module-detected led */
9624 		elink_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
9625 	}
9626 
9627 	/* Check and set limiting mode / LRM mode on 8726. On 8727 it
9628 	 * is done automatically
9629 	 */
9630 	elink_set_limiting_mode(params, phy, edc_mode);
9631 
9632 	/* Disable transmit for this module if the module is not approved, and
9633 	 * laser needs to be disabled.
9634 	 */
9635 	if ((rc != 0) &&
9636 	    ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9637 	     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER))
9638 		elink_sfp_set_transmitter(params, phy, 0);
9639 
9640 	return rc;
9641 }
9642 
9643 void elink_handle_module_detect_int(struct elink_params *params)
9644 {
9645 	struct bxe_softc *sc = params->sc;
9646 	struct elink_phy *phy;
9647 	uint32_t gpio_val;
9648 	uint8_t gpio_num, gpio_port;
9649 	if (CHIP_IS_E3(sc)) {
9650 		phy = &params->phy[ELINK_INT_PHY];
9651 		/* Always enable TX laser,will be disabled in case of fault */
9652 		elink_sfp_set_transmitter(params, phy, 1);
9653 	} else {
9654 		phy = &params->phy[ELINK_EXT_PHY1];
9655 	}
9656 	if (elink_get_mod_abs_int_cfg(sc, params->chip_id, params->shmem_base,
9657 				      params->port, &gpio_num, &gpio_port) ==
9658 	    ELINK_STATUS_ERROR) {
9659 		ELINK_DEBUG_P0(sc, "Failed to get MOD_ABS interrupt config\n");
9660 		return;
9661 	}
9662 
9663 	/* Set valid module led off */
9664 	elink_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
9665 
9666 	/* Get current gpio val reflecting module plugged in / out*/
9667 	gpio_val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
9668 
9669 	/* Call the handling function in case module is detected */
9670 	if (gpio_val == 0) {
9671 		elink_set_mdio_emac_per_phy(sc, params);
9672 		elink_set_aer_mmd(params, phy);
9673 
9674 		elink_power_sfp_module(params, phy, 1);
9675 		elink_cb_gpio_int_write(sc, gpio_num,
9676 				   MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
9677 				   gpio_port);
9678 		if (elink_wait_for_sfp_module_initialized(phy, params) == 0) {
9679 			elink_sfp_module_detection(phy, params);
9680 			if (CHIP_IS_E3(sc)) {
9681 				uint16_t rx_tx_in_reset;
9682 				/* In case WC is out of reset, reconfigure the
9683 				 * link speed while taking into account 1G
9684 				 * module limitation.
9685 				 */
9686 				elink_cl45_read(sc, phy,
9687 						MDIO_WC_DEVAD,
9688 						MDIO_WC_REG_DIGITAL5_MISC6,
9689 						&rx_tx_in_reset);
9690 				if ((!rx_tx_in_reset) &&
9691 				    (params->link_flags &
9692 				     ELINK_PHY_INITIALIZED)) {
9693 					elink_warpcore_reset_lane(sc, phy, 1);
9694 					elink_warpcore_config_sfi(phy, params);
9695 					elink_warpcore_reset_lane(sc, phy, 0);
9696 				}
9697 			}
9698 		} else {
9699 			ELINK_DEBUG_P0(sc, "SFP+ module is not initialized\n");
9700 		}
9701 	} else {
9702 		elink_cb_gpio_int_write(sc, gpio_num,
9703 				   MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
9704 				   gpio_port);
9705 		/* Module was plugged out.
9706 		 * Disable transmit for this module
9707 		 */
9708 		phy->media_type = ELINK_ETH_PHY_NOT_PRESENT;
9709 	}
9710 }
9711 
9712 /******************************************************************/
9713 /*		Used by 8706 and 8727                             */
9714 /******************************************************************/
9715 static void elink_sfp_mask_fault(struct bxe_softc *sc,
9716 				 struct elink_phy *phy,
9717 				 uint16_t alarm_status_offset,
9718 				 uint16_t alarm_ctrl_offset)
9719 {
9720 	uint16_t alarm_status, val;
9721 	elink_cl45_read(sc, phy,
9722 			MDIO_PMA_DEVAD, alarm_status_offset,
9723 			&alarm_status);
9724 	elink_cl45_read(sc, phy,
9725 			MDIO_PMA_DEVAD, alarm_status_offset,
9726 			&alarm_status);
9727 	/* Mask or enable the fault event. */
9728 	elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
9729 	if (alarm_status & (1<<0))
9730 		val &= ~(1<<0);
9731 	else
9732 		val |= (1<<0);
9733 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
9734 }
9735 /******************************************************************/
9736 /*		common BCM8706/BCM8726 PHY SECTION		  */
9737 /******************************************************************/
9738 static uint8_t elink_8706_8726_read_status(struct elink_phy *phy,
9739 				      struct elink_params *params,
9740 				      struct elink_vars *vars)
9741 {
9742 	uint8_t link_up = 0;
9743 	uint16_t val1, val2, rx_sd, pcs_status;
9744 	struct bxe_softc *sc = params->sc;
9745 	ELINK_DEBUG_P0(sc, "XGXS 8706/8726\n");
9746 	/* Clear RX Alarm*/
9747 	elink_cl45_read(sc, phy,
9748 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
9749 
9750 	elink_sfp_mask_fault(sc, phy, MDIO_PMA_LASI_TXSTAT,
9751 			     MDIO_PMA_LASI_TXCTRL);
9752 
9753 	/* Clear LASI indication*/
9754 	elink_cl45_read(sc, phy,
9755 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
9756 	elink_cl45_read(sc, phy,
9757 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
9758 	ELINK_DEBUG_P2(sc, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
9759 
9760 	elink_cl45_read(sc, phy,
9761 			MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
9762 	elink_cl45_read(sc, phy,
9763 			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
9764 	elink_cl45_read(sc, phy,
9765 			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
9766 	elink_cl45_read(sc, phy,
9767 			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
9768 
9769 	ELINK_DEBUG_P3(sc, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
9770 			" link_status 0x%x\n", rx_sd, pcs_status, val2);
9771 	/* Link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
9772 	 * are set, or if the autoneg bit 1 is set
9773 	 */
9774 	link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
9775 	if (link_up) {
9776 		if (val2 & (1<<1))
9777 			vars->line_speed = ELINK_SPEED_1000;
9778 		else
9779 			vars->line_speed = ELINK_SPEED_10000;
9780 		elink_ext_phy_resolve_fc(phy, params, vars);
9781 		vars->duplex = DUPLEX_FULL;
9782 	}
9783 
9784 	/* Capture 10G link fault. Read twice to clear stale value. */
9785 	if (vars->line_speed == ELINK_SPEED_10000) {
9786 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9787 			    MDIO_PMA_LASI_TXSTAT, &val1);
9788 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9789 			    MDIO_PMA_LASI_TXSTAT, &val1);
9790 		if (val1 & (1<<0))
9791 			vars->fault_detected = 1;
9792 	}
9793 
9794 	return link_up;
9795 }
9796 
9797 /******************************************************************/
9798 /*			BCM8706 PHY SECTION			  */
9799 /******************************************************************/
9800 static uint8_t elink_8706_config_init(struct elink_phy *phy,
9801 				 struct elink_params *params,
9802 				 struct elink_vars *vars)
9803 {
9804 	uint32_t tx_en_mode;
9805 	uint16_t cnt, val, tmp1;
9806 	struct bxe_softc *sc = params->sc;
9807 
9808 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
9809 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
9810 	/* HW reset */
9811 	elink_ext_phy_hw_reset(sc, params->port);
9812 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
9813 	elink_wait_reset_complete(sc, phy, params);
9814 
9815 	/* Wait until fw is loaded */
9816 	for (cnt = 0; cnt < 100; cnt++) {
9817 		elink_cl45_read(sc, phy,
9818 				MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
9819 		if (val)
9820 			break;
9821 		DELAY(1000 * 10);
9822 	}
9823 	ELINK_DEBUG_P1(sc, "XGXS 8706 is initialized after %d ms\n", cnt);
9824 	if ((params->feature_config_flags &
9825 	     ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
9826 		uint8_t i;
9827 		uint16_t reg;
9828 		for (i = 0; i < 4; i++) {
9829 			reg = MDIO_XS_8706_REG_BANK_RX0 +
9830 				i*(MDIO_XS_8706_REG_BANK_RX1 -
9831 				   MDIO_XS_8706_REG_BANK_RX0);
9832 			elink_cl45_read(sc, phy, MDIO_XS_DEVAD, reg, &val);
9833 			/* Clear first 3 bits of the control */
9834 			val &= ~0x7;
9835 			/* Set control bits according to configuration */
9836 			val |= (phy->rx_preemphasis[i] & 0x7);
9837 			ELINK_DEBUG_P2(sc, "Setting RX Equalizer to BCM8706"
9838 				   " reg 0x%x <-- val 0x%x\n", reg, val);
9839 			elink_cl45_write(sc, phy, MDIO_XS_DEVAD, reg, val);
9840 		}
9841 	}
9842 	/* Force speed */
9843 	if (phy->req_line_speed == ELINK_SPEED_10000) {
9844 		ELINK_DEBUG_P0(sc, "XGXS 8706 force 10Gbps\n");
9845 
9846 		elink_cl45_write(sc, phy,
9847 				 MDIO_PMA_DEVAD,
9848 				 MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
9849 		elink_cl45_write(sc, phy,
9850 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
9851 				 0);
9852 		/* Arm LASI for link and Tx fault. */
9853 		elink_cl45_write(sc, phy,
9854 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 3);
9855 	} else {
9856 		/* Force 1Gbps using autoneg with 1G advertisement */
9857 
9858 		/* Allow CL37 through CL73 */
9859 		ELINK_DEBUG_P0(sc, "XGXS 8706 AutoNeg\n");
9860 		elink_cl45_write(sc, phy,
9861 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
9862 
9863 		/* Enable Full-Duplex advertisement on CL37 */
9864 		elink_cl45_write(sc, phy,
9865 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
9866 		/* Enable CL37 AN */
9867 		elink_cl45_write(sc, phy,
9868 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
9869 		/* 1G support */
9870 		elink_cl45_write(sc, phy,
9871 				 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
9872 
9873 		/* Enable clause 73 AN */
9874 		elink_cl45_write(sc, phy,
9875 				 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
9876 		elink_cl45_write(sc, phy,
9877 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9878 				 0x0400);
9879 		elink_cl45_write(sc, phy,
9880 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
9881 				 0x0004);
9882 	}
9883 	elink_save_bcm_spirom_ver(sc, phy, params->port);
9884 
9885 	/* If TX Laser is controlled by GPIO_0, do not let PHY go into low
9886 	 * power mode, if TX Laser is disabled
9887 	 */
9888 
9889 	tx_en_mode = REG_RD(sc, params->shmem_base +
9890 			    offsetof(struct shmem_region,
9891 				dev_info.port_hw_config[params->port].sfp_ctrl))
9892 			& PORT_HW_CFG_TX_LASER_MASK;
9893 
9894 	if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
9895 		ELINK_DEBUG_P0(sc, "Enabling TXONOFF_PWRDN_DIS\n");
9896 		elink_cl45_read(sc, phy,
9897 			MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
9898 		tmp1 |= 0x1;
9899 		elink_cl45_write(sc, phy,
9900 			MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
9901 	}
9902 
9903 	return ELINK_STATUS_OK;
9904 }
9905 
9906 static elink_status_t elink_8706_read_status(struct elink_phy *phy,
9907 				  struct elink_params *params,
9908 				  struct elink_vars *vars)
9909 {
9910 	return elink_8706_8726_read_status(phy, params, vars);
9911 }
9912 
9913 /******************************************************************/
9914 /*			BCM8726 PHY SECTION			  */
9915 /******************************************************************/
9916 static void elink_8726_config_loopback(struct elink_phy *phy,
9917 				       struct elink_params *params)
9918 {
9919 	struct bxe_softc *sc = params->sc;
9920 	ELINK_DEBUG_P0(sc, "PMA/PMD ext_phy_loopback: 8726\n");
9921 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
9922 }
9923 
9924 static void elink_8726_external_rom_boot(struct elink_phy *phy,
9925 					 struct elink_params *params)
9926 {
9927 	struct bxe_softc *sc = params->sc;
9928 	/* Need to wait 100ms after reset */
9929 	DELAY(1000 * 100);
9930 
9931 	/* Micro controller re-boot */
9932 	elink_cl45_write(sc, phy,
9933 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
9934 
9935 	/* Set soft reset */
9936 	elink_cl45_write(sc, phy,
9937 			 MDIO_PMA_DEVAD,
9938 			 MDIO_PMA_REG_GEN_CTRL,
9939 			 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
9940 
9941 	elink_cl45_write(sc, phy,
9942 			 MDIO_PMA_DEVAD,
9943 			 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
9944 
9945 	elink_cl45_write(sc, phy,
9946 			 MDIO_PMA_DEVAD,
9947 			 MDIO_PMA_REG_GEN_CTRL,
9948 			 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
9949 
9950 	/* Wait for 150ms for microcode load */
9951 	DELAY(1000 * 150);
9952 
9953 	/* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
9954 	elink_cl45_write(sc, phy,
9955 			 MDIO_PMA_DEVAD,
9956 			 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
9957 
9958 	DELAY(1000 * 200);
9959 	elink_save_bcm_spirom_ver(sc, phy, params->port);
9960 }
9961 
9962 static uint8_t elink_8726_read_status(struct elink_phy *phy,
9963 				 struct elink_params *params,
9964 				 struct elink_vars *vars)
9965 {
9966 	struct bxe_softc *sc = params->sc;
9967 	uint16_t val1;
9968 	uint8_t link_up = elink_8706_8726_read_status(phy, params, vars);
9969 	if (link_up) {
9970 		elink_cl45_read(sc, phy,
9971 				MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
9972 				&val1);
9973 		if (val1 & (1<<15)) {
9974 			ELINK_DEBUG_P0(sc, "Tx is disabled\n");
9975 			link_up = 0;
9976 			vars->line_speed = 0;
9977 		}
9978 	}
9979 	return link_up;
9980 }
9981 
9982 
9983 static elink_status_t elink_8726_config_init(struct elink_phy *phy,
9984 				  struct elink_params *params,
9985 				  struct elink_vars *vars)
9986 {
9987 	struct bxe_softc *sc = params->sc;
9988 	ELINK_DEBUG_P0(sc, "Initializing BCM8726\n");
9989 
9990 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
9991 	elink_wait_reset_complete(sc, phy, params);
9992 
9993 	elink_8726_external_rom_boot(phy, params);
9994 
9995 	/* Need to call module detected on initialization since the module
9996 	 * detection triggered by actual module insertion might occur before
9997 	 * driver is loaded, and when driver is loaded, it reset all
9998 	 * registers, including the transmitter
9999 	 */
10000 	elink_sfp_module_detection(phy, params);
10001 
10002 	if (phy->req_line_speed == ELINK_SPEED_1000) {
10003 		ELINK_DEBUG_P0(sc, "Setting 1G force\n");
10004 		elink_cl45_write(sc, phy,
10005 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
10006 		elink_cl45_write(sc, phy,
10007 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
10008 		elink_cl45_write(sc, phy,
10009 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x5);
10010 		elink_cl45_write(sc, phy,
10011 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
10012 				 0x400);
10013 	} else if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10014 		   (phy->speed_cap_mask &
10015 		      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
10016 		   ((phy->speed_cap_mask &
10017 		      PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
10018 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
10019 		ELINK_DEBUG_P0(sc, "Setting 1G clause37\n");
10020 		/* Set Flow control */
10021 		elink_ext_phy_set_pause(params, phy, vars);
10022 		elink_cl45_write(sc, phy,
10023 				 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
10024 		elink_cl45_write(sc, phy,
10025 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
10026 		elink_cl45_write(sc, phy,
10027 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
10028 		elink_cl45_write(sc, phy,
10029 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
10030 		elink_cl45_write(sc, phy,
10031 				MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
10032 		/* Enable RX-ALARM control to receive interrupt for 1G speed
10033 		 * change
10034 		 */
10035 		elink_cl45_write(sc, phy,
10036 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x4);
10037 		elink_cl45_write(sc, phy,
10038 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
10039 				 0x400);
10040 
10041 	} else { /* Default 10G. Set only LASI control */
10042 		elink_cl45_write(sc, phy,
10043 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 1);
10044 	}
10045 
10046 	/* Set TX PreEmphasis if needed */
10047 	if ((params->feature_config_flags &
10048 	     ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
10049 		ELINK_DEBUG_P2(sc,
10050 		   "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
10051 			 phy->tx_preemphasis[0],
10052 			 phy->tx_preemphasis[1]);
10053 		elink_cl45_write(sc, phy,
10054 				 MDIO_PMA_DEVAD,
10055 				 MDIO_PMA_REG_8726_TX_CTRL1,
10056 				 phy->tx_preemphasis[0]);
10057 
10058 		elink_cl45_write(sc, phy,
10059 				 MDIO_PMA_DEVAD,
10060 				 MDIO_PMA_REG_8726_TX_CTRL2,
10061 				 phy->tx_preemphasis[1]);
10062 	}
10063 
10064 	return ELINK_STATUS_OK;
10065 
10066 }
10067 
10068 static void elink_8726_link_reset(struct elink_phy *phy,
10069 				  struct elink_params *params)
10070 {
10071 	struct bxe_softc *sc = params->sc;
10072 	ELINK_DEBUG_P1(sc, "elink_8726_link_reset port %d\n", params->port);
10073 	/* Set serial boot control for external load */
10074 	elink_cl45_write(sc, phy,
10075 			 MDIO_PMA_DEVAD,
10076 			 MDIO_PMA_REG_GEN_CTRL, 0x0001);
10077 }
10078 
10079 /******************************************************************/
10080 /*			BCM8727 PHY SECTION			  */
10081 /******************************************************************/
10082 
10083 static void elink_8727_set_link_led(struct elink_phy *phy,
10084 				    struct elink_params *params, uint8_t mode)
10085 {
10086 	struct bxe_softc *sc = params->sc;
10087 	uint16_t led_mode_bitmask = 0;
10088 	uint16_t gpio_pins_bitmask = 0;
10089 	uint16_t val;
10090 	/* Only NOC flavor requires to set the LED specifically */
10091 	if (!(phy->flags & ELINK_FLAGS_NOC))
10092 		return;
10093 	switch (mode) {
10094 	case ELINK_LED_MODE_FRONT_PANEL_OFF:
10095 	case ELINK_LED_MODE_OFF:
10096 		led_mode_bitmask = 0;
10097 		gpio_pins_bitmask = 0x03;
10098 		break;
10099 	case ELINK_LED_MODE_ON:
10100 		led_mode_bitmask = 0;
10101 		gpio_pins_bitmask = 0x02;
10102 		break;
10103 	case ELINK_LED_MODE_OPER:
10104 		led_mode_bitmask = 0x60;
10105 		gpio_pins_bitmask = 0x11;
10106 		break;
10107 	}
10108 	elink_cl45_read(sc, phy,
10109 			MDIO_PMA_DEVAD,
10110 			MDIO_PMA_REG_8727_PCS_OPT_CTRL,
10111 			&val);
10112 	val &= 0xff8f;
10113 	val |= led_mode_bitmask;
10114 	elink_cl45_write(sc, phy,
10115 			 MDIO_PMA_DEVAD,
10116 			 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
10117 			 val);
10118 	elink_cl45_read(sc, phy,
10119 			MDIO_PMA_DEVAD,
10120 			MDIO_PMA_REG_8727_GPIO_CTRL,
10121 			&val);
10122 	val &= 0xffe0;
10123 	val |= gpio_pins_bitmask;
10124 	elink_cl45_write(sc, phy,
10125 			 MDIO_PMA_DEVAD,
10126 			 MDIO_PMA_REG_8727_GPIO_CTRL,
10127 			 val);
10128 }
10129 static void elink_8727_hw_reset(struct elink_phy *phy,
10130 				struct elink_params *params) {
10131 	uint32_t swap_val, swap_override;
10132 	uint8_t port;
10133 	/* The PHY reset is controlled by GPIO 1. Fake the port number
10134 	 * to cancel the swap done in set_gpio()
10135 	 */
10136 	struct bxe_softc *sc = params->sc;
10137 	swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
10138 	swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
10139 	port = (swap_val && swap_override) ^ 1;
10140 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
10141 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
10142 }
10143 
10144 static void elink_8727_config_speed(struct elink_phy *phy,
10145 				    struct elink_params *params)
10146 {
10147 	struct bxe_softc *sc = params->sc;
10148 	uint16_t tmp1, val;
10149 	/* Set option 1G speed */
10150 	if ((phy->req_line_speed == ELINK_SPEED_1000) ||
10151 	    (phy->media_type == ELINK_ETH_PHY_SFP_1G_FIBER)) {
10152 		ELINK_DEBUG_P0(sc, "Setting 1G force\n");
10153 		elink_cl45_write(sc, phy,
10154 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
10155 		elink_cl45_write(sc, phy,
10156 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
10157 		elink_cl45_read(sc, phy,
10158 				MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
10159 		ELINK_DEBUG_P1(sc, "1.7 = 0x%x\n", tmp1);
10160 		/* Power down the XAUI until link is up in case of dual-media
10161 		 * and 1G
10162 		 */
10163 		if (ELINK_DUAL_MEDIA(params)) {
10164 			elink_cl45_read(sc, phy,
10165 					MDIO_PMA_DEVAD,
10166 					MDIO_PMA_REG_8727_PCS_GP, &val);
10167 			val |= (3<<10);
10168 			elink_cl45_write(sc, phy,
10169 					 MDIO_PMA_DEVAD,
10170 					 MDIO_PMA_REG_8727_PCS_GP, val);
10171 		}
10172 	} else if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10173 		   ((phy->speed_cap_mask &
10174 		     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
10175 		   ((phy->speed_cap_mask &
10176 		      PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
10177 		   PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
10178 
10179 		ELINK_DEBUG_P0(sc, "Setting 1G clause37\n");
10180 		elink_cl45_write(sc, phy,
10181 				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
10182 		elink_cl45_write(sc, phy,
10183 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
10184 	} else {
10185 		/* Since the 8727 has only single reset pin, need to set the 10G
10186 		 * registers although it is default
10187 		 */
10188 		elink_cl45_write(sc, phy,
10189 				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
10190 				 0x0020);
10191 		elink_cl45_write(sc, phy,
10192 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
10193 		elink_cl45_write(sc, phy,
10194 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
10195 		elink_cl45_write(sc, phy,
10196 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
10197 				 0x0008);
10198 	}
10199 }
10200 
10201 static elink_status_t elink_8727_config_init(struct elink_phy *phy,
10202 				  struct elink_params *params,
10203 				  struct elink_vars *vars)
10204 {
10205 	uint32_t tx_en_mode;
10206 	uint16_t tmp1, mod_abs, tmp2;
10207 	struct bxe_softc *sc = params->sc;
10208 	/* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
10209 
10210 	elink_wait_reset_complete(sc, phy, params);
10211 
10212 	ELINK_DEBUG_P0(sc, "Initializing BCM8727\n");
10213 
10214 	elink_8727_specific_func(phy, params, ELINK_PHY_INIT);
10215 	/* Initially configure MOD_ABS to interrupt when module is
10216 	 * presence( bit 8)
10217 	 */
10218 	elink_cl45_read(sc, phy,
10219 			MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
10220 	/* Set EDC off by setting OPTXLOS signal input to low (bit 9).
10221 	 * When the EDC is off it locks onto a reference clock and avoids
10222 	 * becoming 'lost'
10223 	 */
10224 	mod_abs &= ~(1<<8);
10225 	if (!(phy->flags & ELINK_FLAGS_NOC))
10226 		mod_abs &= ~(1<<9);
10227 	elink_cl45_write(sc, phy,
10228 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10229 
10230 	/* Enable/Disable PHY transmitter output */
10231 	elink_set_disable_pmd_transmit(params, phy, 0);
10232 
10233 	elink_8727_power_module(sc, phy, 1);
10234 
10235 	elink_cl45_read(sc, phy,
10236 			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
10237 
10238 	elink_cl45_read(sc, phy,
10239 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
10240 
10241 	elink_8727_config_speed(phy, params);
10242 
10243 
10244 	/* Set TX PreEmphasis if needed */
10245 	if ((params->feature_config_flags &
10246 	     ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
10247 		ELINK_DEBUG_P2(sc, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
10248 			   phy->tx_preemphasis[0],
10249 			   phy->tx_preemphasis[1]);
10250 		elink_cl45_write(sc, phy,
10251 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
10252 				 phy->tx_preemphasis[0]);
10253 
10254 		elink_cl45_write(sc, phy,
10255 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
10256 				 phy->tx_preemphasis[1]);
10257 	}
10258 
10259 	/* If TX Laser is controlled by GPIO_0, do not let PHY go into low
10260 	 * power mode, if TX Laser is disabled
10261 	 */
10262 	tx_en_mode = REG_RD(sc, params->shmem_base +
10263 			    offsetof(struct shmem_region,
10264 				dev_info.port_hw_config[params->port].sfp_ctrl))
10265 			& PORT_HW_CFG_TX_LASER_MASK;
10266 
10267 	if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
10268 
10269 		ELINK_DEBUG_P0(sc, "Enabling TXONOFF_PWRDN_DIS\n");
10270 		elink_cl45_read(sc, phy,
10271 			MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
10272 		tmp2 |= 0x1000;
10273 		tmp2 &= 0xFFEF;
10274 		elink_cl45_write(sc, phy,
10275 			MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
10276 		elink_cl45_read(sc, phy,
10277 				MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
10278 				&tmp2);
10279 		elink_cl45_write(sc, phy,
10280 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
10281 				 (tmp2 & 0x7fff));
10282 	}
10283 
10284 	return ELINK_STATUS_OK;
10285 }
10286 
10287 static void elink_8727_handle_mod_abs(struct elink_phy *phy,
10288 				      struct elink_params *params)
10289 {
10290 	struct bxe_softc *sc = params->sc;
10291 	uint16_t mod_abs, rx_alarm_status;
10292 	uint32_t val = REG_RD(sc, params->shmem_base +
10293 			     offsetof(struct shmem_region, dev_info.
10294 				      port_feature_config[params->port].
10295 				      config));
10296 	elink_cl45_read(sc, phy,
10297 			MDIO_PMA_DEVAD,
10298 			MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
10299 	if (mod_abs & (1<<8)) {
10300 
10301 		/* Module is absent */
10302 		ELINK_DEBUG_P0(sc,
10303 		   "MOD_ABS indication show module is absent\n");
10304 		phy->media_type = ELINK_ETH_PHY_NOT_PRESENT;
10305 		/* 1. Set mod_abs to detect next module
10306 		 *    presence event
10307 		 * 2. Set EDC off by setting OPTXLOS signal input to low
10308 		 *    (bit 9).
10309 		 *    When the EDC is off it locks onto a reference clock and
10310 		 *    avoids becoming 'lost'.
10311 		 */
10312 		mod_abs &= ~(1<<8);
10313 		if (!(phy->flags & ELINK_FLAGS_NOC))
10314 			mod_abs &= ~(1<<9);
10315 		elink_cl45_write(sc, phy,
10316 				 MDIO_PMA_DEVAD,
10317 				 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10318 
10319 		/* Clear RX alarm since it stays up as long as
10320 		 * the mod_abs wasn't changed
10321 		 */
10322 		elink_cl45_read(sc, phy,
10323 				MDIO_PMA_DEVAD,
10324 				MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10325 
10326 	} else {
10327 		/* Module is present */
10328 		ELINK_DEBUG_P0(sc,
10329 		   "MOD_ABS indication show module is present\n");
10330 		/* First disable transmitter, and if the module is ok, the
10331 		 * module_detection will enable it
10332 		 * 1. Set mod_abs to detect next module absent event ( bit 8)
10333 		 * 2. Restore the default polarity of the OPRXLOS signal and
10334 		 * this signal will then correctly indicate the presence or
10335 		 * absence of the Rx signal. (bit 9)
10336 		 */
10337 		mod_abs |= (1<<8);
10338 		if (!(phy->flags & ELINK_FLAGS_NOC))
10339 			mod_abs |= (1<<9);
10340 		elink_cl45_write(sc, phy,
10341 				 MDIO_PMA_DEVAD,
10342 				 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10343 
10344 		/* Clear RX alarm since it stays up as long as the mod_abs
10345 		 * wasn't changed. This is need to be done before calling the
10346 		 * module detection, otherwise it will clear* the link update
10347 		 * alarm
10348 		 */
10349 		elink_cl45_read(sc, phy,
10350 				MDIO_PMA_DEVAD,
10351 				MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10352 
10353 
10354 		if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
10355 		    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
10356 			elink_sfp_set_transmitter(params, phy, 0);
10357 
10358 		if (elink_wait_for_sfp_module_initialized(phy, params) == 0)
10359 			elink_sfp_module_detection(phy, params);
10360 		else
10361 			ELINK_DEBUG_P0(sc, "SFP+ module is not initialized\n");
10362 
10363 		/* Reconfigure link speed based on module type limitations */
10364 		elink_8727_config_speed(phy, params);
10365 	}
10366 
10367 	ELINK_DEBUG_P1(sc, "8727 RX_ALARM_STATUS 0x%x\n",
10368 		   rx_alarm_status);
10369 	/* No need to check link status in case of module plugged in/out */
10370 }
10371 
10372 static uint8_t elink_8727_read_status(struct elink_phy *phy,
10373 				 struct elink_params *params,
10374 				 struct elink_vars *vars)
10375 
10376 {
10377 	struct bxe_softc *sc = params->sc;
10378 	uint8_t link_up = 0;
10379 	uint16_t link_status = 0;
10380 	uint16_t rx_alarm_status, lasi_ctrl, val1;
10381 
10382 	/* If PHY is not initialized, do not check link status */
10383 	elink_cl45_read(sc, phy,
10384 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
10385 			&lasi_ctrl);
10386 	if (!lasi_ctrl)
10387 		return 0;
10388 
10389 	/* Check the LASI on Rx */
10390 	elink_cl45_read(sc, phy,
10391 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT,
10392 			&rx_alarm_status);
10393 	vars->line_speed = 0;
10394 	ELINK_DEBUG_P1(sc, "8727 RX_ALARM_STATUS  0x%x\n", rx_alarm_status);
10395 
10396 	elink_sfp_mask_fault(sc, phy, MDIO_PMA_LASI_TXSTAT,
10397 			     MDIO_PMA_LASI_TXCTRL);
10398 
10399 	elink_cl45_read(sc, phy,
10400 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
10401 
10402 	ELINK_DEBUG_P1(sc, "8727 LASI status 0x%x\n", val1);
10403 
10404 	/* Clear MSG-OUT */
10405 	elink_cl45_read(sc, phy,
10406 			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
10407 
10408 	/* If a module is present and there is need to check
10409 	 * for over current
10410 	 */
10411 	if (!(phy->flags & ELINK_FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
10412 		/* Check over-current using 8727 GPIO0 input*/
10413 		elink_cl45_read(sc, phy,
10414 				MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
10415 				&val1);
10416 
10417 		if ((val1 & (1<<8)) == 0) {
10418 			uint8_t oc_port = params->port;
10419 			if (!CHIP_IS_E1x(sc))
10420 				oc_port = SC_PATH(sc) + (params->port << 1);
10421 			ELINK_DEBUG_P1(sc,
10422 			   "8727 Power fault has been detected on port %d\n",
10423 			   oc_port);
10424 			elink_cb_event_log(sc, ELINK_LOG_ID_OVER_CURRENT, oc_port); //"Error: Power fault on Port %d has "
10425 					  //  "been detected and the power to "
10426 					  //  "that SFP+ module has been removed "
10427 					  //  "to prevent failure of the card. "
10428 					  //  "Please remove the SFP+ module and "
10429 					  //  "restart the system to clear this "
10430 					  //  "error.\n",
10431 			/* Disable all RX_ALARMs except for mod_abs */
10432 			elink_cl45_write(sc, phy,
10433 					 MDIO_PMA_DEVAD,
10434 					 MDIO_PMA_LASI_RXCTRL, (1<<5));
10435 
10436 			elink_cl45_read(sc, phy,
10437 					MDIO_PMA_DEVAD,
10438 					MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
10439 			/* Wait for module_absent_event */
10440 			val1 |= (1<<8);
10441 			elink_cl45_write(sc, phy,
10442 					 MDIO_PMA_DEVAD,
10443 					 MDIO_PMA_REG_PHY_IDENTIFIER, val1);
10444 			/* Clear RX alarm */
10445 			elink_cl45_read(sc, phy,
10446 				MDIO_PMA_DEVAD,
10447 				MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10448 			elink_8727_power_module(params->sc, phy, 0);
10449 			return 0;
10450 		}
10451 	} /* Over current check */
10452 
10453 	/* When module absent bit is set, check module */
10454 	if (rx_alarm_status & (1<<5)) {
10455 		elink_8727_handle_mod_abs(phy, params);
10456 		/* Enable all mod_abs and link detection bits */
10457 		elink_cl45_write(sc, phy,
10458 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
10459 				 ((1<<5) | (1<<2)));
10460 	}
10461 
10462 	if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED)) {
10463 		ELINK_DEBUG_P0(sc, "Enabling 8727 TX laser\n");
10464 		elink_sfp_set_transmitter(params, phy, 1);
10465 	} else {
10466 		ELINK_DEBUG_P0(sc, "Tx is disabled\n");
10467 		return 0;
10468 	}
10469 
10470 	elink_cl45_read(sc, phy,
10471 			MDIO_PMA_DEVAD,
10472 			MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
10473 
10474 	/* Bits 0..2 --> speed detected,
10475 	 * Bits 13..15--> link is down
10476 	 */
10477 	if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
10478 		link_up = 1;
10479 		vars->line_speed = ELINK_SPEED_10000;
10480 		ELINK_DEBUG_P1(sc, "port %x: External link up in 10G\n",
10481 			   params->port);
10482 	} else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
10483 		link_up = 1;
10484 		vars->line_speed = ELINK_SPEED_1000;
10485 		ELINK_DEBUG_P1(sc, "port %x: External link up in 1G\n",
10486 			   params->port);
10487 	} else {
10488 		link_up = 0;
10489 		ELINK_DEBUG_P1(sc, "port %x: External link is down\n",
10490 			   params->port);
10491 	}
10492 
10493 	/* Capture 10G link fault. */
10494 	if (vars->line_speed == ELINK_SPEED_10000) {
10495 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
10496 			    MDIO_PMA_LASI_TXSTAT, &val1);
10497 
10498 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
10499 			    MDIO_PMA_LASI_TXSTAT, &val1);
10500 
10501 		if (val1 & (1<<0)) {
10502 			vars->fault_detected = 1;
10503 		}
10504 	}
10505 
10506 	if (link_up) {
10507 		elink_ext_phy_resolve_fc(phy, params, vars);
10508 		vars->duplex = DUPLEX_FULL;
10509 		ELINK_DEBUG_P1(sc, "duplex = 0x%x\n", vars->duplex);
10510 	}
10511 
10512 	if ((ELINK_DUAL_MEDIA(params)) &&
10513 	    (phy->req_line_speed == ELINK_SPEED_1000)) {
10514 		elink_cl45_read(sc, phy,
10515 				MDIO_PMA_DEVAD,
10516 				MDIO_PMA_REG_8727_PCS_GP, &val1);
10517 		/* In case of dual-media board and 1G, power up the XAUI side,
10518 		 * otherwise power it down. For 10G it is done automatically
10519 		 */
10520 		if (link_up)
10521 			val1 &= ~(3<<10);
10522 		else
10523 			val1 |= (3<<10);
10524 		elink_cl45_write(sc, phy,
10525 				 MDIO_PMA_DEVAD,
10526 				 MDIO_PMA_REG_8727_PCS_GP, val1);
10527 	}
10528 	return link_up;
10529 }
10530 
10531 static void elink_8727_link_reset(struct elink_phy *phy,
10532 				  struct elink_params *params)
10533 {
10534 	struct bxe_softc *sc = params->sc;
10535 
10536 	/* Enable/Disable PHY transmitter output */
10537 	elink_set_disable_pmd_transmit(params, phy, 1);
10538 
10539 	/* Disable Transmitter */
10540 	elink_sfp_set_transmitter(params, phy, 0);
10541 	/* Clear LASI */
10542 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0);
10543 
10544 }
10545 
10546 /******************************************************************/
10547 /*		BCM8481/BCM84823/BCM84833 PHY SECTION	          */
10548 /******************************************************************/
10549 static int elink_is_8483x_8485x(struct elink_phy *phy)
10550 {
10551 	return ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
10552 		(phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) ||
10553 		(phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858));
10554 }
10555 
10556 static void elink_save_848xx_spirom_version(struct elink_phy *phy,
10557 					    struct bxe_softc *sc,
10558 					    uint8_t port)
10559 {
10560 	uint16_t val, fw_ver2, cnt, i;
10561 	static struct elink_reg_set reg_set[] = {
10562 		{MDIO_PMA_DEVAD, 0xA819, 0x0014},
10563 		{MDIO_PMA_DEVAD, 0xA81A, 0xc200},
10564 		{MDIO_PMA_DEVAD, 0xA81B, 0x0000},
10565 		{MDIO_PMA_DEVAD, 0xA81C, 0x0300},
10566 		{MDIO_PMA_DEVAD, 0xA817, 0x0009}
10567 	};
10568 	uint16_t fw_ver1;
10569 
10570 	if (elink_is_8483x_8485x(phy)) {
10571 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1);
10572 		elink_save_spirom_version(sc, port, fw_ver1 & 0xfff,
10573 				phy->ver_addr);
10574 	} else {
10575 		/* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */
10576 		/* (1) set reg 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
10577 		for (i = 0; i < ARRAY_SIZE(reg_set); i++)
10578 			elink_cl45_write(sc, phy, reg_set[i].devad,
10579 					 reg_set[i].reg, reg_set[i].val);
10580 
10581 		for (cnt = 0; cnt < 100; cnt++) {
10582 			elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA818, &val);
10583 			if (val & 1)
10584 				break;
10585 			DELAY(5);
10586 		}
10587 		if (cnt == 100) {
10588 			ELINK_DEBUG_P0(sc, "Unable to read 848xx "
10589 					"phy fw version(1)\n");
10590 			elink_save_spirom_version(sc, port, 0,
10591 						  phy->ver_addr);
10592 			return;
10593 		}
10594 
10595 
10596 		/* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
10597 		elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
10598 		elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
10599 		elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
10600 		for (cnt = 0; cnt < 100; cnt++) {
10601 			elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA818, &val);
10602 			if (val & 1)
10603 				break;
10604 			DELAY(5);
10605 		}
10606 		if (cnt == 100) {
10607 			ELINK_DEBUG_P0(sc, "Unable to read 848xx phy fw "
10608 					"version(2)\n");
10609 			elink_save_spirom_version(sc, port, 0,
10610 						  phy->ver_addr);
10611 			return;
10612 		}
10613 
10614 		/* lower 16 bits of the register SPI_FW_STATUS */
10615 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
10616 		/* upper 16 bits of register SPI_FW_STATUS */
10617 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
10618 
10619 		elink_save_spirom_version(sc, port, (fw_ver2<<16) | fw_ver1,
10620 					  phy->ver_addr);
10621 	}
10622 
10623 }
10624 static void elink_848xx_set_led(struct bxe_softc *sc,
10625 				struct elink_phy *phy)
10626 {
10627 	uint16_t val, offset, i;
10628 	static struct elink_reg_set reg_set[] = {
10629 		{MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, 0x0080},
10630 		{MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED2_MASK, 0x0018},
10631 		{MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_MASK, 0x0006},
10632 		{MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_BLINK, 0x0000},
10633 		{MDIO_PMA_DEVAD, MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH,
10634 			MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ},
10635 		{MDIO_AN_DEVAD, 0xFFFB, 0xFFFD}
10636 	};
10637 	/* PHYC_CTL_LED_CTL */
10638 	elink_cl45_read(sc, phy,
10639 			MDIO_PMA_DEVAD,
10640 			MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
10641 	val &= 0xFE00;
10642 	val |= 0x0092;
10643 
10644 	elink_cl45_write(sc, phy,
10645 			 MDIO_PMA_DEVAD,
10646 			 MDIO_PMA_REG_8481_LINK_SIGNAL, val);
10647 
10648 	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
10649 		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
10650 				 reg_set[i].val);
10651 
10652 	if (elink_is_8483x_8485x(phy))
10653 		offset = MDIO_PMA_REG_84833_CTL_LED_CTL_1;
10654 	else
10655 		offset = MDIO_PMA_REG_84823_CTL_LED_CTL_1;
10656 
10657 	/* stretch_en for LED3*/
10658 	elink_cl45_read_or_write(sc, phy,
10659 				 MDIO_PMA_DEVAD, offset,
10660 				 MDIO_PMA_REG_84823_LED3_STRETCH_EN);
10661 }
10662 
10663 static void elink_848xx_specific_func(struct elink_phy *phy,
10664 				      struct elink_params *params,
10665 				      uint32_t action)
10666 {
10667 	struct bxe_softc *sc = params->sc;
10668 	switch (action) {
10669 	case ELINK_PHY_INIT:
10670 		if (!elink_is_8483x_8485x(phy)) {
10671 			/* Save spirom version */
10672 			elink_save_848xx_spirom_version(phy, sc, params->port);
10673 		}
10674 		/* This phy uses the NIG latch mechanism since link indication
10675 		 * arrives through its LED4 and not via its LASI signal, so we
10676 		 * get steady signal instead of clear on read
10677 		 */
10678 		elink_bits_en(sc, NIG_REG_LATCH_BC_0 + params->port*4,
10679 			      1 << ELINK_NIG_LATCH_BC_ENABLE_MI_INT);
10680 
10681 		elink_848xx_set_led(sc, phy);
10682 		break;
10683 	}
10684 }
10685 
10686 static elink_status_t elink_848xx_cmn_config_init(struct elink_phy *phy,
10687 				       struct elink_params *params,
10688 				       struct elink_vars *vars)
10689 {
10690 	struct bxe_softc *sc = params->sc;
10691 	uint16_t autoneg_val, an_1000_val, an_10_100_val;
10692 
10693 	elink_848xx_specific_func(phy, params, ELINK_PHY_INIT);
10694 	elink_cl45_write(sc, phy,
10695 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
10696 
10697 	/* set 1000 speed advertisement */
10698 	elink_cl45_read(sc, phy,
10699 			MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
10700 			&an_1000_val);
10701 
10702 	elink_ext_phy_set_pause(params, phy, vars);
10703 	elink_cl45_read(sc, phy,
10704 			MDIO_AN_DEVAD,
10705 			MDIO_AN_REG_8481_LEGACY_AN_ADV,
10706 			&an_10_100_val);
10707 	elink_cl45_read(sc, phy,
10708 			MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
10709 			&autoneg_val);
10710 	/* Disable forced speed */
10711 	autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
10712 	an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
10713 
10714 	if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10715 	     (phy->speed_cap_mask &
10716 	     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
10717 	    (phy->req_line_speed == ELINK_SPEED_1000)) {
10718 		an_1000_val |= (1<<8);
10719 		autoneg_val |= (1<<9 | 1<<12);
10720 		if (phy->req_duplex == DUPLEX_FULL)
10721 			an_1000_val |= (1<<9);
10722 		ELINK_DEBUG_P0(sc, "Advertising 1G\n");
10723 	} else
10724 		an_1000_val &= ~((1<<8) | (1<<9));
10725 
10726 	elink_cl45_write(sc, phy,
10727 			 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
10728 			 an_1000_val);
10729 
10730 	/* Set 10/100 speed advertisement */
10731 	if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
10732 		if (phy->speed_cap_mask &
10733 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
10734 			/* Enable autoneg and restart autoneg for legacy speeds
10735 			 */
10736 			autoneg_val |= (1<<9 | 1<<12);
10737 			an_10_100_val |= (1<<8);
10738 			ELINK_DEBUG_P0(sc, "Advertising 100M-FD\n");
10739 		}
10740 
10741 		if (phy->speed_cap_mask &
10742 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
10743 			/* Enable autoneg and restart autoneg for legacy speeds
10744 			 */
10745 			autoneg_val |= (1<<9 | 1<<12);
10746 			an_10_100_val |= (1<<7);
10747 			ELINK_DEBUG_P0(sc, "Advertising 100M-HD\n");
10748 		}
10749 
10750 		if ((phy->speed_cap_mask &
10751 		     PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
10752 		    (phy->supported & ELINK_SUPPORTED_10baseT_Full)) {
10753 			an_10_100_val |= (1<<6);
10754 			autoneg_val |= (1<<9 | 1<<12);
10755 			ELINK_DEBUG_P0(sc, "Advertising 10M-FD\n");
10756 		}
10757 
10758 		if ((phy->speed_cap_mask &
10759 		     PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) &&
10760 		    (phy->supported & ELINK_SUPPORTED_10baseT_Half)) {
10761 			an_10_100_val |= (1<<5);
10762 			autoneg_val |= (1<<9 | 1<<12);
10763 			ELINK_DEBUG_P0(sc, "Advertising 10M-HD\n");
10764 		}
10765 	}
10766 
10767 	/* Only 10/100 are allowed to work in FORCE mode */
10768 	if ((phy->req_line_speed == ELINK_SPEED_100) &&
10769 	    (phy->supported &
10770 	     (ELINK_SUPPORTED_100baseT_Half |
10771 	      ELINK_SUPPORTED_100baseT_Full))) {
10772 		autoneg_val |= (1<<13);
10773 		/* Enabled AUTO-MDIX when autoneg is disabled */
10774 		elink_cl45_write(sc, phy,
10775 				 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
10776 				 (1<<15 | 1<<9 | 7<<0));
10777 		/* The PHY needs this set even for forced link. */
10778 		an_10_100_val |= (1<<8) | (1<<7);
10779 		ELINK_DEBUG_P0(sc, "Setting 100M force\n");
10780 	}
10781 	if ((phy->req_line_speed == ELINK_SPEED_10) &&
10782 	    (phy->supported &
10783 	     (ELINK_SUPPORTED_10baseT_Half |
10784 	      ELINK_SUPPORTED_10baseT_Full))) {
10785 		/* Enabled AUTO-MDIX when autoneg is disabled */
10786 		elink_cl45_write(sc, phy,
10787 				 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
10788 				 (1<<15 | 1<<9 | 7<<0));
10789 		ELINK_DEBUG_P0(sc, "Setting 10M force\n");
10790 	}
10791 
10792 	elink_cl45_write(sc, phy,
10793 			 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
10794 			 an_10_100_val);
10795 
10796 	if (phy->req_duplex == DUPLEX_FULL)
10797 		autoneg_val |= (1<<8);
10798 
10799 	/* Always write this if this is not 84833/4.
10800 	 * For 84833/4, write it only when it's a forced speed.
10801 	 */
10802 	if (!elink_is_8483x_8485x(phy) ||
10803 	    ((autoneg_val & (1<<12)) == 0))
10804 		elink_cl45_write(sc, phy,
10805 			 MDIO_AN_DEVAD,
10806 			 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
10807 
10808 	if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10809 	    (phy->speed_cap_mask &
10810 	     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
10811 		(phy->req_line_speed == ELINK_SPEED_10000)) {
10812 			ELINK_DEBUG_P0(sc, "Advertising 10G\n");
10813 			/* Restart autoneg for 10G*/
10814 
10815 			elink_cl45_read_or_write(
10816 				sc, phy,
10817 				MDIO_AN_DEVAD,
10818 				MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
10819 				0x1000);
10820 			elink_cl45_write(sc, phy,
10821 					 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
10822 					 0x3200);
10823 	} else
10824 		elink_cl45_write(sc, phy,
10825 				 MDIO_AN_DEVAD,
10826 				 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
10827 				 1);
10828 
10829 	return ELINK_STATUS_OK;
10830 }
10831 
10832 static elink_status_t elink_8481_config_init(struct elink_phy *phy,
10833 				  struct elink_params *params,
10834 				  struct elink_vars *vars)
10835 {
10836 	struct bxe_softc *sc = params->sc;
10837 	/* Restore normal power mode*/
10838 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
10839 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
10840 
10841 	/* HW reset */
10842 	elink_ext_phy_hw_reset(sc, params->port);
10843 	elink_wait_reset_complete(sc, phy, params);
10844 
10845 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
10846 	return elink_848xx_cmn_config_init(phy, params, vars);
10847 }
10848 
10849 #define PHY848xx_CMDHDLR_WAIT 300
10850 #define PHY848xx_CMDHDLR_MAX_ARGS 5
10851 
10852 static elink_status_t elink_84858_cmd_hdlr(struct elink_phy *phy,
10853 					   struct elink_params *params,
10854 					   uint16_t fw_cmd,
10855 					   uint16_t cmd_args[], int argc)
10856 {
10857 	int idx;
10858 	uint16_t val;
10859 	struct bxe_softc *sc = params->sc;
10860 
10861 	/* Step 1: Poll the STATUS register to see whether the previous command
10862 	 * is in progress or the system is busy (CMD_IN_PROGRESS or
10863 	 * SYSTEM_BUSY). If previous command is in progress or system is busy,
10864 	 * check again until the previous command finishes execution and the
10865 	 * system is available for taking command
10866 	 */
10867 
10868 	for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
10869 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10870 				MDIO_848xx_CMD_HDLR_STATUS, &val);
10871 		if ((val != PHY84858_STATUS_CMD_IN_PROGRESS) &&
10872 		    (val != PHY84858_STATUS_CMD_SYSTEM_BUSY))
10873 			break;
10874 		DELAY(1000 * 1);
10875 	}
10876 	if (idx >= PHY848xx_CMDHDLR_WAIT) {
10877 		ELINK_DEBUG_P0(sc, "FW cmd: FW not ready.\n");
10878 		return ELINK_STATUS_ERROR;
10879 	}
10880 
10881 	/* Step2: If any parameters are required for the function, write them
10882 	 * to the required DATA registers
10883 	 */
10884 
10885 	for (idx = 0; idx < argc; idx++) {
10886 		elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10887 				 MDIO_848xx_CMD_HDLR_DATA1 + idx,
10888 				 cmd_args[idx]);
10889 	}
10890 
10891 	/* Step3: When the firmware is ready for commands, write the 'Command
10892 	 * code' to the CMD register
10893 	 */
10894 	elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10895 			 MDIO_848xx_CMD_HDLR_COMMAND, fw_cmd);
10896 
10897 	/* Step4: Once the command has been written, poll the STATUS register
10898 	 * to check whether the command has completed (CMD_COMPLETED_PASS/
10899 	 * CMD_FOR_CMDS or CMD_COMPLETED_ERROR).
10900 	 */
10901 
10902 	for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
10903 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10904 				MDIO_848xx_CMD_HDLR_STATUS, &val);
10905 		if ((val == PHY84858_STATUS_CMD_COMPLETE_PASS) ||
10906 		    (val == PHY84858_STATUS_CMD_COMPLETE_ERROR))
10907 			break;
10908 		DELAY(1000 * 1);
10909 	}
10910 	if ((idx >= PHY848xx_CMDHDLR_WAIT) ||
10911 	    (val == PHY84858_STATUS_CMD_COMPLETE_ERROR)) {
10912 		ELINK_DEBUG_P0(sc, "FW cmd failed.\n");
10913 		return ELINK_STATUS_ERROR;
10914 	}
10915 	/* Step5: Once the command has completed, read the specficied DATA
10916 	 * registers for any saved results for the command, if applicable
10917 	 */
10918 
10919 	/* Gather returning data */
10920 	for (idx = 0; idx < argc; idx++) {
10921 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10922 				MDIO_848xx_CMD_HDLR_DATA1 + idx,
10923 				&cmd_args[idx]);
10924 	}
10925 
10926 	return ELINK_STATUS_OK;
10927 }
10928 
10929 static elink_status_t elink_84833_cmd_hdlr(struct elink_phy *phy,
10930 				struct elink_params *params, uint16_t fw_cmd,
10931 				uint16_t cmd_args[], int argc, int process)
10932 {
10933 	int idx;
10934 	uint16_t val;
10935 	struct bxe_softc *sc = params->sc;
10936 	elink_status_t rc = ELINK_STATUS_OK;
10937 
10938 	if (process == PHY84833_MB_PROCESS2) {
10939 	/* Write CMD_OPEN_OVERRIDE to STATUS reg */
10940 	elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10941 				 MDIO_848xx_CMD_HDLR_STATUS,
10942 			PHY84833_STATUS_CMD_OPEN_OVERRIDE);
10943 	}
10944 
10945 	for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
10946 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10947 			       MDIO_848xx_CMD_HDLR_STATUS, &val);
10948 		if (val == PHY84833_STATUS_CMD_OPEN_FOR_CMDS)
10949 			break;
10950 		DELAY(1000 * 1);
10951 	}
10952 	if (idx >= PHY848xx_CMDHDLR_WAIT) {
10953 		ELINK_DEBUG_P0(sc, "FW cmd: FW not ready.\n");
10954 		/* if the status is CMD_COMPLETE_PASS or CMD_COMPLETE_ERROR
10955 		 * clear the status to CMD_CLEAR_COMPLETE
10956 		 */
10957 		if (val == PHY84833_STATUS_CMD_COMPLETE_PASS ||
10958 		    val == PHY84833_STATUS_CMD_COMPLETE_ERROR) {
10959 			elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10960 					 MDIO_848xx_CMD_HDLR_STATUS,
10961 					 PHY84833_STATUS_CMD_CLEAR_COMPLETE);
10962 		}
10963 		return ELINK_STATUS_ERROR;
10964 	}
10965 	if (process == PHY84833_MB_PROCESS1 ||
10966 	    process == PHY84833_MB_PROCESS2) {
10967 		/* Prepare argument(s) */
10968 	for (idx = 0; idx < argc; idx++) {
10969 		elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10970 					 MDIO_848xx_CMD_HDLR_DATA1 + idx,
10971 				cmd_args[idx]);
10972 	}
10973 	}
10974 
10975 	/* Issue command */
10976 	elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10977 			MDIO_848xx_CMD_HDLR_COMMAND, fw_cmd);
10978 	for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
10979 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10980 			       MDIO_848xx_CMD_HDLR_STATUS, &val);
10981 		if ((val == PHY84833_STATUS_CMD_COMPLETE_PASS) ||
10982 			(val == PHY84833_STATUS_CMD_COMPLETE_ERROR))
10983 			break;
10984 		DELAY(1000 * 1);
10985 	}
10986 	if ((idx >= PHY848xx_CMDHDLR_WAIT) ||
10987 		(val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) {
10988 		ELINK_DEBUG_P0(sc, "FW cmd failed.\n");
10989 		rc = ELINK_STATUS_ERROR;
10990 	}
10991 	if (process == PHY84833_MB_PROCESS3 && rc == ELINK_STATUS_OK) {
10992 	/* Gather returning data */
10993 	for (idx = 0; idx < argc; idx++) {
10994 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10995 					MDIO_848xx_CMD_HDLR_DATA1 + idx,
10996 				&cmd_args[idx]);
10997 	}
10998 	}
10999 	if (val == PHY84833_STATUS_CMD_COMPLETE_ERROR ||
11000 	    val == PHY84833_STATUS_CMD_COMPLETE_PASS) {
11001 	elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11002 				 MDIO_848xx_CMD_HDLR_STATUS,
11003 			PHY84833_STATUS_CMD_CLEAR_COMPLETE);
11004 	}
11005 	return rc;
11006 }
11007 
11008 static elink_status_t elink_848xx_cmd_hdlr(struct elink_phy *phy,
11009 					   struct elink_params *params,
11010 					   uint16_t fw_cmd,
11011 					   uint16_t cmd_args[], int argc,
11012 					   int process)
11013 {
11014 	struct bxe_softc *sc = params->sc;
11015 
11016 	if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858) ||
11017 	    (REG_RD(sc, params->shmem2_base +
11018 		    offsetof(struct shmem2_region,
11019 			     link_attr_sync[params->port])) & LINK_ATTR_84858)) {
11020 		return elink_84858_cmd_hdlr(phy, params, fw_cmd, cmd_args,
11021 					    argc);
11022 	} else {
11023 		return elink_84833_cmd_hdlr(phy, params, fw_cmd, cmd_args,
11024 					    argc, process);
11025 	}
11026 }
11027 
11028 static elink_status_t elink_848xx_pair_swap_cfg(struct elink_phy *phy,
11029 				   struct elink_params *params,
11030 				   struct elink_vars *vars)
11031 {
11032 	uint32_t pair_swap;
11033 	uint16_t data[PHY848xx_CMDHDLR_MAX_ARGS];
11034 	elink_status_t status;
11035 	struct bxe_softc *sc = params->sc;
11036 
11037 	/* Check for configuration. */
11038 	pair_swap = REG_RD(sc, params->shmem_base +
11039 			   offsetof(struct shmem_region,
11040 			dev_info.port_hw_config[params->port].xgbt_phy_cfg)) &
11041 		PORT_HW_CFG_RJ45_PAIR_SWAP_MASK;
11042 
11043 	if (pair_swap == 0)
11044 		return ELINK_STATUS_OK;
11045 
11046 	/* Only the second argument is used for this command */
11047 	data[1] = (uint16_t)pair_swap;
11048 
11049 	status = elink_848xx_cmd_hdlr(phy, params,
11050 				      PHY848xx_CMD_SET_PAIR_SWAP, data,
11051 				      2, PHY84833_MB_PROCESS2);
11052 	if (status == ELINK_STATUS_OK)
11053 		ELINK_DEBUG_P1(sc, "Pairswap OK, val=0x%x\n", data[1]);
11054 
11055 	return status;
11056 }
11057 
11058 static uint8_t elink_84833_get_reset_gpios(struct bxe_softc *sc,
11059 				      uint32_t shmem_base_path[],
11060 				      uint32_t chip_id)
11061 {
11062 	uint32_t reset_pin[2];
11063 	uint32_t idx;
11064 	uint8_t reset_gpios;
11065 	if (CHIP_IS_E3(sc)) {
11066 		/* Assume that these will be GPIOs, not EPIOs. */
11067 		for (idx = 0; idx < 2; idx++) {
11068 			/* Map config param to register bit. */
11069 			reset_pin[idx] = REG_RD(sc, shmem_base_path[idx] +
11070 				offsetof(struct shmem_region,
11071 				dev_info.port_hw_config[0].e3_cmn_pin_cfg));
11072 			reset_pin[idx] = (reset_pin[idx] &
11073 				PORT_HW_CFG_E3_PHY_RESET_MASK) >>
11074 				PORT_HW_CFG_E3_PHY_RESET_SHIFT;
11075 			reset_pin[idx] -= PIN_CFG_GPIO0_P0;
11076 			reset_pin[idx] = (1 << reset_pin[idx]);
11077 		}
11078 		reset_gpios = (uint8_t)(reset_pin[0] | reset_pin[1]);
11079 	} else {
11080 		/* E2, look from diff place of shmem. */
11081 		for (idx = 0; idx < 2; idx++) {
11082 			reset_pin[idx] = REG_RD(sc, shmem_base_path[idx] +
11083 				offsetof(struct shmem_region,
11084 				dev_info.port_hw_config[0].default_cfg));
11085 			reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK;
11086 			reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0;
11087 			reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT;
11088 			reset_pin[idx] = (1 << reset_pin[idx]);
11089 		}
11090 		reset_gpios = (uint8_t)(reset_pin[0] | reset_pin[1]);
11091 	}
11092 
11093 	return reset_gpios;
11094 }
11095 
11096 static elink_status_t elink_84833_hw_reset_phy(struct elink_phy *phy,
11097 				struct elink_params *params)
11098 {
11099 	struct bxe_softc *sc = params->sc;
11100 	uint8_t reset_gpios;
11101 	uint32_t other_shmem_base_addr = REG_RD(sc, params->shmem2_base +
11102 				offsetof(struct shmem2_region,
11103 				other_shmem_base_addr));
11104 
11105 	uint32_t shmem_base_path[2];
11106 
11107 	/* Work around for 84833 LED failure inside RESET status */
11108 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
11109 		MDIO_AN_REG_8481_LEGACY_MII_CTRL,
11110 		MDIO_AN_REG_8481_MII_CTRL_FORCE_1G);
11111 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
11112 		MDIO_AN_REG_8481_1G_100T_EXT_CTRL,
11113 		MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF);
11114 
11115 	shmem_base_path[0] = params->shmem_base;
11116 	shmem_base_path[1] = other_shmem_base_addr;
11117 
11118 	reset_gpios = elink_84833_get_reset_gpios(sc, shmem_base_path,
11119 						  params->chip_id);
11120 
11121 	elink_cb_gpio_mult_write(sc, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
11122 	DELAY(10);
11123 	ELINK_DEBUG_P1(sc, "84833 hw reset on pin values 0x%x\n",
11124 		reset_gpios);
11125 
11126 	return ELINK_STATUS_OK;
11127 }
11128 
11129 static elink_status_t elink_8483x_disable_eee(struct elink_phy *phy,
11130 				   struct elink_params *params,
11131 				   struct elink_vars *vars)
11132 {
11133 	elink_status_t rc;
11134 	struct bxe_softc *sc = params->sc;
11135 	uint16_t cmd_args = 0;
11136 
11137 	ELINK_DEBUG_P0(sc, "Don't Advertise 10GBase-T EEE\n");
11138 
11139 	/* Prevent Phy from working in EEE and advertising it */
11140 	rc = elink_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE,
11141 				  &cmd_args, 1, PHY84833_MB_PROCESS1);
11142 	if (rc != ELINK_STATUS_OK) {
11143 		ELINK_DEBUG_P0(sc, "EEE disable failed.\n");
11144 		return rc;
11145 	}
11146 
11147 	return elink_eee_disable(phy, params, vars);
11148 }
11149 
11150 static elink_status_t elink_8483x_enable_eee(struct elink_phy *phy,
11151 				   struct elink_params *params,
11152 				   struct elink_vars *vars)
11153 {
11154 	elink_status_t rc;
11155 	struct bxe_softc *sc = params->sc;
11156 	uint16_t cmd_args = 1;
11157 
11158 	rc = elink_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE,
11159 				  &cmd_args, 1, PHY84833_MB_PROCESS1);
11160 	if (rc != ELINK_STATUS_OK) {
11161 		ELINK_DEBUG_P0(sc, "EEE enable failed.\n");
11162 		return rc;
11163 	}
11164 
11165 	return elink_eee_advertise(phy, params, vars, SHMEM_EEE_10G_ADV);
11166 }
11167 
11168 #define PHY84833_CONSTANT_LATENCY 1193
11169 static elink_status_t elink_848x3_config_init(struct elink_phy *phy,
11170 				   struct elink_params *params,
11171 				   struct elink_vars *vars)
11172 {
11173 	struct bxe_softc *sc = params->sc;
11174 	uint8_t port, initialize = 1;
11175 	uint16_t val;
11176 	uint32_t actual_phy_selection;
11177 	uint16_t cmd_args[PHY848xx_CMDHDLR_MAX_ARGS];
11178 	elink_status_t rc = ELINK_STATUS_OK;
11179 
11180 	DELAY(1000 * 1);
11181 
11182 	if (!(CHIP_IS_E1x(sc)))
11183 		port = SC_PATH(sc);
11184 	else
11185 		port = params->port;
11186 
11187 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
11188 		elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_3,
11189 			       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
11190 			       port);
11191 	} else {
11192 		/* MDIO reset */
11193 		elink_cl45_write(sc, phy,
11194 				MDIO_PMA_DEVAD,
11195 				MDIO_PMA_REG_CTRL, 0x8000);
11196 	}
11197 
11198 	elink_wait_reset_complete(sc, phy, params);
11199 
11200 	/* Wait for GPHY to come out of reset */
11201 	DELAY(1000 * 50);
11202 	if (!elink_is_8483x_8485x(phy)) {
11203 		/* BCM84823 requires that XGXS links up first @ 10G for normal
11204 		 * behavior.
11205 		 */
11206 		uint16_t temp;
11207 		temp = vars->line_speed;
11208 		vars->line_speed = ELINK_SPEED_10000;
11209 		elink_set_autoneg(&params->phy[ELINK_INT_PHY], params, vars, 0);
11210 		elink_program_serdes(&params->phy[ELINK_INT_PHY], params, vars);
11211 		vars->line_speed = temp;
11212 	}
11213 	/* Check if this is actually BCM84858 */
11214 	if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858) {
11215 		uint16_t hw_rev;
11216 
11217 		elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11218 				MDIO_AN_REG_848xx_ID_MSB, &hw_rev);
11219 		if (hw_rev == BCM84858_PHY_ID) {
11220 			params->link_attr_sync |= LINK_ATTR_84858;
11221 			elink_update_link_attr(params, params->link_attr_sync);
11222 		}
11223 	}
11224 
11225 	/* Set dual-media configuration according to configuration */
11226 	elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11227 			MDIO_CTL_REG_84823_MEDIA, &val);
11228 	val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
11229 		 MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
11230 		 MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
11231 		 MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
11232 		 MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
11233 
11234 	if (CHIP_IS_E3(sc)) {
11235 		val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
11236 			 MDIO_CTL_REG_84823_MEDIA_LINE_MASK);
11237 	} else {
11238 		val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI |
11239 			MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L);
11240 	}
11241 
11242 	actual_phy_selection = elink_phy_selection(params);
11243 
11244 	switch (actual_phy_selection) {
11245 	case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
11246 		/* Do nothing. Essentially this is like the priority copper */
11247 		break;
11248 	case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
11249 		val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
11250 		break;
11251 	case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
11252 		val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
11253 		break;
11254 	case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
11255 		/* Do nothing here. The first PHY won't be initialized at all */
11256 		break;
11257 	case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
11258 		val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
11259 		initialize = 0;
11260 		break;
11261 	}
11262 	if (params->phy[ELINK_EXT_PHY2].req_line_speed == ELINK_SPEED_1000)
11263 		val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
11264 
11265 	elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11266 			 MDIO_CTL_REG_84823_MEDIA, val);
11267 	ELINK_DEBUG_P2(sc, "Multi_phy config = 0x%x, Media control = 0x%x\n",
11268 		   params->multi_phy_config, val);
11269 
11270 	if (elink_is_8483x_8485x(phy)) {
11271 		elink_848xx_pair_swap_cfg(phy, params, vars);
11272 
11273 		/* Keep AutogrEEEn disabled. */
11274 		cmd_args[0] = 0x0;
11275 		cmd_args[1] = 0x0;
11276 		cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1;
11277 		cmd_args[3] = PHY84833_CONSTANT_LATENCY;
11278 		rc = elink_848xx_cmd_hdlr(phy, params,
11279 					  PHY848xx_CMD_SET_EEE_MODE, cmd_args,
11280 					  4, PHY84833_MB_PROCESS1);
11281 		if (rc != ELINK_STATUS_OK)
11282 			ELINK_DEBUG_P0(sc, "Cfg AutogrEEEn failed.\n");
11283 	}
11284 	if (initialize)
11285 		rc = elink_848xx_cmn_config_init(phy, params, vars);
11286 	else
11287 		elink_save_848xx_spirom_version(phy, sc, params->port);
11288 	/* 84833 PHY has a better feature and doesn't need to support this. */
11289 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
11290 		uint32_t cms_enable = REG_RD(sc, params->shmem_base +
11291 			offsetof(struct shmem_region,
11292 			dev_info.port_hw_config[params->port].default_cfg)) &
11293 			PORT_HW_CFG_ENABLE_CMS_MASK;
11294 
11295 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11296 				MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
11297 		if (cms_enable)
11298 			val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
11299 		else
11300 			val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
11301 		elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11302 				 MDIO_CTL_REG_84823_USER_CTRL_REG, val);
11303 	}
11304 
11305 	elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11306 			MDIO_84833_TOP_CFG_FW_REV, &val);
11307 
11308 	/* Configure EEE support */
11309 	if ((val >= MDIO_84833_TOP_CFG_FW_EEE) &&
11310 	    (val != MDIO_84833_TOP_CFG_FW_NO_EEE) &&
11311 	    elink_eee_has_cap(params)) {
11312 		rc = elink_eee_initial_config(params, vars, SHMEM_EEE_10G_ADV);
11313 		if (rc != ELINK_STATUS_OK) {
11314 			ELINK_DEBUG_P0(sc, "Failed to configure EEE timers\n");
11315 			elink_8483x_disable_eee(phy, params, vars);
11316 			return rc;
11317 		}
11318 
11319 		if ((phy->req_duplex == DUPLEX_FULL) &&
11320 		    (params->eee_mode & ELINK_EEE_MODE_ADV_LPI) &&
11321 		    (elink_eee_calc_timer(params) ||
11322 		     !(params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)))
11323 			rc = elink_8483x_enable_eee(phy, params, vars);
11324 		else
11325 			rc = elink_8483x_disable_eee(phy, params, vars);
11326 		if (rc != ELINK_STATUS_OK) {
11327 			ELINK_DEBUG_P0(sc, "Failed to set EEE advertisement\n");
11328 			return rc;
11329 		}
11330 	} else {
11331 		vars->eee_status &= ~SHMEM_EEE_SUPPORTED_MASK;
11332 	}
11333 
11334 	if (elink_is_8483x_8485x(phy)) {
11335 		/* Bring PHY out of super isolate mode as the final step. */
11336 		elink_cl45_read_and_write(sc, phy,
11337 					  MDIO_CTL_DEVAD,
11338 					  MDIO_84833_TOP_CFG_XGPHY_STRAP1,
11339 					  (uint16_t)~MDIO_84833_SUPER_ISOLATE);
11340 	}
11341 	return rc;
11342 }
11343 
11344 static uint8_t elink_848xx_read_status(struct elink_phy *phy,
11345 				  struct elink_params *params,
11346 				  struct elink_vars *vars)
11347 {
11348 	struct bxe_softc *sc = params->sc;
11349 	uint16_t val, val1, val2;
11350 	uint8_t link_up = 0;
11351 
11352 
11353 	/* Check 10G-BaseT link status */
11354 	/* Check PMD signal ok */
11355 	elink_cl45_read(sc, phy,
11356 			MDIO_AN_DEVAD, 0xFFFA, &val1);
11357 	elink_cl45_read(sc, phy,
11358 			MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
11359 			&val2);
11360 	ELINK_DEBUG_P1(sc, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
11361 
11362 	/* Check link 10G */
11363 	if (val2 & (1<<11)) {
11364 		vars->line_speed = ELINK_SPEED_10000;
11365 		vars->duplex = DUPLEX_FULL;
11366 		link_up = 1;
11367 		elink_ext_phy_10G_an_resolve(sc, phy, vars);
11368 	} else { /* Check Legacy speed link */
11369 		uint16_t legacy_status, legacy_speed;
11370 
11371 		/* Enable expansion register 0x42 (Operation mode status) */
11372 		elink_cl45_write(sc, phy,
11373 				 MDIO_AN_DEVAD,
11374 				 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
11375 
11376 		/* Get legacy speed operation status */
11377 		elink_cl45_read(sc, phy,
11378 				MDIO_AN_DEVAD,
11379 				MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
11380 				&legacy_status);
11381 
11382 		ELINK_DEBUG_P1(sc, "Legacy speed status = 0x%x\n",
11383 		   legacy_status);
11384 		link_up = ((legacy_status & (1<<11)) == (1<<11));
11385 		legacy_speed = (legacy_status & (3<<9));
11386 		if (legacy_speed == (0<<9))
11387 			vars->line_speed = ELINK_SPEED_10;
11388 		else if (legacy_speed == (1<<9))
11389 			vars->line_speed = ELINK_SPEED_100;
11390 		else if (legacy_speed == (2<<9))
11391 			vars->line_speed = ELINK_SPEED_1000;
11392 		else { /* Should not happen: Treat as link down */
11393 			vars->line_speed = 0;
11394 			link_up = 0;
11395 		}
11396 
11397 		if (params->feature_config_flags &
11398 			ELINK_FEATURE_CONFIG_IEEE_PHY_TEST) {
11399 			uint16_t mii_ctrl;
11400 
11401 			elink_cl45_read(sc, phy,
11402 					MDIO_AN_DEVAD,
11403 					MDIO_AN_REG_8481_LEGACY_MII_CTRL,
11404 					&mii_ctrl);
11405 			/* For IEEE testing, check for a fake link. */
11406 			link_up |= ((mii_ctrl & 0x3040) == 0x40);
11407 		}
11408 
11409 		if (link_up) {
11410 			if (legacy_status & (1<<8))
11411 				vars->duplex = DUPLEX_FULL;
11412 			else
11413 				vars->duplex = DUPLEX_HALF;
11414 
11415 			ELINK_DEBUG_P2(sc,
11416 			   "Link is up in %dMbps, is_duplex_full= %d\n",
11417 			   vars->line_speed,
11418 			   (vars->duplex == DUPLEX_FULL));
11419 			/* Check legacy speed AN resolution */
11420 			elink_cl45_read(sc, phy,
11421 					MDIO_AN_DEVAD,
11422 					MDIO_AN_REG_8481_LEGACY_MII_STATUS,
11423 					&val);
11424 			if (val & (1<<5))
11425 				vars->link_status |=
11426 					LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
11427 			elink_cl45_read(sc, phy,
11428 					MDIO_AN_DEVAD,
11429 					MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
11430 					&val);
11431 			if ((val & (1<<0)) == 0)
11432 				vars->link_status |=
11433 					LINK_STATUS_PARALLEL_DETECTION_USED;
11434 		}
11435 	}
11436 	if (link_up) {
11437 		ELINK_DEBUG_P1(sc, "BCM848x3: link speed is %d\n",
11438 			   vars->line_speed);
11439 		elink_ext_phy_resolve_fc(phy, params, vars);
11440 
11441 		/* Read LP advertised speeds */
11442 		elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11443 				MDIO_AN_REG_CL37_FC_LP, &val);
11444 		if (val & (1<<5))
11445 			vars->link_status |=
11446 				LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
11447 		if (val & (1<<6))
11448 			vars->link_status |=
11449 				LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
11450 		if (val & (1<<7))
11451 			vars->link_status |=
11452 				LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
11453 		if (val & (1<<8))
11454 			vars->link_status |=
11455 				LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
11456 		if (val & (1<<9))
11457 			vars->link_status |=
11458 				LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
11459 
11460 		elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11461 				MDIO_AN_REG_1000T_STATUS, &val);
11462 
11463 		if (val & (1<<10))
11464 			vars->link_status |=
11465 				LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
11466 		if (val & (1<<11))
11467 			vars->link_status |=
11468 				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
11469 
11470 		elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11471 				MDIO_AN_REG_MASTER_STATUS, &val);
11472 
11473 		if (val & (1<<11))
11474 			vars->link_status |=
11475 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
11476 
11477 		/* Determine if EEE was negotiated */
11478 		if (elink_is_8483x_8485x(phy))
11479 			elink_eee_an_resolve(phy, params, vars);
11480 	}
11481 
11482 	return link_up;
11483 }
11484 
11485 static elink_status_t elink_848xx_format_ver(uint32_t raw_ver, uint8_t *str, uint16_t *len)
11486 {
11487 	elink_status_t status = ELINK_STATUS_OK;
11488 	uint32_t spirom_ver;
11489 	spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
11490 	status = elink_format_ver(spirom_ver, str, len);
11491 	return status;
11492 }
11493 
11494 static void elink_8481_hw_reset(struct elink_phy *phy,
11495 				struct elink_params *params)
11496 {
11497 	elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
11498 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
11499 	elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
11500 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
11501 }
11502 
11503 static void elink_8481_link_reset(struct elink_phy *phy,
11504 					struct elink_params *params)
11505 {
11506 	elink_cl45_write(params->sc, phy,
11507 			 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
11508 	elink_cl45_write(params->sc, phy,
11509 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
11510 }
11511 
11512 static void elink_848x3_link_reset(struct elink_phy *phy,
11513 				   struct elink_params *params)
11514 {
11515 	struct bxe_softc *sc = params->sc;
11516 	uint8_t port;
11517 	uint16_t val16;
11518 
11519 	if (!(CHIP_IS_E1x(sc)))
11520 		port = SC_PATH(sc);
11521 	else
11522 		port = params->port;
11523 
11524 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
11525 		elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_3,
11526 			       MISC_REGISTERS_GPIO_OUTPUT_LOW,
11527 			       port);
11528 	} else {
11529 		elink_cl45_read(sc, phy,
11530 				MDIO_CTL_DEVAD,
11531 				MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val16);
11532 		val16 |= MDIO_84833_SUPER_ISOLATE;
11533 		elink_cl45_write(sc, phy,
11534 				 MDIO_CTL_DEVAD,
11535 				 MDIO_84833_TOP_CFG_XGPHY_STRAP1, val16);
11536 	}
11537 }
11538 
11539 static void elink_848xx_set_link_led(struct elink_phy *phy,
11540 				     struct elink_params *params, uint8_t mode)
11541 {
11542 	struct bxe_softc *sc = params->sc;
11543 	uint16_t val;
11544 	uint8_t port;
11545 
11546 	if (!(CHIP_IS_E1x(sc)))
11547 		port = SC_PATH(sc);
11548 	else
11549 		port = params->port;
11550 	switch (mode) {
11551 	case ELINK_LED_MODE_OFF:
11552 
11553 		ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE OFF\n", port);
11554 
11555 		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11556 		    SHARED_HW_CFG_LED_EXTPHY1) {
11557 
11558 			/* Set LED masks */
11559 			elink_cl45_write(sc, phy,
11560 					MDIO_PMA_DEVAD,
11561 					MDIO_PMA_REG_8481_LED1_MASK,
11562 					0x0);
11563 
11564 			elink_cl45_write(sc, phy,
11565 					MDIO_PMA_DEVAD,
11566 					MDIO_PMA_REG_8481_LED2_MASK,
11567 					0x0);
11568 
11569 			elink_cl45_write(sc, phy,
11570 					MDIO_PMA_DEVAD,
11571 					MDIO_PMA_REG_8481_LED3_MASK,
11572 					0x0);
11573 
11574 			elink_cl45_write(sc, phy,
11575 					MDIO_PMA_DEVAD,
11576 					MDIO_PMA_REG_8481_LED5_MASK,
11577 					0x0);
11578 
11579 		} else {
11580 			elink_cl45_write(sc, phy,
11581 					 MDIO_PMA_DEVAD,
11582 					 MDIO_PMA_REG_8481_LED1_MASK,
11583 					 0x0);
11584 		}
11585 		break;
11586 	case ELINK_LED_MODE_FRONT_PANEL_OFF:
11587 
11588 		ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
11589 		   port);
11590 
11591 		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11592 		    SHARED_HW_CFG_LED_EXTPHY1) {
11593 
11594 			/* Set LED masks */
11595 			elink_cl45_write(sc, phy,
11596 					 MDIO_PMA_DEVAD,
11597 					 MDIO_PMA_REG_8481_LED1_MASK,
11598 					 0x0);
11599 
11600 			elink_cl45_write(sc, phy,
11601 					 MDIO_PMA_DEVAD,
11602 					 MDIO_PMA_REG_8481_LED2_MASK,
11603 					 0x0);
11604 
11605 			elink_cl45_write(sc, phy,
11606 					 MDIO_PMA_DEVAD,
11607 					 MDIO_PMA_REG_8481_LED3_MASK,
11608 					 0x0);
11609 
11610 			elink_cl45_write(sc, phy,
11611 					 MDIO_PMA_DEVAD,
11612 					 MDIO_PMA_REG_8481_LED5_MASK,
11613 					 0x20);
11614 
11615 		} else {
11616 			elink_cl45_write(sc, phy,
11617 					 MDIO_PMA_DEVAD,
11618 					 MDIO_PMA_REG_8481_LED1_MASK,
11619 					 0x0);
11620 			if (phy->type ==
11621 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) {
11622 				/* Disable MI_INT interrupt before setting LED4
11623 				 * source to constant off.
11624 				 */
11625 				if (REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
11626 					   params->port*4) &
11627 				    ELINK_NIG_MASK_MI_INT) {
11628 					params->link_flags |=
11629 					ELINK_LINK_FLAGS_INT_DISABLED;
11630 
11631 					elink_bits_dis(
11632 						sc,
11633 						NIG_REG_MASK_INTERRUPT_PORT0 +
11634 						params->port*4,
11635 						ELINK_NIG_MASK_MI_INT);
11636 				}
11637 				elink_cl45_write(sc, phy,
11638 						 MDIO_PMA_DEVAD,
11639 						 MDIO_PMA_REG_8481_SIGNAL_MASK,
11640 						 0x0);
11641 			}
11642 		}
11643 		break;
11644 	case ELINK_LED_MODE_ON:
11645 
11646 		ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE ON\n", port);
11647 
11648 		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11649 		    SHARED_HW_CFG_LED_EXTPHY1) {
11650 			/* Set control reg */
11651 			elink_cl45_read(sc, phy,
11652 					MDIO_PMA_DEVAD,
11653 					MDIO_PMA_REG_8481_LINK_SIGNAL,
11654 					&val);
11655 			val &= 0x8000;
11656 			val |= 0x2492;
11657 
11658 			elink_cl45_write(sc, phy,
11659 					 MDIO_PMA_DEVAD,
11660 					 MDIO_PMA_REG_8481_LINK_SIGNAL,
11661 					 val);
11662 
11663 			/* Set LED masks */
11664 			elink_cl45_write(sc, phy,
11665 					 MDIO_PMA_DEVAD,
11666 					 MDIO_PMA_REG_8481_LED1_MASK,
11667 					 0x0);
11668 
11669 			elink_cl45_write(sc, phy,
11670 					 MDIO_PMA_DEVAD,
11671 					 MDIO_PMA_REG_8481_LED2_MASK,
11672 					 0x20);
11673 
11674 			elink_cl45_write(sc, phy,
11675 					 MDIO_PMA_DEVAD,
11676 					 MDIO_PMA_REG_8481_LED3_MASK,
11677 					 0x20);
11678 
11679 			elink_cl45_write(sc, phy,
11680 					 MDIO_PMA_DEVAD,
11681 					 MDIO_PMA_REG_8481_LED5_MASK,
11682 					 0x0);
11683 		} else {
11684 			elink_cl45_write(sc, phy,
11685 					 MDIO_PMA_DEVAD,
11686 					 MDIO_PMA_REG_8481_LED1_MASK,
11687 					 0x20);
11688 			if (phy->type ==
11689 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) {
11690 				/* Disable MI_INT interrupt before setting LED4
11691 				 * source to constant on.
11692 				 */
11693 				if (REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
11694 					   params->port*4) &
11695 				    ELINK_NIG_MASK_MI_INT) {
11696 					params->link_flags |=
11697 					ELINK_LINK_FLAGS_INT_DISABLED;
11698 
11699 					elink_bits_dis(
11700 						sc,
11701 						NIG_REG_MASK_INTERRUPT_PORT0 +
11702 						params->port*4,
11703 						ELINK_NIG_MASK_MI_INT);
11704 				}
11705 				elink_cl45_write(sc, phy,
11706 						 MDIO_PMA_DEVAD,
11707 						 MDIO_PMA_REG_8481_SIGNAL_MASK,
11708 						 0x20);
11709 			}
11710 		}
11711 		break;
11712 
11713 	case ELINK_LED_MODE_OPER:
11714 
11715 		ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE OPER\n", port);
11716 
11717 		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11718 		    SHARED_HW_CFG_LED_EXTPHY1) {
11719 
11720 			/* Set control reg */
11721 			elink_cl45_read(sc, phy,
11722 					MDIO_PMA_DEVAD,
11723 					MDIO_PMA_REG_8481_LINK_SIGNAL,
11724 					&val);
11725 
11726 			if (!((val &
11727 			       MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
11728 			  >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
11729 				ELINK_DEBUG_P0(sc, "Setting LINK_SIGNAL\n");
11730 				elink_cl45_write(sc, phy,
11731 						 MDIO_PMA_DEVAD,
11732 						 MDIO_PMA_REG_8481_LINK_SIGNAL,
11733 						 0xa492);
11734 			}
11735 
11736 			/* Set LED masks */
11737 			elink_cl45_write(sc, phy,
11738 					 MDIO_PMA_DEVAD,
11739 					 MDIO_PMA_REG_8481_LED1_MASK,
11740 					 0x10);
11741 
11742 			elink_cl45_write(sc, phy,
11743 					 MDIO_PMA_DEVAD,
11744 					 MDIO_PMA_REG_8481_LED2_MASK,
11745 					 0x80);
11746 
11747 			elink_cl45_write(sc, phy,
11748 					 MDIO_PMA_DEVAD,
11749 					 MDIO_PMA_REG_8481_LED3_MASK,
11750 					 0x98);
11751 
11752 			elink_cl45_write(sc, phy,
11753 					 MDIO_PMA_DEVAD,
11754 					 MDIO_PMA_REG_8481_LED5_MASK,
11755 					 0x40);
11756 
11757 		} else {
11758 			/* EXTPHY2 LED mode indicate that the 100M/1G/10G LED
11759 			 * sources are all wired through LED1, rather than only
11760 			 * 10G in other modes.
11761 			 */
11762 			val = ((params->hw_led_mode <<
11763 				SHARED_HW_CFG_LED_MODE_SHIFT) ==
11764 			       SHARED_HW_CFG_LED_EXTPHY2) ? 0x98 : 0x80;
11765 
11766 			elink_cl45_write(sc, phy,
11767 					 MDIO_PMA_DEVAD,
11768 					 MDIO_PMA_REG_8481_LED1_MASK,
11769 					 val);
11770 
11771 			/* Tell LED3 to blink on source */
11772 			elink_cl45_read(sc, phy,
11773 					MDIO_PMA_DEVAD,
11774 					MDIO_PMA_REG_8481_LINK_SIGNAL,
11775 					&val);
11776 			val &= ~(7<<6);
11777 			val |= (1<<6); /* A83B[8:6]= 1 */
11778 			elink_cl45_write(sc, phy,
11779 					 MDIO_PMA_DEVAD,
11780 					 MDIO_PMA_REG_8481_LINK_SIGNAL,
11781 					 val);
11782 			if (phy->type ==
11783 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) {
11784 				/* Restore LED4 source to external link,
11785 				 * and re-enable interrupts.
11786 				 */
11787 				elink_cl45_write(sc, phy,
11788 						 MDIO_PMA_DEVAD,
11789 						 MDIO_PMA_REG_8481_SIGNAL_MASK,
11790 						 0x40);
11791 				if (params->link_flags &
11792 				    ELINK_LINK_FLAGS_INT_DISABLED) {
11793 					elink_link_int_enable(params);
11794 					params->link_flags &=
11795 						~ELINK_LINK_FLAGS_INT_DISABLED;
11796 				}
11797 			}
11798 		}
11799 		break;
11800 	}
11801 
11802 	/* This is a workaround for E3+84833 until autoneg
11803 	 * restart is fixed in f/w
11804 	 */
11805 	if (CHIP_IS_E3(sc)) {
11806 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
11807 				MDIO_WC_REG_GP2_STATUS_GP_2_1, &val);
11808 	}
11809 }
11810 
11811 /******************************************************************/
11812 /*			54618SE PHY SECTION			  */
11813 /******************************************************************/
11814 static void elink_54618se_specific_func(struct elink_phy *phy,
11815 					struct elink_params *params,
11816 					uint32_t action)
11817 {
11818 	struct bxe_softc *sc = params->sc;
11819 	uint16_t temp;
11820 	switch (action) {
11821 	case ELINK_PHY_INIT:
11822 		/* Configure LED4: set to INTR (0x6). */
11823 		/* Accessing shadow register 0xe. */
11824 		elink_cl22_write(sc, phy,
11825 				 MDIO_REG_GPHY_SHADOW,
11826 				 MDIO_REG_GPHY_SHADOW_LED_SEL2);
11827 		elink_cl22_read(sc, phy,
11828 				MDIO_REG_GPHY_SHADOW,
11829 				&temp);
11830 		temp &= ~(0xf << 4);
11831 		temp |= (0x6 << 4);
11832 		elink_cl22_write(sc, phy,
11833 				 MDIO_REG_GPHY_SHADOW,
11834 				 MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
11835 		/* Configure INTR based on link status change. */
11836 		elink_cl22_write(sc, phy,
11837 				 MDIO_REG_INTR_MASK,
11838 				 ~MDIO_REG_INTR_MASK_LINK_STATUS);
11839 		break;
11840 	}
11841 }
11842 
11843 static elink_status_t elink_54618se_config_init(struct elink_phy *phy,
11844 					       struct elink_params *params,
11845 					       struct elink_vars *vars)
11846 {
11847 	struct bxe_softc *sc = params->sc;
11848 	uint8_t port;
11849 	uint16_t autoneg_val, an_1000_val, an_10_100_val, fc_val, temp;
11850 	uint32_t cfg_pin;
11851 
11852 	ELINK_DEBUG_P0(sc, "54618SE cfg init\n");
11853 	DELAY(1000 * 1);
11854 
11855 	/* This works with E3 only, no need to check the chip
11856 	 * before determining the port.
11857 	 */
11858 	port = params->port;
11859 
11860 	cfg_pin = (REG_RD(sc, params->shmem_base +
11861 			offsetof(struct shmem_region,
11862 			dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
11863 			PORT_HW_CFG_E3_PHY_RESET_MASK) >>
11864 			PORT_HW_CFG_E3_PHY_RESET_SHIFT;
11865 
11866 	/* Drive pin high to bring the GPHY out of reset. */
11867 	elink_set_cfg_pin(sc, cfg_pin, 1);
11868 
11869 	/* wait for GPHY to reset */
11870 	DELAY(1000 * 50);
11871 
11872 	/* reset phy */
11873 	elink_cl22_write(sc, phy,
11874 			 MDIO_PMA_REG_CTRL, 0x8000);
11875 	elink_wait_reset_complete(sc, phy, params);
11876 
11877 	/* Wait for GPHY to reset */
11878 	DELAY(1000 * 50);
11879 
11880 
11881 	elink_54618se_specific_func(phy, params, ELINK_PHY_INIT);
11882 	/* Flip the signal detect polarity (set 0x1c.0x1e[8]). */
11883 	elink_cl22_write(sc, phy,
11884 			MDIO_REG_GPHY_SHADOW,
11885 			MDIO_REG_GPHY_SHADOW_AUTO_DET_MED);
11886 	elink_cl22_read(sc, phy,
11887 			MDIO_REG_GPHY_SHADOW,
11888 			&temp);
11889 	temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD;
11890 	elink_cl22_write(sc, phy,
11891 			MDIO_REG_GPHY_SHADOW,
11892 			MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
11893 
11894 	/* Set up fc */
11895 	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
11896 	elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
11897 	fc_val = 0;
11898 	if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
11899 			MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC)
11900 		fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
11901 
11902 	if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
11903 			MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
11904 		fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
11905 
11906 	/* Read all advertisement */
11907 	elink_cl22_read(sc, phy,
11908 			0x09,
11909 			&an_1000_val);
11910 
11911 	elink_cl22_read(sc, phy,
11912 			0x04,
11913 			&an_10_100_val);
11914 
11915 	elink_cl22_read(sc, phy,
11916 			MDIO_PMA_REG_CTRL,
11917 			&autoneg_val);
11918 
11919 	/* Disable forced speed */
11920 	autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
11921 	an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) |
11922 			   (1<<11));
11923 
11924 	if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
11925 			(phy->speed_cap_mask &
11926 			PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
11927 			(phy->req_line_speed == ELINK_SPEED_1000)) {
11928 		an_1000_val |= (1<<8);
11929 		autoneg_val |= (1<<9 | 1<<12);
11930 		if (phy->req_duplex == DUPLEX_FULL)
11931 			an_1000_val |= (1<<9);
11932 		ELINK_DEBUG_P0(sc, "Advertising 1G\n");
11933 	} else
11934 		an_1000_val &= ~((1<<8) | (1<<9));
11935 
11936 	elink_cl22_write(sc, phy,
11937 			0x09,
11938 			an_1000_val);
11939 	elink_cl22_read(sc, phy,
11940 			0x09,
11941 			&an_1000_val);
11942 
11943 	/* Advertise 10/100 link speed */
11944 	if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
11945 		if (phy->speed_cap_mask &
11946 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) {
11947 			an_10_100_val |= (1<<5);
11948 			autoneg_val |= (1<<9 | 1<<12);
11949 			ELINK_DEBUG_P0(sc, "Advertising 10M-HD\n");
11950 		}
11951 		if (phy->speed_cap_mask &
11952 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) {
11953 			an_10_100_val |= (1<<6);
11954 			autoneg_val |= (1<<9 | 1<<12);
11955 			ELINK_DEBUG_P0(sc, "Advertising 10M-FD\n");
11956 		}
11957 		if (phy->speed_cap_mask &
11958 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
11959 			an_10_100_val |= (1<<7);
11960 			autoneg_val |= (1<<9 | 1<<12);
11961 			ELINK_DEBUG_P0(sc, "Advertising 100M-HD\n");
11962 		}
11963 		if (phy->speed_cap_mask &
11964 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
11965 			an_10_100_val |= (1<<8);
11966 			autoneg_val |= (1<<9 | 1<<12);
11967 			ELINK_DEBUG_P0(sc, "Advertising 100M-FD\n");
11968 		}
11969 	}
11970 
11971 	/* Only 10/100 are allowed to work in FORCE mode */
11972 	if (phy->req_line_speed == ELINK_SPEED_100) {
11973 		autoneg_val |= (1<<13);
11974 		/* Enabled AUTO-MDIX when autoneg is disabled */
11975 		elink_cl22_write(sc, phy,
11976 				0x18,
11977 				(1<<15 | 1<<9 | 7<<0));
11978 		ELINK_DEBUG_P0(sc, "Setting 100M force\n");
11979 	}
11980 	if (phy->req_line_speed == ELINK_SPEED_10) {
11981 		/* Enabled AUTO-MDIX when autoneg is disabled */
11982 		elink_cl22_write(sc, phy,
11983 				0x18,
11984 				(1<<15 | 1<<9 | 7<<0));
11985 		ELINK_DEBUG_P0(sc, "Setting 10M force\n");
11986 	}
11987 
11988 	if ((phy->flags & ELINK_FLAGS_EEE) && elink_eee_has_cap(params)) {
11989 		elink_status_t rc;
11990 
11991 		elink_cl22_write(sc, phy, MDIO_REG_GPHY_EXP_ACCESS,
11992 				 MDIO_REG_GPHY_EXP_ACCESS_TOP |
11993 				 MDIO_REG_GPHY_EXP_TOP_2K_BUF);
11994 		elink_cl22_read(sc, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, &temp);
11995 		temp &= 0xfffe;
11996 		elink_cl22_write(sc, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, temp);
11997 
11998 		rc = elink_eee_initial_config(params, vars, SHMEM_EEE_1G_ADV);
11999 		if (rc != ELINK_STATUS_OK) {
12000 			ELINK_DEBUG_P0(sc, "Failed to configure EEE timers\n");
12001 			elink_eee_disable(phy, params, vars);
12002 		} else if ((params->eee_mode & ELINK_EEE_MODE_ADV_LPI) &&
12003 			   (phy->req_duplex == DUPLEX_FULL) &&
12004 			   (elink_eee_calc_timer(params) ||
12005 			    !(params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI))) {
12006 			/* Need to advertise EEE only when requested,
12007 			 * and either no LPI assertion was requested,
12008 			 * or it was requested and a valid timer was set.
12009 			 * Also notice full duplex is required for EEE.
12010 			 */
12011 			elink_eee_advertise(phy, params, vars,
12012 					    SHMEM_EEE_1G_ADV);
12013 		} else {
12014 			ELINK_DEBUG_P0(sc, "Don't Advertise 1GBase-T EEE\n");
12015 			elink_eee_disable(phy, params, vars);
12016 		}
12017 	} else {
12018 		vars->eee_status &= ((uint32_t)(~SHMEM_EEE_1G_ADV) <<
12019 				    SHMEM_EEE_SUPPORTED_SHIFT);
12020 
12021 		if (phy->flags & ELINK_FLAGS_EEE) {
12022 			/* Handle legacy auto-grEEEn */
12023 			if (params->feature_config_flags &
12024 			    ELINK_FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
12025 				temp = 6;
12026 				ELINK_DEBUG_P0(sc, "Enabling Auto-GrEEEn\n");
12027 			} else {
12028 				temp = 0;
12029 				ELINK_DEBUG_P0(sc, "Don't Adv. EEE\n");
12030 			}
12031 			elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
12032 					 MDIO_AN_REG_EEE_ADV, temp);
12033 		}
12034 	}
12035 
12036 	elink_cl22_write(sc, phy,
12037 			0x04,
12038 			an_10_100_val | fc_val);
12039 
12040 	if (phy->req_duplex == DUPLEX_FULL)
12041 		autoneg_val |= (1<<8);
12042 
12043 	elink_cl22_write(sc, phy,
12044 			MDIO_PMA_REG_CTRL, autoneg_val);
12045 
12046 	return ELINK_STATUS_OK;
12047 }
12048 
12049 
12050 static void elink_5461x_set_link_led(struct elink_phy *phy,
12051 				       struct elink_params *params, uint8_t mode)
12052 {
12053 	struct bxe_softc *sc = params->sc;
12054 	uint16_t temp;
12055 
12056 	elink_cl22_write(sc, phy,
12057 		MDIO_REG_GPHY_SHADOW,
12058 		MDIO_REG_GPHY_SHADOW_LED_SEL1);
12059 	elink_cl22_read(sc, phy,
12060 		MDIO_REG_GPHY_SHADOW,
12061 		&temp);
12062 	temp &= 0xff00;
12063 
12064 	ELINK_DEBUG_P1(sc, "54618x set link led (mode=%x)\n", mode);
12065 	switch (mode) {
12066 	case ELINK_LED_MODE_FRONT_PANEL_OFF:
12067 	case ELINK_LED_MODE_OFF:
12068 		temp |= 0x00ee;
12069 		break;
12070 	case ELINK_LED_MODE_OPER:
12071 		temp |= 0x0001;
12072 		break;
12073 	case ELINK_LED_MODE_ON:
12074 		temp |= 0x00ff;
12075 		break;
12076 	default:
12077 		break;
12078 	}
12079 	elink_cl22_write(sc, phy,
12080 		MDIO_REG_GPHY_SHADOW,
12081 		MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
12082 	return;
12083 }
12084 
12085 
12086 static void elink_54618se_link_reset(struct elink_phy *phy,
12087 				     struct elink_params *params)
12088 {
12089 	struct bxe_softc *sc = params->sc;
12090 	uint32_t cfg_pin;
12091 	uint8_t port;
12092 
12093 	/* In case of no EPIO routed to reset the GPHY, put it
12094 	 * in low power mode.
12095 	 */
12096 	elink_cl22_write(sc, phy, MDIO_PMA_REG_CTRL, 0x800);
12097 	/* This works with E3 only, no need to check the chip
12098 	 * before determining the port.
12099 	 */
12100 	port = params->port;
12101 	cfg_pin = (REG_RD(sc, params->shmem_base +
12102 			offsetof(struct shmem_region,
12103 			dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
12104 			PORT_HW_CFG_E3_PHY_RESET_MASK) >>
12105 			PORT_HW_CFG_E3_PHY_RESET_SHIFT;
12106 
12107 	/* Drive pin low to put GPHY in reset. */
12108 	elink_set_cfg_pin(sc, cfg_pin, 0);
12109 }
12110 
12111 static uint8_t elink_54618se_read_status(struct elink_phy *phy,
12112 				    struct elink_params *params,
12113 				    struct elink_vars *vars)
12114 {
12115 	struct bxe_softc *sc = params->sc;
12116 	uint16_t val;
12117 	uint8_t link_up = 0;
12118 	uint16_t legacy_status, legacy_speed;
12119 
12120 	/* Get speed operation status */
12121 	elink_cl22_read(sc, phy,
12122 			MDIO_REG_GPHY_AUX_STATUS,
12123 			&legacy_status);
12124 	ELINK_DEBUG_P1(sc, "54618SE read_status: 0x%x\n", legacy_status);
12125 
12126 	/* Read status to clear the PHY interrupt. */
12127 	elink_cl22_read(sc, phy,
12128 			MDIO_REG_INTR_STATUS,
12129 			&val);
12130 
12131 	link_up = ((legacy_status & (1<<2)) == (1<<2));
12132 
12133 	if (link_up) {
12134 		legacy_speed = (legacy_status & (7<<8));
12135 		if (legacy_speed == (7<<8)) {
12136 			vars->line_speed = ELINK_SPEED_1000;
12137 			vars->duplex = DUPLEX_FULL;
12138 		} else if (legacy_speed == (6<<8)) {
12139 			vars->line_speed = ELINK_SPEED_1000;
12140 			vars->duplex = DUPLEX_HALF;
12141 		} else if (legacy_speed == (5<<8)) {
12142 			vars->line_speed = ELINK_SPEED_100;
12143 			vars->duplex = DUPLEX_FULL;
12144 		}
12145 		/* Omitting 100Base-T4 for now */
12146 		else if (legacy_speed == (3<<8)) {
12147 			vars->line_speed = ELINK_SPEED_100;
12148 			vars->duplex = DUPLEX_HALF;
12149 		} else if (legacy_speed == (2<<8)) {
12150 			vars->line_speed = ELINK_SPEED_10;
12151 			vars->duplex = DUPLEX_FULL;
12152 		} else if (legacy_speed == (1<<8)) {
12153 			vars->line_speed = ELINK_SPEED_10;
12154 			vars->duplex = DUPLEX_HALF;
12155 		} else /* Should not happen */
12156 			vars->line_speed = 0;
12157 
12158 		ELINK_DEBUG_P2(sc,
12159 		   "Link is up in %dMbps, is_duplex_full= %d\n",
12160 		   vars->line_speed,
12161 		   (vars->duplex == DUPLEX_FULL));
12162 
12163 		/* Check legacy speed AN resolution */
12164 		elink_cl22_read(sc, phy,
12165 				0x01,
12166 				&val);
12167 		if (val & (1<<5))
12168 			vars->link_status |=
12169 				LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
12170 		elink_cl22_read(sc, phy,
12171 				0x06,
12172 				&val);
12173 		if ((val & (1<<0)) == 0)
12174 			vars->link_status |=
12175 				LINK_STATUS_PARALLEL_DETECTION_USED;
12176 
12177 		ELINK_DEBUG_P1(sc, "BCM54618SE: link speed is %d\n",
12178 			   vars->line_speed);
12179 
12180 		elink_ext_phy_resolve_fc(phy, params, vars);
12181 
12182 		if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
12183 			/* Report LP advertised speeds */
12184 			elink_cl22_read(sc, phy, 0x5, &val);
12185 
12186 			if (val & (1<<5))
12187 				vars->link_status |=
12188 				  LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
12189 			if (val & (1<<6))
12190 				vars->link_status |=
12191 				  LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
12192 			if (val & (1<<7))
12193 				vars->link_status |=
12194 				  LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
12195 			if (val & (1<<8))
12196 				vars->link_status |=
12197 				  LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
12198 			if (val & (1<<9))
12199 				vars->link_status |=
12200 				  LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
12201 
12202 			elink_cl22_read(sc, phy, 0xa, &val);
12203 			if (val & (1<<10))
12204 				vars->link_status |=
12205 				  LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
12206 			if (val & (1<<11))
12207 				vars->link_status |=
12208 				  LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
12209 
12210 			if ((phy->flags & ELINK_FLAGS_EEE) &&
12211 			    elink_eee_has_cap(params))
12212 				elink_eee_an_resolve(phy, params, vars);
12213 		}
12214 	}
12215 	return link_up;
12216 }
12217 
12218 static void elink_54618se_config_loopback(struct elink_phy *phy,
12219 					  struct elink_params *params)
12220 {
12221 	struct bxe_softc *sc = params->sc;
12222 	uint16_t val;
12223 	uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
12224 
12225 	ELINK_DEBUG_P0(sc, "2PMA/PMD ext_phy_loopback: 54618se\n");
12226 
12227 	/* Enable master/slave manual mmode and set to master */
12228 	/* mii write 9 [bits set 11 12] */
12229 	elink_cl22_write(sc, phy, 0x09, 3<<11);
12230 
12231 	/* forced 1G and disable autoneg */
12232 	/* set val [mii read 0] */
12233 	/* set val [expr $val & [bits clear 6 12 13]] */
12234 	/* set val [expr $val | [bits set 6 8]] */
12235 	/* mii write 0 $val */
12236 	elink_cl22_read(sc, phy, 0x00, &val);
12237 	val &= ~((1<<6) | (1<<12) | (1<<13));
12238 	val |= (1<<6) | (1<<8);
12239 	elink_cl22_write(sc, phy, 0x00, val);
12240 
12241 	/* Set external loopback and Tx using 6dB coding */
12242 	/* mii write 0x18 7 */
12243 	/* set val [mii read 0x18] */
12244 	/* mii write 0x18 [expr $val | [bits set 10 15]] */
12245 	elink_cl22_write(sc, phy, 0x18, 7);
12246 	elink_cl22_read(sc, phy, 0x18, &val);
12247 	elink_cl22_write(sc, phy, 0x18, val | (1<<10) | (1<<15));
12248 
12249 	/* This register opens the gate for the UMAC despite its name */
12250 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
12251 
12252 	/* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
12253 	 * length used by the MAC receive logic to check frames.
12254 	 */
12255 	REG_WR(sc, umac_base + UMAC_REG_MAXFR, 0x2710);
12256 }
12257 
12258 /******************************************************************/
12259 /*			SFX7101 PHY SECTION			  */
12260 /******************************************************************/
12261 static void elink_7101_config_loopback(struct elink_phy *phy,
12262 				       struct elink_params *params)
12263 {
12264 	struct bxe_softc *sc = params->sc;
12265 	/* SFX7101_XGXS_TEST1 */
12266 	elink_cl45_write(sc, phy,
12267 			 MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
12268 }
12269 
12270 static elink_status_t elink_7101_config_init(struct elink_phy *phy,
12271 				  struct elink_params *params,
12272 				  struct elink_vars *vars)
12273 {
12274 	uint16_t fw_ver1, fw_ver2, val;
12275 	struct bxe_softc *sc = params->sc;
12276 	ELINK_DEBUG_P0(sc, "Setting the SFX7101 LASI indication\n");
12277 
12278 	/* Restore normal power mode*/
12279 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
12280 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
12281 	/* HW reset */
12282 	elink_ext_phy_hw_reset(sc, params->port);
12283 	elink_wait_reset_complete(sc, phy, params);
12284 
12285 	elink_cl45_write(sc, phy,
12286 			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x1);
12287 	ELINK_DEBUG_P0(sc, "Setting the SFX7101 LED to blink on traffic\n");
12288 	elink_cl45_write(sc, phy,
12289 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
12290 
12291 	elink_ext_phy_set_pause(params, phy, vars);
12292 	/* Restart autoneg */
12293 	elink_cl45_read(sc, phy,
12294 			MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
12295 	val |= 0x200;
12296 	elink_cl45_write(sc, phy,
12297 			 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
12298 
12299 	/* Save spirom version */
12300 	elink_cl45_read(sc, phy,
12301 			MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
12302 
12303 	elink_cl45_read(sc, phy,
12304 			MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
12305 	elink_save_spirom_version(sc, params->port,
12306 				  (uint32_t)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
12307 	return ELINK_STATUS_OK;
12308 }
12309 
12310 static uint8_t elink_7101_read_status(struct elink_phy *phy,
12311 				 struct elink_params *params,
12312 				 struct elink_vars *vars)
12313 {
12314 	struct bxe_softc *sc = params->sc;
12315 	uint8_t link_up;
12316 	uint16_t val1, val2;
12317 	elink_cl45_read(sc, phy,
12318 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
12319 	elink_cl45_read(sc, phy,
12320 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
12321 	ELINK_DEBUG_P2(sc, "10G-base-T LASI status 0x%x->0x%x\n",
12322 		   val2, val1);
12323 	elink_cl45_read(sc, phy,
12324 			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
12325 	elink_cl45_read(sc, phy,
12326 			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
12327 	ELINK_DEBUG_P2(sc, "10G-base-T PMA status 0x%x->0x%x\n",
12328 		   val2, val1);
12329 	link_up = ((val1 & 4) == 4);
12330 	/* If link is up print the AN outcome of the SFX7101 PHY */
12331 	if (link_up) {
12332 		elink_cl45_read(sc, phy,
12333 				MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
12334 				&val2);
12335 		vars->line_speed = ELINK_SPEED_10000;
12336 		vars->duplex = DUPLEX_FULL;
12337 		ELINK_DEBUG_P2(sc, "SFX7101 AN status 0x%x->Master=%x\n",
12338 			   val2, (val2 & (1<<14)));
12339 		elink_ext_phy_10G_an_resolve(sc, phy, vars);
12340 		elink_ext_phy_resolve_fc(phy, params, vars);
12341 
12342 		/* Read LP advertised speeds */
12343 		if (val2 & (1<<11))
12344 			vars->link_status |=
12345 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
12346 	}
12347 	return link_up;
12348 }
12349 
12350 static elink_status_t elink_7101_format_ver(uint32_t spirom_ver, uint8_t *str, uint16_t *len)
12351 {
12352 	if (*len < 5)
12353 		return ELINK_STATUS_ERROR;
12354 	str[0] = (spirom_ver & 0xFF);
12355 	str[1] = (spirom_ver & 0xFF00) >> 8;
12356 	str[2] = (spirom_ver & 0xFF0000) >> 16;
12357 	str[3] = (spirom_ver & 0xFF000000) >> 24;
12358 	str[4] = '\0';
12359 	*len -= 5;
12360 	return ELINK_STATUS_OK;
12361 }
12362 
12363 void elink_sfx7101_sp_sw_reset(struct bxe_softc *sc, struct elink_phy *phy)
12364 {
12365 	uint16_t val, cnt;
12366 
12367 	elink_cl45_read(sc, phy,
12368 			MDIO_PMA_DEVAD,
12369 			MDIO_PMA_REG_7101_RESET, &val);
12370 
12371 	for (cnt = 0; cnt < 10; cnt++) {
12372 		DELAY(1000 * 50);
12373 		/* Writes a self-clearing reset */
12374 		elink_cl45_write(sc, phy,
12375 				 MDIO_PMA_DEVAD,
12376 				 MDIO_PMA_REG_7101_RESET,
12377 				 (val | (1<<15)));
12378 		/* Wait for clear */
12379 		elink_cl45_read(sc, phy,
12380 				MDIO_PMA_DEVAD,
12381 				MDIO_PMA_REG_7101_RESET, &val);
12382 
12383 		if ((val & (1<<15)) == 0)
12384 			break;
12385 	}
12386 }
12387 
12388 static void elink_7101_hw_reset(struct elink_phy *phy,
12389 				struct elink_params *params) {
12390 	/* Low power mode is controlled by GPIO 2 */
12391 	elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_2,
12392 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
12393 	/* The PHY reset is controlled by GPIO 1 */
12394 	elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
12395 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
12396 }
12397 
12398 static void elink_7101_set_link_led(struct elink_phy *phy,
12399 				    struct elink_params *params, uint8_t mode)
12400 {
12401 	uint16_t val = 0;
12402 	struct bxe_softc *sc = params->sc;
12403 	switch (mode) {
12404 	case ELINK_LED_MODE_FRONT_PANEL_OFF:
12405 	case ELINK_LED_MODE_OFF:
12406 		val = 2;
12407 		break;
12408 	case ELINK_LED_MODE_ON:
12409 		val = 1;
12410 		break;
12411 	case ELINK_LED_MODE_OPER:
12412 		val = 0;
12413 		break;
12414 	}
12415 	elink_cl45_write(sc, phy,
12416 			 MDIO_PMA_DEVAD,
12417 			 MDIO_PMA_REG_7107_LINK_LED_CNTL,
12418 			 val);
12419 }
12420 
12421 /******************************************************************/
12422 /*			STATIC PHY DECLARATION			  */
12423 /******************************************************************/
12424 
12425 static const struct elink_phy phy_null = {
12426 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
12427 	.addr		= 0,
12428 	.def_md_devad	= 0,
12429 	.flags		= ELINK_FLAGS_INIT_XGXS_FIRST,
12430 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12431 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12432 	.mdio_ctrl	= 0,
12433 	.supported	= 0,
12434 	.media_type	= ELINK_ETH_PHY_NOT_PRESENT,
12435 	.ver_addr	= 0,
12436 	.req_flow_ctrl	= 0,
12437 	.req_line_speed	= 0,
12438 	.speed_cap_mask	= 0,
12439 	.req_duplex	= 0,
12440 	.rsrv		= 0,
12441 	.config_init	= (config_init_t)NULL,
12442 	.read_status	= (read_status_t)NULL,
12443 	.link_reset	= (link_reset_t)NULL,
12444 	.config_loopback = (config_loopback_t)NULL,
12445 	.format_fw_ver	= (format_fw_ver_t)NULL,
12446 	.hw_reset	= (hw_reset_t)NULL,
12447 	.set_link_led	= (set_link_led_t)NULL,
12448 	.phy_specific_func = (phy_specific_func_t)NULL
12449 };
12450 
12451 static const struct elink_phy phy_serdes = {
12452 	.type		= PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
12453 	.addr		= 0xff,
12454 	.def_md_devad	= 0,
12455 	.flags		= 0,
12456 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12457 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12458 	.mdio_ctrl	= 0,
12459 	.supported	= (ELINK_SUPPORTED_10baseT_Half |
12460 			   ELINK_SUPPORTED_10baseT_Full |
12461 			   ELINK_SUPPORTED_100baseT_Half |
12462 			   ELINK_SUPPORTED_100baseT_Full |
12463 			   ELINK_SUPPORTED_1000baseT_Full |
12464 			   ELINK_SUPPORTED_2500baseX_Full |
12465 			   ELINK_SUPPORTED_TP |
12466 			   ELINK_SUPPORTED_Autoneg |
12467 			   ELINK_SUPPORTED_Pause |
12468 			   ELINK_SUPPORTED_Asym_Pause),
12469 	.media_type	= ELINK_ETH_PHY_BASE_T,
12470 	.ver_addr	= 0,
12471 	.req_flow_ctrl	= 0,
12472 	.req_line_speed	= 0,
12473 	.speed_cap_mask	= 0,
12474 	.req_duplex	= 0,
12475 	.rsrv		= 0,
12476 	.config_init	= (config_init_t)elink_xgxs_config_init,
12477 	.read_status	= (read_status_t)elink_link_settings_status,
12478 	.link_reset	= (link_reset_t)elink_int_link_reset,
12479 	.config_loopback = (config_loopback_t)NULL,
12480 	.format_fw_ver	= (format_fw_ver_t)NULL,
12481 	.hw_reset	= (hw_reset_t)NULL,
12482 	.set_link_led	= (set_link_led_t)NULL,
12483 	.phy_specific_func = (phy_specific_func_t)NULL
12484 };
12485 
12486 static const struct elink_phy phy_xgxs = {
12487 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
12488 	.addr		= 0xff,
12489 	.def_md_devad	= 0,
12490 	.flags		= 0,
12491 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12492 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12493 	.mdio_ctrl	= 0,
12494 	.supported	= (ELINK_SUPPORTED_10baseT_Half |
12495 			   ELINK_SUPPORTED_10baseT_Full |
12496 			   ELINK_SUPPORTED_100baseT_Half |
12497 			   ELINK_SUPPORTED_100baseT_Full |
12498 			   ELINK_SUPPORTED_1000baseT_Full |
12499 			   ELINK_SUPPORTED_2500baseX_Full |
12500 			   ELINK_SUPPORTED_10000baseT_Full |
12501 			   ELINK_SUPPORTED_FIBRE |
12502 			   ELINK_SUPPORTED_Autoneg |
12503 			   ELINK_SUPPORTED_Pause |
12504 			   ELINK_SUPPORTED_Asym_Pause),
12505 	.media_type	= ELINK_ETH_PHY_CX4,
12506 	.ver_addr	= 0,
12507 	.req_flow_ctrl	= 0,
12508 	.req_line_speed	= 0,
12509 	.speed_cap_mask	= 0,
12510 	.req_duplex	= 0,
12511 	.rsrv		= 0,
12512 	.config_init	= (config_init_t)elink_xgxs_config_init,
12513 	.read_status	= (read_status_t)elink_link_settings_status,
12514 	.link_reset	= (link_reset_t)elink_int_link_reset,
12515 	.config_loopback = (config_loopback_t)elink_set_xgxs_loopback,
12516 	.format_fw_ver	= (format_fw_ver_t)NULL,
12517 	.hw_reset	= (hw_reset_t)NULL,
12518 	.set_link_led	= (set_link_led_t)NULL,
12519 	.phy_specific_func = (phy_specific_func_t)elink_xgxs_specific_func
12520 };
12521 static const struct elink_phy phy_warpcore = {
12522 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
12523 	.addr		= 0xff,
12524 	.def_md_devad	= 0,
12525 	.flags		= ELINK_FLAGS_TX_ERROR_CHECK,
12526 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12527 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12528 	.mdio_ctrl	= 0,
12529 	.supported	= (ELINK_SUPPORTED_10baseT_Half |
12530 			   ELINK_SUPPORTED_10baseT_Full |
12531 			   ELINK_SUPPORTED_100baseT_Half |
12532 			   ELINK_SUPPORTED_100baseT_Full |
12533 			   ELINK_SUPPORTED_1000baseT_Full |
12534 			   ELINK_SUPPORTED_1000baseKX_Full |
12535 			   ELINK_SUPPORTED_10000baseT_Full |
12536 			   ELINK_SUPPORTED_10000baseKR_Full |
12537 			   ELINK_SUPPORTED_20000baseKR2_Full |
12538 			   ELINK_SUPPORTED_20000baseMLD2_Full |
12539 			   ELINK_SUPPORTED_FIBRE |
12540 			   ELINK_SUPPORTED_Autoneg |
12541 			   ELINK_SUPPORTED_Pause |
12542 			   ELINK_SUPPORTED_Asym_Pause),
12543 	.media_type	= ELINK_ETH_PHY_UNSPECIFIED,
12544 	.ver_addr	= 0,
12545 	.req_flow_ctrl	= 0,
12546 	.req_line_speed	= 0,
12547 	.speed_cap_mask	= 0,
12548 	/* req_duplex = */0,
12549 	/* rsrv = */0,
12550 	.config_init	= (config_init_t)elink_warpcore_config_init,
12551 	.read_status	= (read_status_t)elink_warpcore_read_status,
12552 	.link_reset	= (link_reset_t)elink_warpcore_link_reset,
12553 	.config_loopback = (config_loopback_t)elink_set_warpcore_loopback,
12554 	.format_fw_ver	= (format_fw_ver_t)NULL,
12555 	.hw_reset	= (hw_reset_t)elink_warpcore_hw_reset,
12556 	.set_link_led	= (set_link_led_t)NULL,
12557 	.phy_specific_func = (phy_specific_func_t)NULL
12558 };
12559 
12560 
12561 static const struct elink_phy phy_7101 = {
12562 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
12563 	.addr		= 0xff,
12564 	.def_md_devad	= 0,
12565 	.flags		= ELINK_FLAGS_FAN_FAILURE_DET_REQ,
12566 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12567 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12568 	.mdio_ctrl	= 0,
12569 	.supported	= (ELINK_SUPPORTED_10000baseT_Full |
12570 			   ELINK_SUPPORTED_TP |
12571 			   ELINK_SUPPORTED_Autoneg |
12572 			   ELINK_SUPPORTED_Pause |
12573 			   ELINK_SUPPORTED_Asym_Pause),
12574 	.media_type	= ELINK_ETH_PHY_BASE_T,
12575 	.ver_addr	= 0,
12576 	.req_flow_ctrl	= 0,
12577 	.req_line_speed	= 0,
12578 	.speed_cap_mask	= 0,
12579 	.req_duplex	= 0,
12580 	.rsrv		= 0,
12581 	.config_init	= (config_init_t)elink_7101_config_init,
12582 	.read_status	= (read_status_t)elink_7101_read_status,
12583 	.link_reset	= (link_reset_t)elink_common_ext_link_reset,
12584 	.config_loopback = (config_loopback_t)elink_7101_config_loopback,
12585 	.format_fw_ver	= (format_fw_ver_t)elink_7101_format_ver,
12586 	.hw_reset	= (hw_reset_t)elink_7101_hw_reset,
12587 	.set_link_led	= (set_link_led_t)elink_7101_set_link_led,
12588 	.phy_specific_func = (phy_specific_func_t)NULL
12589 };
12590 static const struct elink_phy phy_8073 = {
12591 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
12592 	.addr		= 0xff,
12593 	.def_md_devad	= 0,
12594 	.flags		= 0,
12595 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12596 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12597 	.mdio_ctrl	= 0,
12598 	.supported	= (ELINK_SUPPORTED_10000baseT_Full |
12599 			   ELINK_SUPPORTED_2500baseX_Full |
12600 			   ELINK_SUPPORTED_1000baseT_Full |
12601 			   ELINK_SUPPORTED_FIBRE |
12602 			   ELINK_SUPPORTED_Autoneg |
12603 			   ELINK_SUPPORTED_Pause |
12604 			   ELINK_SUPPORTED_Asym_Pause),
12605 	.media_type	= ELINK_ETH_PHY_KR,
12606 	.ver_addr	= 0,
12607 	.req_flow_ctrl	= 0,
12608 	.req_line_speed	= 0,
12609 	.speed_cap_mask	= 0,
12610 	.req_duplex	= 0,
12611 	.rsrv		= 0,
12612 	.config_init	= (config_init_t)elink_8073_config_init,
12613 	.read_status	= (read_status_t)elink_8073_read_status,
12614 	.link_reset	= (link_reset_t)elink_8073_link_reset,
12615 	.config_loopback = (config_loopback_t)NULL,
12616 	.format_fw_ver	= (format_fw_ver_t)elink_format_ver,
12617 	.hw_reset	= (hw_reset_t)NULL,
12618 	.set_link_led	= (set_link_led_t)NULL,
12619 	.phy_specific_func = (phy_specific_func_t)elink_8073_specific_func
12620 };
12621 static const struct elink_phy phy_8705 = {
12622 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
12623 	.addr		= 0xff,
12624 	.def_md_devad	= 0,
12625 	.flags		= ELINK_FLAGS_INIT_XGXS_FIRST,
12626 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12627 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12628 	.mdio_ctrl	= 0,
12629 	.supported	= (ELINK_SUPPORTED_10000baseT_Full |
12630 			   ELINK_SUPPORTED_FIBRE |
12631 			   ELINK_SUPPORTED_Pause |
12632 			   ELINK_SUPPORTED_Asym_Pause),
12633 	.media_type	= ELINK_ETH_PHY_XFP_FIBER,
12634 	.ver_addr	= 0,
12635 	.req_flow_ctrl	= 0,
12636 	.req_line_speed	= 0,
12637 	.speed_cap_mask	= 0,
12638 	.req_duplex	= 0,
12639 	.rsrv		= 0,
12640 	.config_init	= (config_init_t)elink_8705_config_init,
12641 	.read_status	= (read_status_t)elink_8705_read_status,
12642 	.link_reset	= (link_reset_t)elink_common_ext_link_reset,
12643 	.config_loopback = (config_loopback_t)NULL,
12644 	.format_fw_ver	= (format_fw_ver_t)elink_null_format_ver,
12645 	.hw_reset	= (hw_reset_t)NULL,
12646 	.set_link_led	= (set_link_led_t)NULL,
12647 	.phy_specific_func = (phy_specific_func_t)NULL
12648 };
12649 static const struct elink_phy phy_8706 = {
12650 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
12651 	.addr		= 0xff,
12652 	.def_md_devad	= 0,
12653 	.flags		= ELINK_FLAGS_INIT_XGXS_FIRST,
12654 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12655 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12656 	.mdio_ctrl	= 0,
12657 	.supported	= (ELINK_SUPPORTED_10000baseT_Full |
12658 			   ELINK_SUPPORTED_1000baseT_Full |
12659 			   ELINK_SUPPORTED_FIBRE |
12660 			   ELINK_SUPPORTED_Pause |
12661 			   ELINK_SUPPORTED_Asym_Pause),
12662 	.media_type	= ELINK_ETH_PHY_SFPP_10G_FIBER,
12663 	.ver_addr	= 0,
12664 	.req_flow_ctrl	= 0,
12665 	.req_line_speed	= 0,
12666 	.speed_cap_mask	= 0,
12667 	.req_duplex	= 0,
12668 	.rsrv		= 0,
12669 	.config_init	= (config_init_t)elink_8706_config_init,
12670 	.read_status	= (read_status_t)elink_8706_read_status,
12671 	.link_reset	= (link_reset_t)elink_common_ext_link_reset,
12672 	.config_loopback = (config_loopback_t)NULL,
12673 	.format_fw_ver	= (format_fw_ver_t)elink_format_ver,
12674 	.hw_reset	= (hw_reset_t)NULL,
12675 	.set_link_led	= (set_link_led_t)NULL,
12676 	.phy_specific_func = (phy_specific_func_t)NULL
12677 };
12678 
12679 static const struct elink_phy phy_8726 = {
12680 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
12681 	.addr		= 0xff,
12682 	.def_md_devad	= 0,
12683 	.flags		= (ELINK_FLAGS_INIT_XGXS_FIRST |
12684 			   ELINK_FLAGS_TX_ERROR_CHECK),
12685 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12686 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12687 	.mdio_ctrl	= 0,
12688 	.supported	= (ELINK_SUPPORTED_10000baseT_Full |
12689 			   ELINK_SUPPORTED_1000baseT_Full |
12690 			   ELINK_SUPPORTED_Autoneg |
12691 			   ELINK_SUPPORTED_FIBRE |
12692 			   ELINK_SUPPORTED_Pause |
12693 			   ELINK_SUPPORTED_Asym_Pause),
12694 	.media_type	= ELINK_ETH_PHY_NOT_PRESENT,
12695 	.ver_addr	= 0,
12696 	.req_flow_ctrl	= 0,
12697 	.req_line_speed	= 0,
12698 	.speed_cap_mask	= 0,
12699 	.req_duplex	= 0,
12700 	.rsrv		= 0,
12701 	.config_init	= (config_init_t)elink_8726_config_init,
12702 	.read_status	= (read_status_t)elink_8726_read_status,
12703 	.link_reset	= (link_reset_t)elink_8726_link_reset,
12704 	.config_loopback = (config_loopback_t)elink_8726_config_loopback,
12705 	.format_fw_ver	= (format_fw_ver_t)elink_format_ver,
12706 	.hw_reset	= (hw_reset_t)NULL,
12707 	.set_link_led	= (set_link_led_t)NULL,
12708 	.phy_specific_func = (phy_specific_func_t)NULL
12709 };
12710 
12711 static const struct elink_phy phy_8727 = {
12712 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
12713 	.addr		= 0xff,
12714 	.def_md_devad	= 0,
12715 	.flags		= (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12716 			   ELINK_FLAGS_TX_ERROR_CHECK),
12717 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12718 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12719 	.mdio_ctrl	= 0,
12720 	.supported	= (ELINK_SUPPORTED_10000baseT_Full |
12721 			   ELINK_SUPPORTED_1000baseT_Full |
12722 			   ELINK_SUPPORTED_FIBRE |
12723 			   ELINK_SUPPORTED_Pause |
12724 			   ELINK_SUPPORTED_Asym_Pause),
12725 	.media_type	= ELINK_ETH_PHY_NOT_PRESENT,
12726 	.ver_addr	= 0,
12727 	.req_flow_ctrl	= 0,
12728 	.req_line_speed	= 0,
12729 	.speed_cap_mask	= 0,
12730 	.req_duplex	= 0,
12731 	.rsrv		= 0,
12732 	.config_init	= (config_init_t)elink_8727_config_init,
12733 	.read_status	= (read_status_t)elink_8727_read_status,
12734 	.link_reset	= (link_reset_t)elink_8727_link_reset,
12735 	.config_loopback = (config_loopback_t)NULL,
12736 	.format_fw_ver	= (format_fw_ver_t)elink_format_ver,
12737 	.hw_reset	= (hw_reset_t)elink_8727_hw_reset,
12738 	.set_link_led	= (set_link_led_t)elink_8727_set_link_led,
12739 	.phy_specific_func = (phy_specific_func_t)elink_8727_specific_func
12740 };
12741 static const struct elink_phy phy_8481 = {
12742 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
12743 	.addr		= 0xff,
12744 	.def_md_devad	= 0,
12745 	.flags		= ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12746 			  ELINK_FLAGS_REARM_LATCH_SIGNAL,
12747 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12748 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12749 	.mdio_ctrl	= 0,
12750 	.supported	= (ELINK_SUPPORTED_10baseT_Half |
12751 			   ELINK_SUPPORTED_10baseT_Full |
12752 			   ELINK_SUPPORTED_100baseT_Half |
12753 			   ELINK_SUPPORTED_100baseT_Full |
12754 			   ELINK_SUPPORTED_1000baseT_Full |
12755 			   ELINK_SUPPORTED_10000baseT_Full |
12756 			   ELINK_SUPPORTED_TP |
12757 			   ELINK_SUPPORTED_Autoneg |
12758 			   ELINK_SUPPORTED_Pause |
12759 			   ELINK_SUPPORTED_Asym_Pause),
12760 	.media_type	= ELINK_ETH_PHY_BASE_T,
12761 	.ver_addr	= 0,
12762 	.req_flow_ctrl	= 0,
12763 	.req_line_speed	= 0,
12764 	.speed_cap_mask	= 0,
12765 	.req_duplex	= 0,
12766 	.rsrv		= 0,
12767 	.config_init	= (config_init_t)elink_8481_config_init,
12768 	.read_status	= (read_status_t)elink_848xx_read_status,
12769 	.link_reset	= (link_reset_t)elink_8481_link_reset,
12770 	.config_loopback = (config_loopback_t)NULL,
12771 	.format_fw_ver	= (format_fw_ver_t)elink_848xx_format_ver,
12772 	.hw_reset	= (hw_reset_t)elink_8481_hw_reset,
12773 	.set_link_led	= (set_link_led_t)elink_848xx_set_link_led,
12774 	.phy_specific_func = (phy_specific_func_t)NULL
12775 };
12776 
12777 static const struct elink_phy phy_84823 = {
12778 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
12779 	.addr		= 0xff,
12780 	.def_md_devad	= 0,
12781 	.flags		= (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12782 			   ELINK_FLAGS_REARM_LATCH_SIGNAL |
12783 			   ELINK_FLAGS_TX_ERROR_CHECK),
12784 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12785 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12786 	.mdio_ctrl	= 0,
12787 	.supported	= (ELINK_SUPPORTED_10baseT_Half |
12788 			   ELINK_SUPPORTED_10baseT_Full |
12789 			   ELINK_SUPPORTED_100baseT_Half |
12790 			   ELINK_SUPPORTED_100baseT_Full |
12791 			   ELINK_SUPPORTED_1000baseT_Full |
12792 			   ELINK_SUPPORTED_10000baseT_Full |
12793 			   ELINK_SUPPORTED_TP |
12794 			   ELINK_SUPPORTED_Autoneg |
12795 			   ELINK_SUPPORTED_Pause |
12796 			   ELINK_SUPPORTED_Asym_Pause),
12797 	.media_type	= ELINK_ETH_PHY_BASE_T,
12798 	.ver_addr	= 0,
12799 	.req_flow_ctrl	= 0,
12800 	.req_line_speed	= 0,
12801 	.speed_cap_mask	= 0,
12802 	.req_duplex	= 0,
12803 	.rsrv		= 0,
12804 	.config_init	= (config_init_t)elink_848x3_config_init,
12805 	.read_status	= (read_status_t)elink_848xx_read_status,
12806 	.link_reset	= (link_reset_t)elink_848x3_link_reset,
12807 	.config_loopback = (config_loopback_t)NULL,
12808 	.format_fw_ver	= (format_fw_ver_t)elink_848xx_format_ver,
12809 	.hw_reset	= (hw_reset_t)NULL,
12810 	.set_link_led	= (set_link_led_t)elink_848xx_set_link_led,
12811 	.phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12812 };
12813 
12814 static const struct elink_phy phy_84833 = {
12815 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833,
12816 	.addr		= 0xff,
12817 	.def_md_devad	= 0,
12818 	.flags		= (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12819 			   ELINK_FLAGS_REARM_LATCH_SIGNAL |
12820 			   ELINK_FLAGS_TX_ERROR_CHECK |
12821 			   ELINK_FLAGS_TEMPERATURE),
12822 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12823 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12824 	.mdio_ctrl	= 0,
12825 	.supported	= (ELINK_SUPPORTED_100baseT_Half |
12826 			   ELINK_SUPPORTED_100baseT_Full |
12827 			   ELINK_SUPPORTED_1000baseT_Full |
12828 			   ELINK_SUPPORTED_10000baseT_Full |
12829 			   ELINK_SUPPORTED_TP |
12830 			   ELINK_SUPPORTED_Autoneg |
12831 			   ELINK_SUPPORTED_Pause |
12832 			   ELINK_SUPPORTED_Asym_Pause),
12833 	.media_type	= ELINK_ETH_PHY_BASE_T,
12834 	.ver_addr	= 0,
12835 	.req_flow_ctrl	= 0,
12836 	.req_line_speed	= 0,
12837 	.speed_cap_mask	= 0,
12838 	.req_duplex	= 0,
12839 	.rsrv		= 0,
12840 	.config_init	= (config_init_t)elink_848x3_config_init,
12841 	.read_status	= (read_status_t)elink_848xx_read_status,
12842 	.link_reset	= (link_reset_t)elink_848x3_link_reset,
12843 	.config_loopback = (config_loopback_t)NULL,
12844 	.format_fw_ver	= (format_fw_ver_t)elink_848xx_format_ver,
12845 	.hw_reset	= (hw_reset_t)elink_84833_hw_reset_phy,
12846 	.set_link_led	= (set_link_led_t)elink_848xx_set_link_led,
12847 	.phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12848 };
12849 
12850 static const struct elink_phy phy_84834 = {
12851 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834,
12852 	.addr		= 0xff,
12853 	.def_md_devad	= 0,
12854 	.flags		= ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12855 			    ELINK_FLAGS_REARM_LATCH_SIGNAL,
12856 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12857 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12858 	.mdio_ctrl	= 0,
12859 	.supported	= (ELINK_SUPPORTED_100baseT_Half |
12860 			   ELINK_SUPPORTED_100baseT_Full |
12861 			   ELINK_SUPPORTED_1000baseT_Full |
12862 			   ELINK_SUPPORTED_10000baseT_Full |
12863 			   ELINK_SUPPORTED_TP |
12864 			   ELINK_SUPPORTED_Autoneg |
12865 			   ELINK_SUPPORTED_Pause |
12866 			   ELINK_SUPPORTED_Asym_Pause),
12867 	.media_type	= ELINK_ETH_PHY_BASE_T,
12868 	.ver_addr	= 0,
12869 	.req_flow_ctrl	= 0,
12870 	.req_line_speed	= 0,
12871 	.speed_cap_mask	= 0,
12872 	.req_duplex	= 0,
12873 	.rsrv		= 0,
12874 	.config_init	= (config_init_t)elink_848x3_config_init,
12875 	.read_status	= (read_status_t)elink_848xx_read_status,
12876 	.link_reset	= (link_reset_t)elink_848x3_link_reset,
12877 	.config_loopback = (config_loopback_t)NULL,
12878 	.format_fw_ver	= (format_fw_ver_t)elink_848xx_format_ver,
12879 	.hw_reset	= (hw_reset_t)elink_84833_hw_reset_phy,
12880 	.set_link_led	= (set_link_led_t)elink_848xx_set_link_led,
12881 	.phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12882 };
12883 
12884 static const struct elink_phy phy_84858 = {
12885 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858,
12886 	.addr		= 0xff,
12887 	.def_md_devad	= 0,
12888 	.flags		= ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12889 			    ELINK_FLAGS_REARM_LATCH_SIGNAL,
12890 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12891 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12892 	.mdio_ctrl	= 0,
12893 	.supported	= (ELINK_SUPPORTED_100baseT_Half |
12894 			   ELINK_SUPPORTED_100baseT_Full |
12895 			   ELINK_SUPPORTED_1000baseT_Full |
12896 			   ELINK_SUPPORTED_10000baseT_Full |
12897 			   ELINK_SUPPORTED_TP |
12898 			   ELINK_SUPPORTED_Autoneg |
12899 			   ELINK_SUPPORTED_Pause |
12900 			   ELINK_SUPPORTED_Asym_Pause),
12901 	.media_type	= ELINK_ETH_PHY_BASE_T,
12902 	.ver_addr	= 0,
12903 	.req_flow_ctrl	= 0,
12904 	.req_line_speed	= 0,
12905 	.speed_cap_mask	= 0,
12906 	.req_duplex	= 0,
12907 	.rsrv		= 0,
12908 	.config_init	= (config_init_t)elink_848x3_config_init,
12909 	.read_status	= (read_status_t)elink_848xx_read_status,
12910 	.link_reset	= (link_reset_t)elink_848x3_link_reset,
12911 	.config_loopback = (config_loopback_t)NULL,
12912 	.format_fw_ver	= (format_fw_ver_t)elink_848xx_format_ver,
12913 	.hw_reset	= (hw_reset_t)elink_84833_hw_reset_phy,
12914 	.set_link_led	= (set_link_led_t)elink_848xx_set_link_led,
12915 	.phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12916 };
12917 
12918 
12919 static const struct elink_phy phy_54618se = {
12920 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE,
12921 	.addr		= 0xff,
12922 	.def_md_devad	= 0,
12923 	.flags		= ELINK_FLAGS_INIT_XGXS_FIRST,
12924 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12925 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12926 	.mdio_ctrl	= 0,
12927 	.supported	= (ELINK_SUPPORTED_10baseT_Half |
12928 			   ELINK_SUPPORTED_10baseT_Full |
12929 			   ELINK_SUPPORTED_100baseT_Half |
12930 			   ELINK_SUPPORTED_100baseT_Full |
12931 			   ELINK_SUPPORTED_1000baseT_Full |
12932 			   ELINK_SUPPORTED_TP |
12933 			   ELINK_SUPPORTED_Autoneg |
12934 			   ELINK_SUPPORTED_Pause |
12935 			   ELINK_SUPPORTED_Asym_Pause),
12936 	.media_type	= ELINK_ETH_PHY_BASE_T,
12937 	.ver_addr	= 0,
12938 	.req_flow_ctrl	= 0,
12939 	.req_line_speed	= 0,
12940 	.speed_cap_mask	= 0,
12941 	/* req_duplex = */0,
12942 	/* rsrv = */0,
12943 	.config_init	= (config_init_t)elink_54618se_config_init,
12944 	.read_status	= (read_status_t)elink_54618se_read_status,
12945 	.link_reset	= (link_reset_t)elink_54618se_link_reset,
12946 	.config_loopback = (config_loopback_t)elink_54618se_config_loopback,
12947 	.format_fw_ver	= (format_fw_ver_t)NULL,
12948 	.hw_reset	= (hw_reset_t)NULL,
12949 	.set_link_led	= (set_link_led_t)elink_5461x_set_link_led,
12950 	.phy_specific_func = (phy_specific_func_t)elink_54618se_specific_func
12951 };
12952 /*****************************************************************/
12953 /*                                                               */
12954 /* Populate the phy according. Main function: elink_populate_phy   */
12955 /*                                                               */
12956 /*****************************************************************/
12957 
12958 static void elink_populate_preemphasis(struct bxe_softc *sc, uint32_t shmem_base,
12959 				     struct elink_phy *phy, uint8_t port,
12960 				     uint8_t phy_index)
12961 {
12962 	/* Get the 4 lanes xgxs config rx and tx */
12963 	uint32_t rx = 0, tx = 0, i;
12964 	for (i = 0; i < 2; i++) {
12965 		/* INT_PHY and ELINK_EXT_PHY1 share the same value location in
12966 		 * the shmem. When num_phys is greater than 1, than this value
12967 		 * applies only to ELINK_EXT_PHY1
12968 		 */
12969 		if (phy_index == ELINK_INT_PHY || phy_index == ELINK_EXT_PHY1) {
12970 			rx = REG_RD(sc, shmem_base +
12971 				    offsetof(struct shmem_region,
12972 			  dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
12973 
12974 			tx = REG_RD(sc, shmem_base +
12975 				    offsetof(struct shmem_region,
12976 			  dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
12977 		} else {
12978 			rx = REG_RD(sc, shmem_base +
12979 				    offsetof(struct shmem_region,
12980 			 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
12981 
12982 			tx = REG_RD(sc, shmem_base +
12983 				    offsetof(struct shmem_region,
12984 			 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
12985 		}
12986 
12987 		phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
12988 		phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
12989 
12990 		phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
12991 		phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
12992 		ELINK_DEBUG_P2(sc,"phy->rx_preemphasis = %x, phy->tx_preemphasis = %x\n",
12993 			phy->rx_preemphasis[i << 1], phy->tx_preemphasis[i << 1]);
12994 	}
12995 }
12996 
12997 static uint32_t elink_get_ext_phy_config(struct bxe_softc *sc, uint32_t shmem_base,
12998 				    uint8_t phy_index, uint8_t port)
12999 {
13000 	uint32_t ext_phy_config = 0;
13001 	switch (phy_index) {
13002 	case ELINK_EXT_PHY1:
13003 		ext_phy_config = REG_RD(sc, shmem_base +
13004 					      offsetof(struct shmem_region,
13005 			dev_info.port_hw_config[port].external_phy_config));
13006 		break;
13007 	case ELINK_EXT_PHY2:
13008 		ext_phy_config = REG_RD(sc, shmem_base +
13009 					      offsetof(struct shmem_region,
13010 			dev_info.port_hw_config[port].external_phy_config2));
13011 		break;
13012 	default:
13013 		ELINK_DEBUG_P1(sc, "Invalid phy_index %d\n", phy_index);
13014 		return ELINK_STATUS_ERROR;
13015 	}
13016 
13017 	return ext_phy_config;
13018 }
13019 static elink_status_t elink_populate_int_phy(struct bxe_softc *sc, uint32_t shmem_base, uint8_t port,
13020 				  struct elink_phy *phy)
13021 {
13022 	uint32_t phy_addr;
13023 	uint32_t chip_id;
13024 	uint32_t switch_cfg = (REG_RD(sc, shmem_base +
13025 				       offsetof(struct shmem_region,
13026 			dev_info.port_feature_config[port].link_config)) &
13027 			  PORT_FEATURE_CONNECTED_SWITCH_MASK);
13028 	chip_id = (REG_RD(sc, MISC_REG_CHIP_NUM) << 16) |
13029 		((REG_RD(sc, MISC_REG_CHIP_REV) & 0xf) << 12);
13030 
13031 	ELINK_DEBUG_P1(sc, ":chip_id = 0x%x\n", chip_id);
13032 	if (USES_WARPCORE(sc)) {
13033 		uint32_t serdes_net_if;
13034 		phy_addr = REG_RD(sc,
13035 				  MISC_REG_WC0_CTRL_PHY_ADDR);
13036 		*phy = phy_warpcore;
13037 		if (REG_RD(sc, MISC_REG_PORT4MODE_EN_OVWR) == 0x3)
13038 			phy->flags |= ELINK_FLAGS_4_PORT_MODE;
13039 		else
13040 			phy->flags &= ~ELINK_FLAGS_4_PORT_MODE;
13041 			/* Check Dual mode */
13042 		serdes_net_if = (REG_RD(sc, shmem_base +
13043 					offsetof(struct shmem_region, dev_info.
13044 					port_hw_config[port].default_cfg)) &
13045 				 PORT_HW_CFG_NET_SERDES_IF_MASK);
13046 		/* Set the appropriate supported and flags indications per
13047 		 * interface type of the chip
13048 		 */
13049 		switch (serdes_net_if) {
13050 		case PORT_HW_CFG_NET_SERDES_IF_SGMII:
13051 			phy->supported &= (ELINK_SUPPORTED_10baseT_Half |
13052 					   ELINK_SUPPORTED_10baseT_Full |
13053 					   ELINK_SUPPORTED_100baseT_Half |
13054 					   ELINK_SUPPORTED_100baseT_Full |
13055 					   ELINK_SUPPORTED_1000baseT_Full |
13056 					   ELINK_SUPPORTED_FIBRE |
13057 					   ELINK_SUPPORTED_Autoneg |
13058 					   ELINK_SUPPORTED_Pause |
13059 					   ELINK_SUPPORTED_Asym_Pause);
13060 			phy->media_type = ELINK_ETH_PHY_BASE_T;
13061 			break;
13062 		case PORT_HW_CFG_NET_SERDES_IF_XFI:
13063 			phy->supported &= (ELINK_SUPPORTED_1000baseT_Full |
13064 					   ELINK_SUPPORTED_10000baseT_Full |
13065 					   ELINK_SUPPORTED_FIBRE |
13066 					   ELINK_SUPPORTED_Pause |
13067 					   ELINK_SUPPORTED_Asym_Pause);
13068 			phy->media_type = ELINK_ETH_PHY_XFP_FIBER;
13069 			break;
13070 		case PORT_HW_CFG_NET_SERDES_IF_SFI:
13071 			phy->supported &= (ELINK_SUPPORTED_1000baseT_Full |
13072 					   ELINK_SUPPORTED_10000baseT_Full |
13073 					   ELINK_SUPPORTED_FIBRE |
13074 					   ELINK_SUPPORTED_Pause |
13075 					   ELINK_SUPPORTED_Asym_Pause);
13076 			phy->media_type = ELINK_ETH_PHY_SFPP_10G_FIBER;
13077 			break;
13078 		case PORT_HW_CFG_NET_SERDES_IF_KR:
13079 			phy->media_type = ELINK_ETH_PHY_KR;
13080 			phy->supported &= (ELINK_SUPPORTED_1000baseKX_Full |
13081 					   ELINK_SUPPORTED_10000baseKR_Full |
13082 					   ELINK_SUPPORTED_FIBRE |
13083 					   ELINK_SUPPORTED_Autoneg |
13084 					   ELINK_SUPPORTED_Pause |
13085 					   ELINK_SUPPORTED_Asym_Pause);
13086 			break;
13087 		case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
13088 			phy->media_type = ELINK_ETH_PHY_KR;
13089 			phy->flags |= ELINK_FLAGS_WC_DUAL_MODE;
13090 			phy->supported &= (ELINK_SUPPORTED_20000baseMLD2_Full |
13091 					   ELINK_SUPPORTED_FIBRE |
13092 					   ELINK_SUPPORTED_Pause |
13093 					   ELINK_SUPPORTED_Asym_Pause);
13094 			break;
13095 		case PORT_HW_CFG_NET_SERDES_IF_KR2:
13096 			phy->media_type = ELINK_ETH_PHY_KR;
13097 			phy->flags |= ELINK_FLAGS_WC_DUAL_MODE;
13098 			phy->supported &= (ELINK_SUPPORTED_20000baseKR2_Full |
13099 					   ELINK_SUPPORTED_10000baseKR_Full |
13100 					   ELINK_SUPPORTED_1000baseKX_Full |
13101 					   ELINK_SUPPORTED_Autoneg |
13102 					   ELINK_SUPPORTED_FIBRE |
13103 					   ELINK_SUPPORTED_Pause |
13104 					   ELINK_SUPPORTED_Asym_Pause);
13105 			phy->flags &= ~ELINK_FLAGS_TX_ERROR_CHECK;
13106 			break;
13107 		default:
13108 			ELINK_DEBUG_P1(sc, "Unknown WC interface type 0x%x\n",
13109 				       serdes_net_if);
13110 			break;
13111 		}
13112 
13113 		/* Enable MDC/MDIO work-around for E3 A0 since free running MDC
13114 		 * was not set as expected. For B0, ECO will be enabled so there
13115 		 * won't be an issue there
13116 		 */
13117 		if (CHIP_REV(sc) == CHIP_REV_Ax)
13118 			phy->flags |= ELINK_FLAGS_MDC_MDIO_WA;
13119 		else
13120 			phy->flags |= ELINK_FLAGS_MDC_MDIO_WA_B0;
13121 		ELINK_DEBUG_P3(sc, "media_type = %x, flags = %x, supported = %x\n",
13122 				phy->media_type, phy->flags, phy->supported);
13123 	} else
13124 	{
13125 		switch (switch_cfg) {
13126 		case ELINK_SWITCH_CFG_1G:
13127 			phy_addr = REG_RD(sc,
13128 					  NIG_REG_SERDES0_CTRL_PHY_ADDR +
13129 					  port * 0x10);
13130 			*phy = phy_serdes;
13131 			break;
13132 		case ELINK_SWITCH_CFG_10G:
13133 			phy_addr = REG_RD(sc,
13134 					  NIG_REG_XGXS0_CTRL_PHY_ADDR +
13135 					  port * 0x18);
13136 			*phy = phy_xgxs;
13137 			break;
13138 		default:
13139 			ELINK_DEBUG_P0(sc, "Invalid switch_cfg\n");
13140 			return ELINK_STATUS_ERROR;
13141 		}
13142 	}
13143 	phy->addr = (uint8_t)phy_addr;
13144 	phy->mdio_ctrl = elink_get_emac_base(sc,
13145 					    SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
13146 					    port);
13147 	if (CHIP_IS_E2(sc))
13148 		phy->def_md_devad = ELINK_E2_DEFAULT_PHY_DEV_ADDR;
13149 	else
13150 		phy->def_md_devad = ELINK_DEFAULT_PHY_DEV_ADDR;
13151 
13152 	ELINK_DEBUG_P3(sc, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
13153 		   port, phy->addr, phy->mdio_ctrl);
13154 
13155 	elink_populate_preemphasis(sc, shmem_base, phy, port, ELINK_INT_PHY);
13156 	return ELINK_STATUS_OK;
13157 }
13158 
13159 static elink_status_t elink_populate_ext_phy(struct bxe_softc *sc,
13160 				  uint8_t phy_index,
13161 				  uint32_t shmem_base,
13162 				  uint32_t shmem2_base,
13163 				  uint8_t port,
13164 				  struct elink_phy *phy)
13165 {
13166 	uint32_t ext_phy_config, phy_type, config2;
13167 	uint32_t mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
13168 	ext_phy_config = elink_get_ext_phy_config(sc, shmem_base,
13169 						  phy_index, port);
13170 	phy_type = ELINK_XGXS_EXT_PHY_TYPE(ext_phy_config);
13171 	/* Select the phy type */
13172 	switch (phy_type) {
13173 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
13174 		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
13175 		*phy = phy_8073;
13176 		break;
13177 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
13178 		*phy = phy_8705;
13179 		break;
13180 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
13181 		*phy = phy_8706;
13182 		break;
13183 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
13184 		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
13185 		*phy = phy_8726;
13186 		break;
13187 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
13188 		/* BCM8727_NOC => BCM8727 no over current */
13189 		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
13190 		*phy = phy_8727;
13191 		phy->flags |= ELINK_FLAGS_NOC;
13192 		break;
13193 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
13194 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
13195 		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
13196 		*phy = phy_8727;
13197 		break;
13198 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
13199 		*phy = phy_8481;
13200 		break;
13201 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
13202 		*phy = phy_84823;
13203 		break;
13204 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
13205 		*phy = phy_84833;
13206 		break;
13207 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834:
13208 		*phy = phy_84834;
13209 		break;
13210 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858:
13211 		*phy = phy_84858;
13212 		break;
13213 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616:
13214 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE:
13215 		*phy = phy_54618se;
13216 		if (phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
13217 			phy->flags |= ELINK_FLAGS_EEE;
13218 		break;
13219 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
13220 		*phy = phy_7101;
13221 		break;
13222 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
13223 		*phy = phy_null;
13224 		return ELINK_STATUS_ERROR;
13225 	default:
13226 		*phy = phy_null;
13227 		/* In case external PHY wasn't found */
13228 		if ((phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
13229 		    (phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
13230 			return ELINK_STATUS_ERROR;
13231 		return ELINK_STATUS_OK;
13232 	}
13233 
13234 	phy->addr = ELINK_XGXS_EXT_PHY_ADDR(ext_phy_config);
13235 	elink_populate_preemphasis(sc, shmem_base, phy, port, phy_index);
13236 
13237 	/* The shmem address of the phy version is located on different
13238 	 * structures. In case this structure is too old, do not set
13239 	 * the address
13240 	 */
13241 	config2 = REG_RD(sc, shmem_base + offsetof(struct shmem_region,
13242 					dev_info.shared_hw_config.config2));
13243 	if (phy_index == ELINK_EXT_PHY1) {
13244 		phy->ver_addr = shmem_base + offsetof(struct shmem_region,
13245 				port_mb[port].ext_phy_fw_version);
13246 
13247 		/* Check specific mdc mdio settings */
13248 		if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
13249 			mdc_mdio_access = config2 &
13250 			SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
13251 	} else {
13252 		uint32_t size = REG_RD(sc, shmem2_base);
13253 
13254 		if (size >
13255 		    offsetof(struct shmem2_region, ext_phy_fw_version2)) {
13256 			phy->ver_addr = shmem2_base +
13257 			    offsetof(struct shmem2_region,
13258 				     ext_phy_fw_version2[port]);
13259 		}
13260 		/* Check specific mdc mdio settings */
13261 		if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
13262 			mdc_mdio_access = (config2 &
13263 			SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
13264 			(SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
13265 			 SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
13266 	}
13267 	phy->mdio_ctrl = elink_get_emac_base(sc, mdc_mdio_access, port);
13268 
13269 	if (elink_is_8483x_8485x(phy) && (phy->ver_addr)) {
13270 		/* Remove 100Mb link supported for BCM84833/4 when phy fw
13271 		 * version lower than or equal to 1.39
13272 		 */
13273 		uint32_t raw_ver = REG_RD(sc, phy->ver_addr);
13274 		if (((raw_ver & 0x7F) <= 39) &&
13275 		    (((raw_ver & 0xF80) >> 7) <= 1))
13276 			phy->supported &= ~(ELINK_SUPPORTED_100baseT_Half |
13277 					    ELINK_SUPPORTED_100baseT_Full);
13278 	}
13279 
13280 	ELINK_DEBUG_P3(sc, "phy_type 0x%x port %d found in index %d\n",
13281 		   phy_type, port, phy_index);
13282 	ELINK_DEBUG_P2(sc, "             addr=0x%x, mdio_ctl=0x%x\n",
13283 		   phy->addr, phy->mdio_ctrl);
13284 	return ELINK_STATUS_OK;
13285 }
13286 
13287 static elink_status_t elink_populate_phy(struct bxe_softc *sc, uint8_t phy_index, uint32_t shmem_base,
13288 			      uint32_t shmem2_base, uint8_t port, struct elink_phy *phy)
13289 {
13290 	elink_status_t status = ELINK_STATUS_OK;
13291 	phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
13292 	if (phy_index == ELINK_INT_PHY)
13293 		return elink_populate_int_phy(sc, shmem_base, port, phy);
13294 	status = elink_populate_ext_phy(sc, phy_index, shmem_base, shmem2_base,
13295 					port, phy);
13296 	return status;
13297 }
13298 
13299 static void elink_phy_def_cfg(struct elink_params *params,
13300 			      struct elink_phy *phy,
13301 			      uint8_t phy_index)
13302 {
13303 	struct bxe_softc *sc = params->sc;
13304 	uint32_t link_config;
13305 	/* Populate the default phy configuration for MF mode */
13306 	if (phy_index == ELINK_EXT_PHY2) {
13307 		link_config = REG_RD(sc, params->shmem_base +
13308 				     offsetof(struct shmem_region, dev_info.
13309 			port_feature_config[params->port].link_config2));
13310 		phy->speed_cap_mask = REG_RD(sc, params->shmem_base +
13311 					     offsetof(struct shmem_region,
13312 						      dev_info.
13313 			port_hw_config[params->port].speed_capability_mask2));
13314 	} else {
13315 		link_config = REG_RD(sc, params->shmem_base +
13316 				     offsetof(struct shmem_region, dev_info.
13317 				port_feature_config[params->port].link_config));
13318 		phy->speed_cap_mask = REG_RD(sc, params->shmem_base +
13319 					     offsetof(struct shmem_region,
13320 						      dev_info.
13321 			port_hw_config[params->port].speed_capability_mask));
13322 	}
13323 	ELINK_DEBUG_P3(sc,
13324 	   "Default config phy idx %x cfg 0x%x speed_cap_mask 0x%x\n",
13325 	   phy_index, link_config, phy->speed_cap_mask);
13326 
13327 	phy->req_duplex = DUPLEX_FULL;
13328 	switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
13329 	case PORT_FEATURE_LINK_SPEED_10M_HALF:
13330 		phy->req_duplex = DUPLEX_HALF;
13331 	case PORT_FEATURE_LINK_SPEED_10M_FULL:
13332 		phy->req_line_speed = ELINK_SPEED_10;
13333 		break;
13334 	case PORT_FEATURE_LINK_SPEED_100M_HALF:
13335 		phy->req_duplex = DUPLEX_HALF;
13336 	case PORT_FEATURE_LINK_SPEED_100M_FULL:
13337 		phy->req_line_speed = ELINK_SPEED_100;
13338 		break;
13339 	case PORT_FEATURE_LINK_SPEED_1G:
13340 		phy->req_line_speed = ELINK_SPEED_1000;
13341 		break;
13342 	case PORT_FEATURE_LINK_SPEED_2_5G:
13343 		phy->req_line_speed = ELINK_SPEED_2500;
13344 		break;
13345 	case PORT_FEATURE_LINK_SPEED_10G_CX4:
13346 		phy->req_line_speed = ELINK_SPEED_10000;
13347 		break;
13348 	default:
13349 		phy->req_line_speed = ELINK_SPEED_AUTO_NEG;
13350 		break;
13351 	}
13352 
13353 	ELINK_DEBUG_P2(sc, "Default config phy idx %x, req_duplex config %x\n",
13354 			phy_index, phy->req_duplex);
13355 
13356 	switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
13357 	case PORT_FEATURE_FLOW_CONTROL_AUTO:
13358 		phy->req_flow_ctrl = ELINK_FLOW_CTRL_AUTO;
13359 		break;
13360 	case PORT_FEATURE_FLOW_CONTROL_TX:
13361 		phy->req_flow_ctrl = ELINK_FLOW_CTRL_TX;
13362 		break;
13363 	case PORT_FEATURE_FLOW_CONTROL_RX:
13364 		phy->req_flow_ctrl = ELINK_FLOW_CTRL_RX;
13365 		break;
13366 	case PORT_FEATURE_FLOW_CONTROL_BOTH:
13367 		phy->req_flow_ctrl = ELINK_FLOW_CTRL_BOTH;
13368 		break;
13369 	default:
13370 		phy->req_flow_ctrl = ELINK_FLOW_CTRL_NONE;
13371 		break;
13372 	}
13373 	ELINK_DEBUG_P3(sc, "Requested Duplex = %x, line_speed = %x, flow_ctrl = %x\n",
13374 			phy->req_duplex, phy->req_line_speed, phy->req_flow_ctrl);
13375 }
13376 
13377 uint32_t elink_phy_selection(struct elink_params *params)
13378 {
13379 	uint32_t phy_config_swapped, prio_cfg;
13380 	uint32_t return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
13381 
13382 	phy_config_swapped = params->multi_phy_config &
13383 		PORT_HW_CFG_PHY_SWAPPED_ENABLED;
13384 
13385 	prio_cfg = params->multi_phy_config &
13386 			PORT_HW_CFG_PHY_SELECTION_MASK;
13387 
13388 	if (phy_config_swapped) {
13389 		switch (prio_cfg) {
13390 		case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
13391 		     return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
13392 		     break;
13393 		case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
13394 		     return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
13395 		     break;
13396 		case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
13397 		     return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
13398 		     break;
13399 		case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
13400 		     return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
13401 		     break;
13402 		}
13403 	} else
13404 		return_cfg = prio_cfg;
13405 
13406 	return return_cfg;
13407 }
13408 
13409 elink_status_t elink_phy_probe(struct elink_params *params)
13410 {
13411 	uint8_t phy_index, actual_phy_idx;
13412 	uint32_t phy_config_swapped, sync_offset, media_types;
13413 	struct bxe_softc *sc = params->sc;
13414 	struct elink_phy *phy;
13415 	params->num_phys = 0;
13416 	ELINK_DEBUG_P0(sc, "Begin phy probe\n");
13417 #ifdef ELINK_INCLUDE_EMUL
13418 	if (CHIP_REV_IS_EMUL(sc))
13419 		return ELINK_STATUS_OK;
13420 #endif
13421 	phy_config_swapped = params->multi_phy_config &
13422 		PORT_HW_CFG_PHY_SWAPPED_ENABLED;
13423 
13424 	for (phy_index = ELINK_INT_PHY; phy_index < ELINK_MAX_PHYS;
13425 	      phy_index++) {
13426 		actual_phy_idx = phy_index;
13427 		if (phy_config_swapped) {
13428 			if (phy_index == ELINK_EXT_PHY1)
13429 				actual_phy_idx = ELINK_EXT_PHY2;
13430 			else if (phy_index == ELINK_EXT_PHY2)
13431 				actual_phy_idx = ELINK_EXT_PHY1;
13432 		}
13433 		ELINK_DEBUG_P3(sc, "phy_config_swapped %x, phy_index %x,"
13434 			       " actual_phy_idx %x\n", phy_config_swapped,
13435 			   phy_index, actual_phy_idx);
13436 		phy = &params->phy[actual_phy_idx];
13437 		if (elink_populate_phy(sc, phy_index, params->shmem_base,
13438 				       params->shmem2_base, params->port,
13439 				       phy) != ELINK_STATUS_OK) {
13440 			params->num_phys = 0;
13441 			ELINK_DEBUG_P1(sc, "phy probe failed in phy index %d\n",
13442 				   phy_index);
13443 			for (phy_index = ELINK_INT_PHY;
13444 			      phy_index < ELINK_MAX_PHYS;
13445 			      phy_index++)
13446 				*phy = phy_null;
13447 			return ELINK_STATUS_ERROR;
13448 		}
13449 		if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
13450 			break;
13451 
13452 		if (params->feature_config_flags &
13453 		    ELINK_FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET)
13454 			phy->flags &= ~ELINK_FLAGS_TX_ERROR_CHECK;
13455 
13456 		if (!(params->feature_config_flags &
13457 		      ELINK_FEATURE_CONFIG_MT_SUPPORT))
13458 			phy->flags |= ELINK_FLAGS_MDC_MDIO_WA_G;
13459 
13460 		sync_offset = params->shmem_base +
13461 			offsetof(struct shmem_region,
13462 			dev_info.port_hw_config[params->port].media_type);
13463 		media_types = REG_RD(sc, sync_offset);
13464 
13465 		/* Update media type for non-PMF sync only for the first time
13466 		 * In case the media type changes afterwards, it will be updated
13467 		 * using the update_status function
13468 		 */
13469 		if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
13470 				    (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
13471 				     actual_phy_idx))) == 0) {
13472 			media_types |= ((phy->media_type &
13473 					PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
13474 				(PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
13475 				 actual_phy_idx));
13476 		}
13477 		REG_WR(sc, sync_offset, media_types);
13478 
13479 		elink_phy_def_cfg(params, phy, phy_index);
13480 		params->num_phys++;
13481 	}
13482 
13483 	ELINK_DEBUG_P1(sc, "End phy probe. #phys found %x\n", params->num_phys);
13484 	return ELINK_STATUS_OK;
13485 }
13486 
13487 #ifdef ELINK_INCLUDE_EMUL
13488 static elink_status_t elink_init_e3_emul_mac(struct elink_params *params,
13489 					     struct elink_vars *vars)
13490 {
13491 	struct bxe_softc *sc = params->sc;
13492 	vars->line_speed = params->req_line_speed[0];
13493 	/* In case link speed is auto, set speed the highest as possible */
13494 	if (params->req_line_speed[0] == ELINK_SPEED_AUTO_NEG) {
13495 		if (params->feature_config_flags &
13496 		    ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC)
13497 			vars->line_speed = ELINK_SPEED_2500;
13498 		else if (elink_is_4_port_mode(sc))
13499 			vars->line_speed = ELINK_SPEED_10000;
13500 		else
13501 			vars->line_speed = ELINK_SPEED_20000;
13502 	}
13503 	if (vars->line_speed < ELINK_SPEED_10000) {
13504 		if ((params->feature_config_flags &
13505 		     ELINK_FEATURE_CONFIG_EMUL_DISABLE_UMAC)) {
13506 			ELINK_DEBUG_P1(sc, "Invalid line speed %d while UMAC is"
13507 				   " disabled!\n", params->req_line_speed[0]);
13508 			return ELINK_STATUS_ERROR;
13509 		}
13510 		switch (vars->line_speed) {
13511 		case ELINK_SPEED_10:
13512 			vars->link_status = ELINK_LINK_10TFD;
13513 			break;
13514 		case ELINK_SPEED_100:
13515 			vars->link_status = ELINK_LINK_100TXFD;
13516 			break;
13517 		case ELINK_SPEED_1000:
13518 			vars->link_status = ELINK_LINK_1000TFD;
13519 			break;
13520 		case ELINK_SPEED_2500:
13521 			vars->link_status = ELINK_LINK_2500TFD;
13522 			break;
13523 		default:
13524 			ELINK_DEBUG_P1(sc, "Invalid line speed %d for UMAC\n",
13525 				   vars->line_speed);
13526 			return ELINK_STATUS_ERROR;
13527 		}
13528 		vars->link_status |= LINK_STATUS_LINK_UP;
13529 
13530 		if (params->loopback_mode == ELINK_LOOPBACK_UMAC)
13531 			elink_umac_enable(params, vars, 1);
13532 		else
13533 			elink_umac_enable(params, vars, 0);
13534 	} else {
13535 		/* Link speed >= 10000 requires XMAC enabled */
13536 		if (params->feature_config_flags &
13537 		    ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC) {
13538 			ELINK_DEBUG_P1(sc, "Invalid line speed %d while XMAC is"
13539 				   " disabled!\n", params->req_line_speed[0]);
13540 		return ELINK_STATUS_ERROR;
13541 	}
13542 		/* Check link speed */
13543 		switch (vars->line_speed) {
13544 		case ELINK_SPEED_10000:
13545 			vars->link_status = ELINK_LINK_10GTFD;
13546 			break;
13547 		case ELINK_SPEED_20000:
13548 			vars->link_status = ELINK_LINK_20GTFD;
13549 			break;
13550 		default:
13551 			ELINK_DEBUG_P1(sc, "Invalid line speed %d for XMAC\n",
13552 				   vars->line_speed);
13553 			return ELINK_STATUS_ERROR;
13554 		}
13555 		vars->link_status |= LINK_STATUS_LINK_UP;
13556 		if (params->loopback_mode == ELINK_LOOPBACK_XMAC)
13557 			elink_xmac_enable(params, vars, 1);
13558 		else
13559 			elink_xmac_enable(params, vars, 0);
13560 	}
13561 		return ELINK_STATUS_OK;
13562 }
13563 
13564 static elink_status_t elink_init_emul(struct elink_params *params,
13565 			    struct elink_vars *vars)
13566 {
13567 	struct bxe_softc *sc = params->sc;
13568 	if (CHIP_IS_E3(sc)) {
13569 		if (elink_init_e3_emul_mac(params, vars) !=
13570 		    ELINK_STATUS_OK)
13571 			return ELINK_STATUS_ERROR;
13572 	} else {
13573 		if (params->feature_config_flags &
13574 		    ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC) {
13575 			vars->line_speed = ELINK_SPEED_1000;
13576 			vars->link_status = (LINK_STATUS_LINK_UP |
13577 					     ELINK_LINK_1000XFD);
13578 			if (params->loopback_mode ==
13579 			    ELINK_LOOPBACK_EMAC)
13580 				elink_emac_enable(params, vars, 1);
13581 			else
13582 				elink_emac_enable(params, vars, 0);
13583 		} else {
13584 			vars->line_speed = ELINK_SPEED_10000;
13585 			vars->link_status = (LINK_STATUS_LINK_UP |
13586 					     ELINK_LINK_10GTFD);
13587 			if (params->loopback_mode ==
13588 			    ELINK_LOOPBACK_BMAC)
13589 				elink_bmac_enable(params, vars, 1, 1);
13590 			else
13591 				elink_bmac_enable(params, vars, 0, 1);
13592 		}
13593 	}
13594 	vars->link_up = 1;
13595 	vars->duplex = DUPLEX_FULL;
13596 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13597 
13598 		if (CHIP_IS_E1x(sc))
13599 			elink_pbf_update(params, vars->flow_ctrl,
13600 					 vars->line_speed);
13601 		/* Disable drain */
13602 		REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13603 
13604 		/* update shared memory */
13605 		elink_update_mng(params, vars->link_status);
13606 	return ELINK_STATUS_OK;
13607 }
13608 #endif
13609 #ifdef ELINK_INCLUDE_FPGA
13610 static elink_status_t elink_init_fpga(struct elink_params *params,
13611 			    struct elink_vars *vars)
13612 {
13613 	/* Enable on E1.5 FPGA */
13614 	struct bxe_softc *sc = params->sc;
13615 	vars->duplex = DUPLEX_FULL;
13616 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13617 	if (!(CHIP_IS_E1(sc))) {
13618 		vars->flow_ctrl = (ELINK_FLOW_CTRL_TX |
13619 				   ELINK_FLOW_CTRL_RX);
13620 		vars->link_status |= (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
13621 				      LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
13622 	}
13623 	if (CHIP_IS_E3(sc)) {
13624 		vars->line_speed = params->req_line_speed[0];
13625 		switch (vars->line_speed) {
13626 		case ELINK_SPEED_AUTO_NEG:
13627 			vars->line_speed = ELINK_SPEED_2500;
13628 		case ELINK_SPEED_2500:
13629 			vars->link_status = ELINK_LINK_2500TFD;
13630 			break;
13631 		case ELINK_SPEED_1000:
13632 			vars->link_status = ELINK_LINK_1000XFD;
13633 			break;
13634 		case ELINK_SPEED_100:
13635 			vars->link_status = ELINK_LINK_100TXFD;
13636 			break;
13637 		case ELINK_SPEED_10:
13638 			vars->link_status = ELINK_LINK_10TFD;
13639 			break;
13640 		default:
13641 			ELINK_DEBUG_P1(sc, "Invalid link speed %d\n",
13642 				   params->req_line_speed[0]);
13643 			return ELINK_STATUS_ERROR;
13644 		}
13645 		vars->link_status |= LINK_STATUS_LINK_UP;
13646 		if (params->loopback_mode == ELINK_LOOPBACK_UMAC)
13647 			elink_umac_enable(params, vars, 1);
13648 		else
13649 			elink_umac_enable(params, vars, 0);
13650 	} else {
13651 		vars->line_speed = ELINK_SPEED_10000;
13652 		vars->link_status = (LINK_STATUS_LINK_UP | ELINK_LINK_10GTFD);
13653 		if (params->loopback_mode == ELINK_LOOPBACK_EMAC)
13654 			elink_emac_enable(params, vars, 1);
13655 		else
13656 			elink_emac_enable(params, vars, 0);
13657 	}
13658 	vars->link_up = 1;
13659 
13660 	if (CHIP_IS_E1x(sc))
13661 		elink_pbf_update(params, vars->flow_ctrl,
13662 				 vars->line_speed);
13663 	/* Disable drain */
13664 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13665 
13666 	/* Update shared memory */
13667 	elink_update_mng(params, vars->link_status);
13668 		return ELINK_STATUS_OK;
13669 }
13670 #endif
13671 static void elink_init_bmac_loopback(struct elink_params *params,
13672 				     struct elink_vars *vars)
13673 {
13674 	struct bxe_softc *sc = params->sc;
13675 		vars->link_up = 1;
13676 		vars->line_speed = ELINK_SPEED_10000;
13677 		vars->duplex = DUPLEX_FULL;
13678 		vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13679 		vars->mac_type = ELINK_MAC_TYPE_BMAC;
13680 
13681 		vars->phy_flags = PHY_XGXS_FLAG;
13682 
13683 		elink_xgxs_deassert(params);
13684 
13685 		/* Set bmac loopback */
13686 		elink_bmac_enable(params, vars, 1, 1);
13687 
13688 		REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13689 }
13690 
13691 static void elink_init_emac_loopback(struct elink_params *params,
13692 				     struct elink_vars *vars)
13693 {
13694 	struct bxe_softc *sc = params->sc;
13695 		vars->link_up = 1;
13696 		vars->line_speed = ELINK_SPEED_1000;
13697 		vars->duplex = DUPLEX_FULL;
13698 		vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13699 		vars->mac_type = ELINK_MAC_TYPE_EMAC;
13700 
13701 		vars->phy_flags = PHY_XGXS_FLAG;
13702 
13703 		elink_xgxs_deassert(params);
13704 		/* Set bmac loopback */
13705 		elink_emac_enable(params, vars, 1);
13706 		elink_emac_program(params, vars);
13707 		REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13708 }
13709 
13710 static void elink_init_xmac_loopback(struct elink_params *params,
13711 				     struct elink_vars *vars)
13712 {
13713 	struct bxe_softc *sc = params->sc;
13714 	vars->link_up = 1;
13715 	if (!params->req_line_speed[0])
13716 		vars->line_speed = ELINK_SPEED_10000;
13717 	else
13718 		vars->line_speed = params->req_line_speed[0];
13719 	vars->duplex = DUPLEX_FULL;
13720 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13721 	vars->mac_type = ELINK_MAC_TYPE_XMAC;
13722 	vars->phy_flags = PHY_XGXS_FLAG;
13723 	/* Set WC to loopback mode since link is required to provide clock
13724 	 * to the XMAC in 20G mode
13725 	 */
13726 	elink_set_aer_mmd(params, &params->phy[0]);
13727 	elink_warpcore_reset_lane(sc, &params->phy[0], 0);
13728 	params->phy[ELINK_INT_PHY].config_loopback(
13729 			&params->phy[ELINK_INT_PHY],
13730 			params);
13731 
13732 	elink_xmac_enable(params, vars, 1);
13733 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13734 }
13735 
13736 static void elink_init_umac_loopback(struct elink_params *params,
13737 				     struct elink_vars *vars)
13738 {
13739 	struct bxe_softc *sc = params->sc;
13740 	vars->link_up = 1;
13741 	vars->line_speed = ELINK_SPEED_1000;
13742 	vars->duplex = DUPLEX_FULL;
13743 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13744 	vars->mac_type = ELINK_MAC_TYPE_UMAC;
13745 	vars->phy_flags = PHY_XGXS_FLAG;
13746 	elink_umac_enable(params, vars, 1);
13747 
13748 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13749 }
13750 
13751 static void elink_init_xgxs_loopback(struct elink_params *params,
13752 				     struct elink_vars *vars)
13753 {
13754 	struct bxe_softc *sc = params->sc;
13755 	struct elink_phy *int_phy = &params->phy[ELINK_INT_PHY];
13756 	vars->link_up = 1;
13757 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13758 	vars->duplex = DUPLEX_FULL;
13759 	if (params->req_line_speed[0] == ELINK_SPEED_1000)
13760 		vars->line_speed = ELINK_SPEED_1000;
13761 	else if ((params->req_line_speed[0] == ELINK_SPEED_20000) ||
13762 		 (int_phy->flags & ELINK_FLAGS_WC_DUAL_MODE))
13763 		vars->line_speed = ELINK_SPEED_20000;
13764 	else
13765 		vars->line_speed = ELINK_SPEED_10000;
13766 
13767 	if (!USES_WARPCORE(sc))
13768 		elink_xgxs_deassert(params);
13769 	elink_link_initialize(params, vars);
13770 
13771 	if (params->req_line_speed[0] == ELINK_SPEED_1000) {
13772 		if (USES_WARPCORE(sc))
13773 			elink_umac_enable(params, vars, 0);
13774 		else {
13775 			elink_emac_program(params, vars);
13776 			elink_emac_enable(params, vars, 0);
13777 		}
13778 	} else {
13779 		if (USES_WARPCORE(sc))
13780 			elink_xmac_enable(params, vars, 0);
13781 		else
13782 			elink_bmac_enable(params, vars, 0, 1);
13783 	}
13784 
13785 	if (params->loopback_mode == ELINK_LOOPBACK_XGXS) {
13786 		/* Set 10G XGXS loopback */
13787 		int_phy->config_loopback(int_phy, params);
13788 	} else {
13789 		/* Set external phy loopback */
13790 		uint8_t phy_index;
13791 		for (phy_index = ELINK_EXT_PHY1;
13792 		      phy_index < params->num_phys; phy_index++)
13793 			if (params->phy[phy_index].config_loopback)
13794 				params->phy[phy_index].config_loopback(
13795 					&params->phy[phy_index],
13796 					params);
13797 	}
13798 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13799 
13800 	elink_set_led(params, vars, ELINK_LED_MODE_OPER, vars->line_speed);
13801 }
13802 
13803 void elink_set_rx_filter(struct elink_params *params, uint8_t en)
13804 {
13805 	struct bxe_softc *sc = params->sc;
13806 	uint8_t val = en * 0x1F;
13807 
13808 	/* Open / close the gate between the NIG and the BRB */
13809 	if (!CHIP_IS_E1x(sc))
13810 		val |= en * 0x20;
13811 	REG_WR(sc, NIG_REG_LLH0_BRB1_DRV_MASK + params->port*4, val);
13812 
13813 	if (!CHIP_IS_E1(sc)) {
13814 		REG_WR(sc, NIG_REG_LLH0_BRB1_DRV_MASK_MF + params->port*4,
13815 		       en*0x3);
13816 	}
13817 
13818 	REG_WR(sc, (params->port ? NIG_REG_LLH1_BRB1_NOT_MCP :
13819 		    NIG_REG_LLH0_BRB1_NOT_MCP), en);
13820 }
13821 static elink_status_t elink_avoid_link_flap(struct elink_params *params,
13822 					    struct elink_vars *vars)
13823 {
13824 	uint32_t phy_idx;
13825 	uint32_t dont_clear_stat, lfa_sts;
13826 	struct bxe_softc *sc = params->sc;
13827 
13828 	elink_set_mdio_emac_per_phy(sc, params);
13829 	/* Sync the link parameters */
13830 	elink_link_status_update(params, vars);
13831 
13832 	/*
13833 	 * The module verification was already done by previous link owner,
13834 	 * so this call is meant only to get warning message
13835 	 */
13836 
13837 	for (phy_idx = ELINK_INT_PHY; phy_idx < params->num_phys; phy_idx++) {
13838 		struct elink_phy *phy = &params->phy[phy_idx];
13839 		if (phy->phy_specific_func) {
13840 			ELINK_DEBUG_P0(sc, "Calling PHY specific func\n");
13841 			phy->phy_specific_func(phy, params, ELINK_PHY_INIT);
13842 		}
13843 		if ((phy->media_type == ELINK_ETH_PHY_SFPP_10G_FIBER) ||
13844 		    (phy->media_type == ELINK_ETH_PHY_SFP_1G_FIBER) ||
13845 		    (phy->media_type == ELINK_ETH_PHY_DA_TWINAX))
13846 			elink_verify_sfp_module(phy, params);
13847 	}
13848 	lfa_sts = REG_RD(sc, params->lfa_base +
13849 			 offsetof(struct shmem_lfa,
13850 				  lfa_sts));
13851 
13852 	dont_clear_stat = lfa_sts & SHMEM_LFA_DONT_CLEAR_STAT;
13853 
13854 	/* Re-enable the NIG/MAC */
13855 	if (CHIP_IS_E3(sc)) {
13856 		if (!dont_clear_stat) {
13857 			REG_WR(sc, GRCBASE_MISC +
13858 			       MISC_REGISTERS_RESET_REG_2_CLEAR,
13859 			       (MISC_REGISTERS_RESET_REG_2_MSTAT0 <<
13860 				params->port));
13861 			REG_WR(sc, GRCBASE_MISC +
13862 			       MISC_REGISTERS_RESET_REG_2_SET,
13863 			       (MISC_REGISTERS_RESET_REG_2_MSTAT0 <<
13864 				params->port));
13865 		}
13866 		if (vars->line_speed < ELINK_SPEED_10000)
13867 			elink_umac_enable(params, vars, 0);
13868 		else
13869 			elink_xmac_enable(params, vars, 0);
13870 	} else {
13871 		if (vars->line_speed < ELINK_SPEED_10000)
13872 			elink_emac_enable(params, vars, 0);
13873 		else
13874 			elink_bmac_enable(params, vars, 0, !dont_clear_stat);
13875 	}
13876 
13877 	/* Increment LFA count */
13878 	lfa_sts = ((lfa_sts & ~LINK_FLAP_AVOIDANCE_COUNT_MASK) |
13879 		   (((((lfa_sts & LINK_FLAP_AVOIDANCE_COUNT_MASK) >>
13880 		       LINK_FLAP_AVOIDANCE_COUNT_OFFSET) + 1) & 0xff)
13881 		    << LINK_FLAP_AVOIDANCE_COUNT_OFFSET));
13882 	/* Clear link flap reason */
13883 	lfa_sts &= ~LFA_LINK_FLAP_REASON_MASK;
13884 
13885 	REG_WR(sc, params->lfa_base +
13886 	       offsetof(struct shmem_lfa, lfa_sts), lfa_sts);
13887 
13888 	/* Disable NIG DRAIN */
13889 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13890 
13891 	/* Enable interrupts */
13892 	elink_link_int_enable(params);
13893 	return ELINK_STATUS_OK;
13894 }
13895 
13896 static void elink_cannot_avoid_link_flap(struct elink_params *params,
13897 					 struct elink_vars *vars,
13898 					 int lfa_status)
13899 {
13900 	uint32_t lfa_sts, cfg_idx, tmp_val;
13901 	struct bxe_softc *sc = params->sc;
13902 
13903 	elink_link_reset(params, vars, 1);
13904 
13905 	if (!params->lfa_base)
13906 		return;
13907 	/* Store the new link parameters */
13908 	REG_WR(sc, params->lfa_base +
13909 	       offsetof(struct shmem_lfa, req_duplex),
13910 	       params->req_duplex[0] | (params->req_duplex[1] << 16));
13911 
13912 	REG_WR(sc, params->lfa_base +
13913 	       offsetof(struct shmem_lfa, req_flow_ctrl),
13914 	       params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16));
13915 
13916 	REG_WR(sc, params->lfa_base +
13917 	       offsetof(struct shmem_lfa, req_line_speed),
13918 	       params->req_line_speed[0] | (params->req_line_speed[1] << 16));
13919 
13920 	for (cfg_idx = 0; cfg_idx < SHMEM_LINK_CONFIG_SIZE; cfg_idx++) {
13921 		REG_WR(sc, params->lfa_base +
13922 		       offsetof(struct shmem_lfa,
13923 				speed_cap_mask[cfg_idx]),
13924 		       params->speed_cap_mask[cfg_idx]);
13925 	}
13926 
13927 	tmp_val = REG_RD(sc, params->lfa_base +
13928 			 offsetof(struct shmem_lfa, additional_config));
13929 	tmp_val &= ~REQ_FC_AUTO_ADV_MASK;
13930 	tmp_val |= params->req_fc_auto_adv;
13931 
13932 	REG_WR(sc, params->lfa_base +
13933 	       offsetof(struct shmem_lfa, additional_config), tmp_val);
13934 
13935 	lfa_sts = REG_RD(sc, params->lfa_base +
13936 			 offsetof(struct shmem_lfa, lfa_sts));
13937 
13938 	/* Clear the "Don't Clear Statistics" bit, and set reason */
13939 	lfa_sts &= ~SHMEM_LFA_DONT_CLEAR_STAT;
13940 
13941 	/* Set link flap reason */
13942 	lfa_sts &= ~LFA_LINK_FLAP_REASON_MASK;
13943 	lfa_sts |= ((lfa_status & LFA_LINK_FLAP_REASON_MASK) <<
13944 		    LFA_LINK_FLAP_REASON_OFFSET);
13945 
13946 	/* Increment link flap counter */
13947 	lfa_sts = ((lfa_sts & ~LINK_FLAP_COUNT_MASK) |
13948 		   (((((lfa_sts & LINK_FLAP_COUNT_MASK) >>
13949 		       LINK_FLAP_COUNT_OFFSET) + 1) & 0xff)
13950 		    << LINK_FLAP_COUNT_OFFSET));
13951 	REG_WR(sc, params->lfa_base +
13952 	       offsetof(struct shmem_lfa, lfa_sts), lfa_sts);
13953 	/* Proceed with regular link initialization */
13954 }
13955 
13956 elink_status_t elink_phy_init(struct elink_params *params, struct elink_vars *vars)
13957 {
13958 	int lfa_status;
13959 	struct bxe_softc *sc = params->sc;
13960 	ELINK_DEBUG_P0(sc, "Phy Initialization started\n");
13961 	ELINK_DEBUG_P2(sc, "(1) req_speed %d, req_flowctrl %d\n",
13962 		   params->req_line_speed[0], params->req_flow_ctrl[0]);
13963 	ELINK_DEBUG_P2(sc, "(2) req_speed %d, req_flowctrl %d\n",
13964 		   params->req_line_speed[1], params->req_flow_ctrl[1]);
13965 	ELINK_DEBUG_P1(sc, "req_adv_flow_ctrl 0x%x\n", params->req_fc_auto_adv);
13966 	vars->link_status = 0;
13967 	vars->phy_link_up = 0;
13968 	vars->link_up = 0;
13969 	vars->line_speed = 0;
13970 	vars->duplex = DUPLEX_FULL;
13971 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13972 	vars->mac_type = ELINK_MAC_TYPE_NONE;
13973 	vars->phy_flags = 0;
13974 	vars->check_kr2_recovery_cnt = 0;
13975 	params->link_flags = ELINK_PHY_INITIALIZED;
13976 	/* Driver opens NIG-BRB filters */
13977 	elink_set_rx_filter(params, 1);
13978 	elink_chng_link_count(params, 1);
13979 	/* Check if link flap can be avoided */
13980 	lfa_status = elink_check_lfa(params);
13981 
13982 	ELINK_DEBUG_P3(sc, " params : port = %x, loopback_mode = %x req_duplex = %x\n",
13983                         params->port, params->loopback_mode, params->req_duplex[0]);
13984         ELINK_DEBUG_P3(sc, " params : switch_cfg = %x, lane_config = %x req_duplex[1] = %x\n",
13985                         params->switch_cfg, params->lane_config, params->req_duplex[1]);
13986         ELINK_DEBUG_P3(sc, " params : chip_id = %x, feature_config_flags = %x, num_phys = %x\n",
13987                        params->chip_id, params->feature_config_flags, params->num_phys);
13988         ELINK_DEBUG_P3(sc, " params : rsrv = %x, eee_mode = %x, hw_led_mode = x\n",
13989                         params->rsrv, params->eee_mode, params->hw_led_mode);
13990         ELINK_DEBUG_P3(sc, " params : multi_phy = %x, req_fc_auto_adv = %x, link_flags = %x\n",
13991                         params->multi_phy_config, params->req_fc_auto_adv, params->link_flags);
13992         ELINK_DEBUG_P2(sc, " params : lfa_base = %x, link_attr = %x\n",
13993                         params->lfa_base, params->link_attr_sync);
13994 	if (lfa_status == 0) {
13995 		ELINK_DEBUG_P0(sc, "Link Flap Avoidance in progress\n");
13996 		return elink_avoid_link_flap(params, vars);
13997 	}
13998 
13999 	ELINK_DEBUG_P1(sc, "Cannot avoid link flap lfa_sta=0x%x\n",
14000 		       lfa_status);
14001 	elink_cannot_avoid_link_flap(params, vars, lfa_status);
14002 
14003 	/* Disable attentions */
14004 	elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
14005 		       (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14006 			ELINK_NIG_MASK_XGXS0_LINK10G |
14007 			ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14008 			ELINK_NIG_MASK_MI_INT));
14009 #ifdef ELINK_INCLUDE_EMUL
14010 	if (!(params->feature_config_flags &
14011 	      ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC))
14012 #endif
14013 
14014 	elink_emac_init(params, vars);
14015 
14016 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
14017 		vars->link_status |= LINK_STATUS_PFC_ENABLED;
14018 
14019 	if ((params->num_phys == 0) &&
14020 	    !CHIP_REV_IS_SLOW(sc)) {
14021 		ELINK_DEBUG_P0(sc, "No phy found for initialization !!\n");
14022 		return ELINK_STATUS_ERROR;
14023 	}
14024 	set_phy_vars(params, vars);
14025 
14026 	ELINK_DEBUG_P1(sc, "Num of phys on board: %d\n", params->num_phys);
14027 #ifdef ELINK_INCLUDE_FPGA
14028 	if (CHIP_REV_IS_FPGA(sc)) {
14029 		return elink_init_fpga(params, vars);
14030 	} else
14031 #endif
14032 #ifdef ELINK_INCLUDE_EMUL
14033 	if (CHIP_REV_IS_EMUL(sc)) {
14034 		return elink_init_emul(params, vars);
14035 	} else
14036 #endif
14037 	switch (params->loopback_mode) {
14038 	case ELINK_LOOPBACK_BMAC:
14039 		elink_init_bmac_loopback(params, vars);
14040 		break;
14041 	case ELINK_LOOPBACK_EMAC:
14042 		elink_init_emac_loopback(params, vars);
14043 		break;
14044 	case ELINK_LOOPBACK_XMAC:
14045 		elink_init_xmac_loopback(params, vars);
14046 		break;
14047 	case ELINK_LOOPBACK_UMAC:
14048 		elink_init_umac_loopback(params, vars);
14049 		break;
14050 	case ELINK_LOOPBACK_XGXS:
14051 	case ELINK_LOOPBACK_EXT_PHY:
14052 		elink_init_xgxs_loopback(params, vars);
14053 		break;
14054 	default:
14055 		if (!CHIP_IS_E3(sc)) {
14056 			if (params->switch_cfg == ELINK_SWITCH_CFG_10G)
14057 				elink_xgxs_deassert(params);
14058 			else
14059 				elink_serdes_deassert(sc, params->port);
14060 		}
14061 		elink_link_initialize(params, vars);
14062 		DELAY(1000 * 30);
14063 		elink_link_int_enable(params);
14064 		break;
14065 	}
14066 	elink_update_mng(params, vars->link_status);
14067 
14068 	elink_update_mng_eee(params, vars->eee_status);
14069 	return ELINK_STATUS_OK;
14070 }
14071 
14072 elink_status_t elink_link_reset(struct elink_params *params, struct elink_vars *vars,
14073 		     uint8_t reset_ext_phy)
14074 {
14075 	struct bxe_softc *sc = params->sc;
14076 	uint8_t phy_index, port = params->port, clear_latch_ind = 0;
14077 	ELINK_DEBUG_P1(sc, "Resetting the link of port %d\n", port);
14078 	/* Disable attentions */
14079 	vars->link_status = 0;
14080 	elink_chng_link_count(params, 1);
14081 	elink_update_mng(params, vars->link_status);
14082 	vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
14083 			      SHMEM_EEE_ACTIVE_BIT);
14084 	elink_update_mng_eee(params, vars->eee_status);
14085 	elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
14086 		       (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14087 			ELINK_NIG_MASK_XGXS0_LINK10G |
14088 			ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14089 			ELINK_NIG_MASK_MI_INT));
14090 
14091 	/* Activate nig drain */
14092 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
14093 
14094 	/* Disable nig egress interface */
14095 	if (!CHIP_IS_E3(sc)) {
14096 		REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port*4, 0);
14097 		REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
14098 	}
14099 
14100 #ifdef ELINK_INCLUDE_EMUL
14101 	/* Stop BigMac rx */
14102 	if (!(params->feature_config_flags &
14103 	      ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC))
14104 #endif
14105 		if (!CHIP_IS_E3(sc))
14106 			elink_set_bmac_rx(sc, params->chip_id, port, 0);
14107 #ifdef ELINK_INCLUDE_EMUL
14108 	/* Stop XMAC/UMAC rx */
14109 	if (!(params->feature_config_flags &
14110 	      ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC))
14111 #endif
14112 		if (CHIP_IS_E3(sc) &&
14113 		!CHIP_REV_IS_FPGA(sc)) {
14114 			elink_set_xmac_rxtx(params, 0);
14115 			elink_set_umac_rxtx(params, 0);
14116 		}
14117 	/* Disable emac */
14118 	if (!CHIP_IS_E3(sc))
14119 		REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port*4, 0);
14120 
14121 	DELAY(1000 * 10);
14122 	/* The PHY reset is controlled by GPIO 1
14123 	 * Hold it as vars low
14124 	 */
14125 	 /* Clear link led */
14126 	elink_set_mdio_emac_per_phy(sc, params);
14127 	elink_set_led(params, vars, ELINK_LED_MODE_OFF, 0);
14128 
14129 	if (reset_ext_phy && (!CHIP_REV_IS_SLOW(sc))) {
14130 		for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
14131 		      phy_index++) {
14132 			if (params->phy[phy_index].link_reset) {
14133 				elink_set_aer_mmd(params,
14134 						  &params->phy[phy_index]);
14135 				params->phy[phy_index].link_reset(
14136 					&params->phy[phy_index],
14137 					params);
14138 			}
14139 			if (params->phy[phy_index].flags &
14140 			    ELINK_FLAGS_REARM_LATCH_SIGNAL)
14141 				clear_latch_ind = 1;
14142 		}
14143 	}
14144 
14145 	if (clear_latch_ind) {
14146 		/* Clear latching indication */
14147 		elink_rearm_latch_signal(sc, port, 0);
14148 		elink_bits_dis(sc, NIG_REG_LATCH_BC_0 + port*4,
14149 			       1 << ELINK_NIG_LATCH_BC_ENABLE_MI_INT);
14150 	}
14151 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
14152 	if (!CHIP_REV_IS_SLOW(sc))
14153 #endif
14154 	if (params->phy[ELINK_INT_PHY].link_reset)
14155 		params->phy[ELINK_INT_PHY].link_reset(
14156 			&params->phy[ELINK_INT_PHY], params);
14157 
14158 	/* Disable nig ingress interface */
14159 	if (!CHIP_IS_E3(sc)) {
14160 		/* Reset BigMac */
14161 		REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
14162 		       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
14163 		REG_WR(sc, NIG_REG_BMAC0_IN_EN + port*4, 0);
14164 		REG_WR(sc, NIG_REG_EMAC0_IN_EN + port*4, 0);
14165 	} else {
14166 		uint32_t xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
14167 		elink_set_xumac_nig(params, 0, 0);
14168 		if (REG_RD(sc, MISC_REG_RESET_REG_2) &
14169 		    MISC_REGISTERS_RESET_REG_2_XMAC)
14170 			REG_WR(sc, xmac_base + XMAC_REG_CTRL,
14171 			       XMAC_CTRL_REG_SOFT_RESET);
14172 	}
14173 	vars->link_up = 0;
14174 	vars->phy_flags = 0;
14175 	return ELINK_STATUS_OK;
14176 }
14177 elink_status_t elink_lfa_reset(struct elink_params *params,
14178 			       struct elink_vars *vars)
14179 {
14180 	struct bxe_softc *sc = params->sc;
14181 	vars->link_up = 0;
14182 	vars->phy_flags = 0;
14183 	params->link_flags &= ~ELINK_PHY_INITIALIZED;
14184 	if (!params->lfa_base)
14185 		return elink_link_reset(params, vars, 1);
14186 	/*
14187 	 * Activate NIG drain so that during this time the device won't send
14188 	 * anything while it is unable to response.
14189 	 */
14190 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 1);
14191 
14192 	/*
14193 	 * Close gracefully the gate from BMAC to NIG such that no half packets
14194 	 * are passed.
14195 	 */
14196 	if (!CHIP_IS_E3(sc))
14197 		elink_set_bmac_rx(sc, params->chip_id, params->port, 0);
14198 
14199 	if (CHIP_IS_E3(sc)) {
14200 		elink_set_xmac_rxtx(params, 0);
14201 		elink_set_umac_rxtx(params, 0);
14202 	}
14203 	/* Wait 10ms for the pipe to clean up*/
14204 	DELAY(1000 * 10);
14205 
14206 	/* Clean the NIG-BRB using the network filters in a way that will
14207 	 * not cut a packet in the middle.
14208 	 */
14209 	elink_set_rx_filter(params, 0);
14210 
14211 	/*
14212 	 * Re-open the gate between the BMAC and the NIG, after verifying the
14213 	 * gate to the BRB is closed, otherwise packets may arrive to the
14214 	 * firmware before driver had initialized it. The target is to achieve
14215 	 * minimum management protocol down time.
14216 	 */
14217 	if (!CHIP_IS_E3(sc))
14218 		elink_set_bmac_rx(sc, params->chip_id, params->port, 1);
14219 
14220 	if (CHIP_IS_E3(sc)) {
14221 		elink_set_xmac_rxtx(params, 1);
14222 		elink_set_umac_rxtx(params, 1);
14223 	}
14224 	/* Disable NIG drain */
14225 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
14226 	return ELINK_STATUS_OK;
14227 }
14228 
14229 /****************************************************************************/
14230 /*				Common function				    */
14231 /****************************************************************************/
14232 static elink_status_t elink_8073_common_init_phy(struct bxe_softc *sc,
14233 				      uint32_t shmem_base_path[],
14234 				      uint32_t shmem2_base_path[], uint8_t phy_index,
14235 				      uint32_t chip_id)
14236 {
14237 	struct elink_phy phy[PORT_MAX];
14238 	struct elink_phy *phy_blk[PORT_MAX];
14239 	uint16_t val;
14240 	int8_t port = 0;
14241 	int8_t port_of_path = 0;
14242 	uint32_t swap_val, swap_override;
14243 	swap_val = REG_RD(sc,  NIG_REG_PORT_SWAP);
14244 	swap_override = REG_RD(sc,  NIG_REG_STRAP_OVERRIDE);
14245 	port ^= (swap_val && swap_override);
14246 	elink_ext_phy_hw_reset(sc, port);
14247 	/* PART1 - Reset both phys */
14248 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14249 		uint32_t shmem_base, shmem2_base;
14250 		/* In E2, same phy is using for port0 of the two paths */
14251 		if (CHIP_IS_E1x(sc)) {
14252 			shmem_base = shmem_base_path[0];
14253 			shmem2_base = shmem2_base_path[0];
14254 			port_of_path = port;
14255 		} else {
14256 			shmem_base = shmem_base_path[port];
14257 			shmem2_base = shmem2_base_path[port];
14258 			port_of_path = 0;
14259 		}
14260 
14261 		/* Extract the ext phy address for the port */
14262 		if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14263 				       port_of_path, &phy[port]) !=
14264 		    ELINK_STATUS_OK) {
14265 			ELINK_DEBUG_P0(sc, "populate_phy failed\n");
14266 			return ELINK_STATUS_ERROR;
14267 		}
14268 		/* Disable attentions */
14269 		elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
14270 			       port_of_path*4,
14271 			       (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14272 				ELINK_NIG_MASK_XGXS0_LINK10G |
14273 				ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14274 				ELINK_NIG_MASK_MI_INT));
14275 
14276 		/* Need to take the phy out of low power mode in order
14277 		 * to write to access its registers
14278 		 */
14279 		elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
14280 			       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
14281 			       port);
14282 
14283 		/* Reset the phy */
14284 		elink_cl45_write(sc, &phy[port],
14285 				 MDIO_PMA_DEVAD,
14286 				 MDIO_PMA_REG_CTRL,
14287 				 1<<15);
14288 	}
14289 
14290 	/* Add delay of 150ms after reset */
14291 	DELAY(1000 * 150);
14292 
14293 	if (phy[PORT_0].addr & 0x1) {
14294 		phy_blk[PORT_0] = &(phy[PORT_1]);
14295 		phy_blk[PORT_1] = &(phy[PORT_0]);
14296 	} else {
14297 		phy_blk[PORT_0] = &(phy[PORT_0]);
14298 		phy_blk[PORT_1] = &(phy[PORT_1]);
14299 	}
14300 
14301 	/* PART2 - Download firmware to both phys */
14302 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14303 		if (CHIP_IS_E1x(sc))
14304 			port_of_path = port;
14305 		else
14306 			port_of_path = 0;
14307 
14308 		ELINK_DEBUG_P1(sc, "Loading spirom for phy address 0x%x\n",
14309 			   phy_blk[port]->addr);
14310 		if (elink_8073_8727_external_rom_boot(sc, phy_blk[port],
14311 						      port_of_path))
14312 			return ELINK_STATUS_ERROR;
14313 
14314 		/* Only set bit 10 = 1 (Tx power down) */
14315 		elink_cl45_read(sc, phy_blk[port],
14316 				MDIO_PMA_DEVAD,
14317 				MDIO_PMA_REG_TX_POWER_DOWN, &val);
14318 
14319 		/* Phase1 of TX_POWER_DOWN reset */
14320 		elink_cl45_write(sc, phy_blk[port],
14321 				 MDIO_PMA_DEVAD,
14322 				 MDIO_PMA_REG_TX_POWER_DOWN,
14323 				 (val | 1<<10));
14324 	}
14325 
14326 	/* Toggle Transmitter: Power down and then up with 600ms delay
14327 	 * between
14328 	 */
14329 	DELAY(1000 * 600);
14330 
14331 	/* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
14332 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14333 		/* Phase2 of POWER_DOWN_RESET */
14334 		/* Release bit 10 (Release Tx power down) */
14335 		elink_cl45_read(sc, phy_blk[port],
14336 				MDIO_PMA_DEVAD,
14337 				MDIO_PMA_REG_TX_POWER_DOWN, &val);
14338 
14339 		elink_cl45_write(sc, phy_blk[port],
14340 				MDIO_PMA_DEVAD,
14341 				MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
14342 		DELAY(1000 * 15);
14343 
14344 		/* Read modify write the SPI-ROM version select register */
14345 		elink_cl45_read(sc, phy_blk[port],
14346 				MDIO_PMA_DEVAD,
14347 				MDIO_PMA_REG_EDC_FFE_MAIN, &val);
14348 		elink_cl45_write(sc, phy_blk[port],
14349 				 MDIO_PMA_DEVAD,
14350 				 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
14351 
14352 		/* set GPIO2 back to LOW */
14353 		elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
14354 			       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
14355 	}
14356 	return ELINK_STATUS_OK;
14357 }
14358 static elink_status_t elink_8726_common_init_phy(struct bxe_softc *sc,
14359 				      uint32_t shmem_base_path[],
14360 				      uint32_t shmem2_base_path[], uint8_t phy_index,
14361 				      uint32_t chip_id)
14362 {
14363 	uint32_t val;
14364 	int8_t port;
14365 	struct elink_phy phy;
14366 	/* Use port1 because of the static port-swap */
14367 	/* Enable the module detection interrupt */
14368 	val = REG_RD(sc, MISC_REG_GPIO_EVENT_EN);
14369 	val |= ((1<<MISC_REGISTERS_GPIO_3)|
14370 		(1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
14371 	REG_WR(sc, MISC_REG_GPIO_EVENT_EN, val);
14372 
14373 	elink_ext_phy_hw_reset(sc, 0);
14374 	DELAY(1000 * 5);
14375 	for (port = 0; port < PORT_MAX; port++) {
14376 		uint32_t shmem_base, shmem2_base;
14377 
14378 		/* In E2, same phy is using for port0 of the two paths */
14379 		if (CHIP_IS_E1x(sc)) {
14380 			shmem_base = shmem_base_path[0];
14381 			shmem2_base = shmem2_base_path[0];
14382 		} else {
14383 			shmem_base = shmem_base_path[port];
14384 			shmem2_base = shmem2_base_path[port];
14385 		}
14386 		/* Extract the ext phy address for the port */
14387 		if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14388 				       port, &phy) !=
14389 		    ELINK_STATUS_OK) {
14390 			ELINK_DEBUG_P0(sc, "populate phy failed\n");
14391 			return ELINK_STATUS_ERROR;
14392 		}
14393 
14394 		/* Reset phy*/
14395 		elink_cl45_write(sc, &phy,
14396 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
14397 
14398 
14399 		/* Set fault module detected LED on */
14400 		elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_0,
14401 			       MISC_REGISTERS_GPIO_HIGH,
14402 			       port);
14403 	}
14404 
14405 	return ELINK_STATUS_OK;
14406 }
14407 static void elink_get_ext_phy_reset_gpio(struct bxe_softc *sc, uint32_t shmem_base,
14408 					 uint8_t *io_gpio, uint8_t *io_port)
14409 {
14410 
14411 	uint32_t phy_gpio_reset = REG_RD(sc, shmem_base +
14412 					  offsetof(struct shmem_region,
14413 				dev_info.port_hw_config[PORT_0].default_cfg));
14414 	switch (phy_gpio_reset) {
14415 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
14416 		*io_gpio = 0;
14417 		*io_port = 0;
14418 		break;
14419 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
14420 		*io_gpio = 1;
14421 		*io_port = 0;
14422 		break;
14423 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
14424 		*io_gpio = 2;
14425 		*io_port = 0;
14426 		break;
14427 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
14428 		*io_gpio = 3;
14429 		*io_port = 0;
14430 		break;
14431 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
14432 		*io_gpio = 0;
14433 		*io_port = 1;
14434 		break;
14435 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
14436 		*io_gpio = 1;
14437 		*io_port = 1;
14438 		break;
14439 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
14440 		*io_gpio = 2;
14441 		*io_port = 1;
14442 		break;
14443 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
14444 		*io_gpio = 3;
14445 		*io_port = 1;
14446 		break;
14447 	default:
14448 		/* Don't override the io_gpio and io_port */
14449 		break;
14450 	}
14451 }
14452 
14453 static elink_status_t elink_8727_common_init_phy(struct bxe_softc *sc,
14454 				      uint32_t shmem_base_path[],
14455 				      uint32_t shmem2_base_path[], uint8_t phy_index,
14456 				      uint32_t chip_id)
14457 {
14458 	int8_t port, reset_gpio;
14459 	uint32_t swap_val, swap_override;
14460 	struct elink_phy phy[PORT_MAX];
14461 	struct elink_phy *phy_blk[PORT_MAX];
14462 	int8_t port_of_path;
14463 	swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
14464 	swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
14465 
14466 	reset_gpio = MISC_REGISTERS_GPIO_1;
14467 	port = 1;
14468 
14469 	/* Retrieve the reset gpio/port which control the reset.
14470 	 * Default is GPIO1, PORT1
14471 	 */
14472 	elink_get_ext_phy_reset_gpio(sc, shmem_base_path[0],
14473 				     (uint8_t *)&reset_gpio, (uint8_t *)&port);
14474 
14475 	/* Calculate the port based on port swap */
14476 	port ^= (swap_val && swap_override);
14477 
14478 	/* Initiate PHY reset*/
14479 	elink_cb_gpio_write(sc, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
14480 		       port);
14481 	DELAY(1000 * 1);
14482 	elink_cb_gpio_write(sc, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
14483 		       port);
14484 
14485 	DELAY(1000 * 5);
14486 
14487 	/* PART1 - Reset both phys */
14488 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14489 		uint32_t shmem_base, shmem2_base;
14490 
14491 		/* In E2, same phy is using for port0 of the two paths */
14492 		if (CHIP_IS_E1x(sc)) {
14493 			shmem_base = shmem_base_path[0];
14494 			shmem2_base = shmem2_base_path[0];
14495 			port_of_path = port;
14496 		} else {
14497 			shmem_base = shmem_base_path[port];
14498 			shmem2_base = shmem2_base_path[port];
14499 			port_of_path = 0;
14500 		}
14501 
14502 		/* Extract the ext phy address for the port */
14503 		if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14504 				       port_of_path, &phy[port]) !=
14505 				       ELINK_STATUS_OK) {
14506 			ELINK_DEBUG_P0(sc, "populate phy failed\n");
14507 			return ELINK_STATUS_ERROR;
14508 		}
14509 		/* disable attentions */
14510 		elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
14511 			       port_of_path*4,
14512 			       (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14513 				ELINK_NIG_MASK_XGXS0_LINK10G |
14514 				ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14515 				ELINK_NIG_MASK_MI_INT));
14516 
14517 
14518 		/* Reset the phy */
14519 		elink_cl45_write(sc, &phy[port],
14520 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
14521 	}
14522 
14523 	/* Add delay of 150ms after reset */
14524 	DELAY(1000 * 150);
14525 	if (phy[PORT_0].addr & 0x1) {
14526 		phy_blk[PORT_0] = &(phy[PORT_1]);
14527 		phy_blk[PORT_1] = &(phy[PORT_0]);
14528 	} else {
14529 		phy_blk[PORT_0] = &(phy[PORT_0]);
14530 		phy_blk[PORT_1] = &(phy[PORT_1]);
14531 	}
14532 	/* PART2 - Download firmware to both phys */
14533 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14534 		if (CHIP_IS_E1x(sc))
14535 			port_of_path = port;
14536 		else
14537 			port_of_path = 0;
14538 		ELINK_DEBUG_P1(sc, "Loading spirom for phy address 0x%x\n",
14539 			   phy_blk[port]->addr);
14540 		if (elink_8073_8727_external_rom_boot(sc, phy_blk[port],
14541 						      port_of_path))
14542 			return ELINK_STATUS_ERROR;
14543 		/* Disable PHY transmitter output */
14544 		elink_cl45_write(sc, phy_blk[port],
14545 				 MDIO_PMA_DEVAD,
14546 				 MDIO_PMA_REG_TX_DISABLE, 1);
14547 
14548 	}
14549 	return ELINK_STATUS_OK;
14550 }
14551 
14552 static elink_status_t elink_84833_common_init_phy(struct bxe_softc *sc,
14553 						uint32_t shmem_base_path[],
14554 						uint32_t shmem2_base_path[],
14555 						uint8_t phy_index,
14556 						uint32_t chip_id)
14557 {
14558 	uint8_t reset_gpios;
14559 	reset_gpios = elink_84833_get_reset_gpios(sc, shmem_base_path, chip_id);
14560 	elink_cb_gpio_mult_write(sc, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
14561 	DELAY(10);
14562 	elink_cb_gpio_mult_write(sc, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH);
14563 	ELINK_DEBUG_P1(sc, "84833 reset pulse on pin values 0x%x\n",
14564 		reset_gpios);
14565 	return ELINK_STATUS_OK;
14566 }
14567 static elink_status_t elink_ext_phy_common_init(struct bxe_softc *sc, uint32_t shmem_base_path[],
14568 				     uint32_t shmem2_base_path[], uint8_t phy_index,
14569 				     uint32_t ext_phy_type, uint32_t chip_id)
14570 {
14571 	elink_status_t rc = ELINK_STATUS_OK;
14572 
14573 	switch (ext_phy_type) {
14574 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
14575 		rc = elink_8073_common_init_phy(sc, shmem_base_path,
14576 						shmem2_base_path,
14577 						phy_index, chip_id);
14578 		break;
14579 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
14580 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
14581 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
14582 		rc = elink_8727_common_init_phy(sc, shmem_base_path,
14583 						shmem2_base_path,
14584 						phy_index, chip_id);
14585 		break;
14586 
14587 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
14588 		/* GPIO1 affects both ports, so there's need to pull
14589 		 * it for single port alone
14590 		 */
14591 		rc = elink_8726_common_init_phy(sc, shmem_base_path,
14592 						shmem2_base_path,
14593 						phy_index, chip_id);
14594 		break;
14595 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
14596 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834:
14597 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858:
14598 		/* GPIO3's are linked, and so both need to be toggled
14599 		 * to obtain required 2us pulse.
14600 		 */
14601 		rc = elink_84833_common_init_phy(sc, shmem_base_path,
14602 						shmem2_base_path,
14603 						phy_index, chip_id);
14604 		break;
14605 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
14606 		rc = ELINK_STATUS_ERROR;
14607 		break;
14608 	default:
14609 		ELINK_DEBUG_P1(sc,
14610 			   "ext_phy 0x%x common init not required\n",
14611 			   ext_phy_type);
14612 		break;
14613 	}
14614 
14615 	if (rc != ELINK_STATUS_OK)
14616 		elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED, 0); // "Warning: PHY was not initialized,"
14617 				     // " Port %d\n",
14618 
14619 	return rc;
14620 }
14621 
14622 elink_status_t elink_common_init_phy(struct bxe_softc *sc, uint32_t shmem_base_path[],
14623 			  uint32_t shmem2_base_path[], uint32_t chip_id,
14624 			  uint8_t one_port_enabled)
14625 {
14626 	elink_status_t rc = ELINK_STATUS_OK;
14627 	uint32_t phy_ver, val;
14628 	uint8_t phy_index = 0;
14629 	uint32_t ext_phy_type, ext_phy_config;
14630 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
14631 	if (CHIP_REV_IS_EMUL(sc) || CHIP_REV_IS_FPGA(sc))
14632 		return ELINK_STATUS_OK;
14633 #endif
14634 
14635 	elink_set_mdio_clk(sc, chip_id, GRCBASE_EMAC0);
14636 	elink_set_mdio_clk(sc, chip_id, GRCBASE_EMAC1);
14637 	ELINK_DEBUG_P0(sc, "Begin common phy init\n");
14638 	if (CHIP_IS_E3(sc)) {
14639 		/* Enable EPIO */
14640 		val = REG_RD(sc, MISC_REG_GEN_PURP_HWG);
14641 		REG_WR(sc, MISC_REG_GEN_PURP_HWG, val | 1);
14642 	}
14643 	/* Check if common init was already done */
14644 	phy_ver = REG_RD(sc, shmem_base_path[0] +
14645 			 offsetof(struct shmem_region,
14646 				  port_mb[PORT_0].ext_phy_fw_version));
14647 	if (phy_ver) {
14648 		ELINK_DEBUG_P1(sc, "Not doing common init; phy ver is 0x%x\n",
14649 			       phy_ver);
14650 		return ELINK_STATUS_OK;
14651 	}
14652 
14653 	/* Read the ext_phy_type for arbitrary port(0) */
14654 	for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
14655 	      phy_index++) {
14656 		ext_phy_config = elink_get_ext_phy_config(sc,
14657 							  shmem_base_path[0],
14658 							  phy_index, 0);
14659 		ext_phy_type = ELINK_XGXS_EXT_PHY_TYPE(ext_phy_config);
14660 		rc |= elink_ext_phy_common_init(sc, shmem_base_path,
14661 						shmem2_base_path,
14662 						phy_index, ext_phy_type,
14663 						chip_id);
14664 	}
14665 	return rc;
14666 }
14667 
14668 static void elink_check_over_curr(struct elink_params *params,
14669 				  struct elink_vars *vars)
14670 {
14671 	struct bxe_softc *sc = params->sc;
14672 	uint32_t cfg_pin;
14673 	uint8_t port = params->port;
14674 	uint32_t pin_val;
14675 
14676 	cfg_pin = (REG_RD(sc, params->shmem_base +
14677 			  offsetof(struct shmem_region,
14678 			       dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) &
14679 		   PORT_HW_CFG_E3_OVER_CURRENT_MASK) >>
14680 		PORT_HW_CFG_E3_OVER_CURRENT_SHIFT;
14681 
14682 	/* Ignore check if no external input PIN available */
14683 	if (elink_get_cfg_pin(sc, cfg_pin, &pin_val) != ELINK_STATUS_OK)
14684 		return;
14685 
14686 	if (!pin_val) {
14687 		if ((vars->phy_flags & PHY_OVER_CURRENT_FLAG) == 0) {
14688 			elink_cb_event_log(sc, ELINK_LOG_ID_OVER_CURRENT, params->port); //"Error:  Power fault on Port %d has"
14689 					  //  " been detected and the power to "
14690 					  //  "that SFP+ module has been removed"
14691 					  //  " to prevent failure of the card."
14692 					  //  " Please remove the SFP+ module and"
14693 					  //  " restart the system to clear this"
14694 					  //  " error.\n",
14695 			vars->phy_flags |= PHY_OVER_CURRENT_FLAG;
14696 			elink_warpcore_power_module(params, 0);
14697 		}
14698 	} else
14699 		vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG;
14700 }
14701 
14702 /* Returns 0 if no change occurred since last check; 1 otherwise. */
14703 static uint8_t elink_analyze_link_error(struct elink_params *params,
14704 				    struct elink_vars *vars, uint32_t status,
14705 				    uint32_t phy_flag, uint32_t link_flag, uint8_t notify)
14706 {
14707 	struct bxe_softc *sc = params->sc;
14708 	/* Compare new value with previous value */
14709 	uint8_t led_mode;
14710 	uint32_t old_status = (vars->phy_flags & phy_flag) ? 1 : 0;
14711 
14712 	if ((status ^ old_status) == 0)
14713 		return 0;
14714 
14715 	/* If values differ */
14716 	switch (phy_flag) {
14717 	case PHY_HALF_OPEN_CONN_FLAG:
14718 		ELINK_DEBUG_P0(sc, "Analyze Remote Fault\n");
14719 		break;
14720 	case PHY_SFP_TX_FAULT_FLAG:
14721 		ELINK_DEBUG_P0(sc, "Analyze TX Fault\n");
14722 		break;
14723 	default:
14724 		ELINK_DEBUG_P0(sc, "Analyze UNKNOWN\n");
14725 	}
14726 	ELINK_DEBUG_P3(sc, "Link changed:[%x %x]->%x\n", vars->link_up,
14727 	   old_status, status);
14728 
14729 	/* Do not touch the link in case physical link down */
14730 	if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0)
14731 		return 1;
14732 
14733 	/* a. Update shmem->link_status accordingly
14734 	 * b. Update elink_vars->link_up
14735 	 */
14736 	if (status) {
14737 		vars->link_status &= ~LINK_STATUS_LINK_UP;
14738 		vars->link_status |= link_flag;
14739 		vars->link_up = 0;
14740 		vars->phy_flags |= phy_flag;
14741 
14742 		/* activate nig drain */
14743 		REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 1);
14744 		/* Set LED mode to off since the PHY doesn't know about these
14745 		 * errors
14746 		 */
14747 		led_mode = ELINK_LED_MODE_OFF;
14748 	} else {
14749 		vars->link_status |= LINK_STATUS_LINK_UP;
14750 		vars->link_status &= ~link_flag;
14751 		vars->link_up = 1;
14752 		vars->phy_flags &= ~phy_flag;
14753 		led_mode = ELINK_LED_MODE_OPER;
14754 
14755 		/* Clear nig drain */
14756 		REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
14757 	}
14758 	elink_sync_link(params, vars);
14759 	/* Update the LED according to the link state */
14760 	elink_set_led(params, vars, led_mode, ELINK_SPEED_10000);
14761 
14762 	/* Update link status in the shared memory */
14763 	elink_update_mng(params, vars->link_status);
14764 
14765 	/* C. Trigger General Attention */
14766 	vars->periodic_flags |= ELINK_PERIODIC_FLAGS_LINK_EVENT;
14767 	if (notify)
14768 		elink_cb_notify_link_changed(sc);
14769 
14770 	return 1;
14771 }
14772 
14773 /******************************************************************************
14774 * Description:
14775 *	This function checks for half opened connection change indication.
14776 *	When such change occurs, it calls the elink_analyze_link_error
14777 *	to check if Remote Fault is set or cleared. Reception of remote fault
14778 *	status message in the MAC indicates that the peer's MAC has detected
14779 *	a fault, for example, due to break in the TX side of fiber.
14780 *
14781 ******************************************************************************/
14782 static
14783 elink_status_t elink_check_half_open_conn(struct elink_params *params,
14784 				struct elink_vars *vars,
14785 				uint8_t notify)
14786 {
14787 	struct bxe_softc *sc = params->sc;
14788 	uint32_t lss_status = 0;
14789 	uint32_t mac_base;
14790 	/* In case link status is physically up @ 10G do */
14791 	if (((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0) ||
14792 	    (REG_RD(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port*4)))
14793 		return ELINK_STATUS_OK;
14794 
14795 	if (CHIP_IS_E3(sc) &&
14796 	    (REG_RD(sc, MISC_REG_RESET_REG_2) &
14797 	      (MISC_REGISTERS_RESET_REG_2_XMAC))) {
14798 		/* Check E3 XMAC */
14799 		/* Note that link speed cannot be queried here, since it may be
14800 		 * zero while link is down. In case UMAC is active, LSS will
14801 		 * simply not be set
14802 		 */
14803 		mac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
14804 
14805 		/* Clear stick bits (Requires rising edge) */
14806 		REG_WR(sc, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
14807 		REG_WR(sc, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
14808 		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
14809 		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
14810 		if (REG_RD(sc, mac_base + XMAC_REG_RX_LSS_STATUS))
14811 			lss_status = 1;
14812 
14813 		elink_analyze_link_error(params, vars, lss_status,
14814 					 PHY_HALF_OPEN_CONN_FLAG,
14815 					 LINK_STATUS_NONE, notify);
14816 	} else if (REG_RD(sc, MISC_REG_RESET_REG_2) &
14817 		   (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) {
14818 		/* Check E1X / E2 BMAC */
14819 		uint32_t lss_status_reg;
14820 		uint32_t wb_data[2];
14821 		mac_base = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
14822 			NIG_REG_INGRESS_BMAC0_MEM;
14823 		/*  Read BIGMAC_REGISTER_RX_LSS_STATUS */
14824 		if (CHIP_IS_E2(sc))
14825 			lss_status_reg = BIGMAC2_REGISTER_RX_LSS_STAT;
14826 		else
14827 			lss_status_reg = BIGMAC_REGISTER_RX_LSS_STATUS;
14828 
14829 		REG_RD_DMAE(sc, mac_base + lss_status_reg, wb_data, 2);
14830 		lss_status = (wb_data[0] > 0);
14831 
14832 		elink_analyze_link_error(params, vars, lss_status,
14833 					 PHY_HALF_OPEN_CONN_FLAG,
14834 					 LINK_STATUS_NONE, notify);
14835 	}
14836 	return ELINK_STATUS_OK;
14837 }
14838 static void elink_sfp_tx_fault_detection(struct elink_phy *phy,
14839 					 struct elink_params *params,
14840 					 struct elink_vars *vars)
14841 {
14842 	struct bxe_softc *sc = params->sc;
14843 	uint32_t cfg_pin, value = 0;
14844 	uint8_t led_change, port = params->port;
14845 
14846 	/* Get The SFP+ TX_Fault controlling pin ([eg]pio) */
14847 	cfg_pin = (REG_RD(sc, params->shmem_base + offsetof(struct shmem_region,
14848 			  dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
14849 		   PORT_HW_CFG_E3_TX_FAULT_MASK) >>
14850 		  PORT_HW_CFG_E3_TX_FAULT_SHIFT;
14851 
14852 	if (elink_get_cfg_pin(sc, cfg_pin, &value)) {
14853 		ELINK_DEBUG_P1(sc, "Failed to read pin 0x%02x\n", cfg_pin);
14854 		return;
14855 	}
14856 
14857 	led_change = elink_analyze_link_error(params, vars, value,
14858 					      PHY_SFP_TX_FAULT_FLAG,
14859 					      LINK_STATUS_SFP_TX_FAULT, 1);
14860 
14861 	if (led_change) {
14862 		/* Change TX_Fault led, set link status for further syncs */
14863 		uint8_t led_mode;
14864 
14865 		if (vars->phy_flags & PHY_SFP_TX_FAULT_FLAG) {
14866 			led_mode = MISC_REGISTERS_GPIO_HIGH;
14867 			vars->link_status |= LINK_STATUS_SFP_TX_FAULT;
14868 		} else {
14869 			led_mode = MISC_REGISTERS_GPIO_LOW;
14870 			vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT;
14871 		}
14872 
14873 		/* If module is unapproved, led should be on regardless */
14874 		if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED)) {
14875 			ELINK_DEBUG_P1(sc, "Change TX_Fault LED: ->%x\n",
14876 			   led_mode);
14877 			elink_set_e3_module_fault_led(params, led_mode);
14878 		}
14879 	}
14880 }
14881 static void elink_kr2_recovery(struct elink_params *params,
14882 			       struct elink_vars *vars,
14883 			       struct elink_phy *phy)
14884 {
14885 	struct bxe_softc *sc = params->sc;
14886 	ELINK_DEBUG_P0(sc, "KR2 recovery\n");
14887 	elink_warpcore_enable_AN_KR2(phy, params, vars);
14888 	elink_warpcore_restart_AN_KR(phy, params);
14889 }
14890 
14891 static void elink_check_kr2_wa(struct elink_params *params,
14892 			       struct elink_vars *vars,
14893 			       struct elink_phy *phy)
14894 {
14895 	struct bxe_softc *sc = params->sc;
14896 	uint16_t base_page, next_page, not_kr2_device, lane;
14897 	int sigdet;
14898 
14899 	/* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery
14900 	 * Since some switches tend to reinit the AN process and clear the
14901 	 * the advertised BP/NP after ~2 seconds causing the KR2 to be disabled
14902 	 * and recovered many times
14903 	 */
14904 	if (vars->check_kr2_recovery_cnt > 0) {
14905 		vars->check_kr2_recovery_cnt--;
14906 		return;
14907 	}
14908 
14909 	sigdet = elink_warpcore_get_sigdet(phy, params);
14910 	if (!sigdet) {
14911 		if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
14912 			elink_kr2_recovery(params, vars, phy);
14913 			ELINK_DEBUG_P0(sc, "No sigdet\n");
14914 		}
14915 		return;
14916 	}
14917 
14918 	lane = elink_get_warpcore_lane(phy, params);
14919 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
14920 			  MDIO_AER_BLOCK_AER_REG, lane);
14921 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
14922 			MDIO_AN_REG_LP_AUTO_NEG, &base_page);
14923 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
14924 			MDIO_AN_REG_LP_AUTO_NEG2, &next_page);
14925 	elink_set_aer_mmd(params, phy);
14926 
14927 	/* CL73 has not begun yet */
14928 	if (base_page == 0) {
14929 		if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
14930 			elink_kr2_recovery(params, vars, phy);
14931 			ELINK_DEBUG_P0(sc, "No BP\n");
14932 		}
14933 		return;
14934 	}
14935 
14936 	/* In case NP bit is not set in the BasePage, or it is set,
14937 	 * but only KX is advertised, declare this link partner as non-KR2
14938 	 * device.
14939 	 */
14940 	not_kr2_device = (((base_page & 0x8000) == 0) ||
14941 			  (((base_page & 0x8000) &&
14942 			    ((next_page & 0xe0) == 0x20))));
14943 
14944 	/* In case KR2 is already disabled, check if we need to re-enable it */
14945 	if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
14946 		if (!not_kr2_device) {
14947 			ELINK_DEBUG_P2(sc, "BP=0x%x, NP=0x%x\n", base_page,
14948 			   next_page);
14949 			elink_kr2_recovery(params, vars, phy);
14950 		}
14951 		return;
14952 	}
14953 	/* KR2 is enabled, but not KR2 device */
14954 	if (not_kr2_device) {
14955 		/* Disable KR2 on both lanes */
14956 		ELINK_DEBUG_P2(sc, "BP=0x%x, NP=0x%x\n", base_page, next_page);
14957 		elink_disable_kr2(params, vars, phy);
14958 		/* Restart AN on leading lane */
14959 		elink_warpcore_restart_AN_KR(phy, params);
14960 		return;
14961 	}
14962 }
14963 
14964 void elink_period_func(struct elink_params *params, struct elink_vars *vars)
14965 {
14966 	uint16_t phy_idx;
14967 	struct bxe_softc *sc = params->sc;
14968 	for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
14969 		if (params->phy[phy_idx].flags & ELINK_FLAGS_TX_ERROR_CHECK) {
14970 			elink_set_aer_mmd(params, &params->phy[phy_idx]);
14971 			if (elink_check_half_open_conn(params, vars, 1) !=
14972 			    ELINK_STATUS_OK)
14973 				ELINK_DEBUG_P0(sc, "Fault detection failed\n");
14974 			break;
14975 		}
14976 	}
14977 
14978 	if (CHIP_IS_E3(sc)) {
14979 		struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
14980 		elink_set_aer_mmd(params, phy);
14981 		if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
14982 		     (phy->speed_cap_mask &
14983 		      PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) ||
14984 		    (phy->req_line_speed == ELINK_SPEED_20000))
14985 			elink_check_kr2_wa(params, vars, phy);
14986 		elink_check_over_curr(params, vars);
14987 		if (vars->rx_tx_asic_rst)
14988 			elink_warpcore_config_runtime(phy, params, vars);
14989 
14990 		if ((REG_RD(sc, params->shmem_base +
14991 			    offsetof(struct shmem_region, dev_info.
14992 				port_hw_config[params->port].default_cfg))
14993 		    & PORT_HW_CFG_NET_SERDES_IF_MASK) ==
14994 		    PORT_HW_CFG_NET_SERDES_IF_SFI) {
14995 			if (elink_is_sfp_module_plugged(phy, params)) {
14996 				elink_sfp_tx_fault_detection(phy, params, vars);
14997 			} else if (vars->link_status &
14998 				LINK_STATUS_SFP_TX_FAULT) {
14999 				/* Clean trail, interrupt corrects the leds */
15000 				vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT;
15001 				vars->phy_flags &= ~PHY_SFP_TX_FAULT_FLAG;
15002 				/* Update link status in the shared memory */
15003 				elink_update_mng(params, vars->link_status);
15004 			}
15005 		}
15006 	}
15007 }
15008 
15009 uint8_t elink_fan_failure_det_req(struct bxe_softc *sc,
15010 			     uint32_t shmem_base,
15011 			     uint32_t shmem2_base,
15012 			     uint8_t port)
15013 {
15014 	uint8_t phy_index, fan_failure_det_req = 0;
15015 	struct elink_phy phy;
15016 	for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
15017 	      phy_index++) {
15018 		if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
15019 				       port, &phy)
15020 		    != ELINK_STATUS_OK) {
15021 			ELINK_DEBUG_P0(sc, "populate phy failed\n");
15022 			return 0;
15023 		}
15024 		fan_failure_det_req |= (phy.flags &
15025 					ELINK_FLAGS_FAN_FAILURE_DET_REQ);
15026 	}
15027 	return fan_failure_det_req;
15028 }
15029 
15030 void elink_hw_reset_phy(struct elink_params *params)
15031 {
15032 	uint8_t phy_index;
15033 	struct bxe_softc *sc = params->sc;
15034 	elink_update_mng(params, 0);
15035 	elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
15036 		       (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
15037 			ELINK_NIG_MASK_XGXS0_LINK10G |
15038 			ELINK_NIG_MASK_SERDES0_LINK_STATUS |
15039 			ELINK_NIG_MASK_MI_INT));
15040 
15041 	for (phy_index = ELINK_INT_PHY; phy_index < ELINK_MAX_PHYS;
15042 	      phy_index++) {
15043 		if (params->phy[phy_index].hw_reset) {
15044 			params->phy[phy_index].hw_reset(
15045 				&params->phy[phy_index],
15046 				params);
15047 			params->phy[phy_index] = phy_null;
15048 		}
15049 	}
15050 }
15051 
15052 void elink_init_mod_abs_int(struct bxe_softc *sc, struct elink_vars *vars,
15053 			    uint32_t chip_id, uint32_t shmem_base, uint32_t shmem2_base,
15054 			    uint8_t port)
15055 {
15056 	uint8_t gpio_num = 0xff, gpio_port = 0xff, phy_index;
15057 	uint32_t val;
15058 	uint32_t offset, aeu_mask, swap_val, swap_override, sync_offset;
15059 	if (CHIP_IS_E3(sc)) {
15060 		if (elink_get_mod_abs_int_cfg(sc, chip_id,
15061 					      shmem_base,
15062 					      port,
15063 					      &gpio_num,
15064 					      &gpio_port) != ELINK_STATUS_OK)
15065 			return;
15066 	} else {
15067 		struct elink_phy phy;
15068 		for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
15069 		      phy_index++) {
15070 			if (elink_populate_phy(sc, phy_index, shmem_base,
15071 					       shmem2_base, port, &phy)
15072 			    != ELINK_STATUS_OK) {
15073 				ELINK_DEBUG_P0(sc, "populate phy failed\n");
15074 				return;
15075 			}
15076 			if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
15077 				gpio_num = MISC_REGISTERS_GPIO_3;
15078 				gpio_port = port;
15079 				break;
15080 			}
15081 		}
15082 	}
15083 
15084 	if (gpio_num == 0xff)
15085 		return;
15086 
15087 	/* Set GPIO3 to trigger SFP+ module insertion/removal */
15088 	elink_cb_gpio_write(sc, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z, gpio_port);
15089 
15090 	swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
15091 	swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
15092 	gpio_port ^= (swap_val && swap_override);
15093 
15094 	vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 <<
15095 		(gpio_num + (gpio_port << 2));
15096 
15097 	sync_offset = shmem_base +
15098 		offsetof(struct shmem_region,
15099 			 dev_info.port_hw_config[port].aeu_int_mask);
15100 	REG_WR(sc, sync_offset, vars->aeu_int_mask);
15101 
15102 	ELINK_DEBUG_P3(sc, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n",
15103 		       gpio_num, gpio_port, vars->aeu_int_mask);
15104 
15105 	if (port == 0)
15106 		offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
15107 	else
15108 		offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
15109 
15110 	/* Open appropriate AEU for interrupts */
15111 	aeu_mask = REG_RD(sc, offset);
15112 	aeu_mask |= vars->aeu_int_mask;
15113 	REG_WR(sc, offset, aeu_mask);
15114 
15115 	/* Enable the GPIO to trigger interrupt */
15116 	val = REG_RD(sc, MISC_REG_GPIO_EVENT_EN);
15117 	val |= 1 << (gpio_num + (gpio_port << 2));
15118 	REG_WR(sc, MISC_REG_GPIO_EVENT_EN, val);
15119 }
15120 
15121