xref: /dpdk/drivers/net/bnx2x/elink.c (revision 048ca64705eb521deabe5577038570072f68d3f0)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2007-2013 Broadcom Corporation.
3  *
4  * Eric Davis        <edavis@broadcom.com>
5  * David Christensen <davidch@broadcom.com>
6  * Gary Zambrano     <zambrano@broadcom.com>
7  *
8  * Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
9  * Copyright (c) 2015-2018 Cavium Inc.
10  * All rights reserved.
11  * www.cavium.com
12  */
13 
14 #include "bnx2x.h"
15 #include "elink.h"
16 #include "ecore_mfw_req.h"
17 #include "ecore_fw_defs.h"
18 #include "ecore_hsi.h"
19 #include "ecore_reg.h"
20 
21 
22 #define MDIO_REG_BANK_CL73_IEEEB0			0x0
23 	#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL		0x0
24 		#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN	0x0200
25 		#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN		0x1000
26 		#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_MAIN_RST	0x8000
27 
28 #define MDIO_REG_BANK_CL73_IEEEB1			0x10
29 	#define MDIO_CL73_IEEEB1_AN_ADV1			0x00
30 		#define	MDIO_CL73_IEEEB1_AN_ADV1_PAUSE			0x0400
31 		#define	MDIO_CL73_IEEEB1_AN_ADV1_ASYMMETRIC		0x0800
32 		#define	MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH		0x0C00
33 		#define	MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK		0x0C00
34 	#define MDIO_CL73_IEEEB1_AN_ADV2				0x01
35 		#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M		0x0000
36 		#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX		0x0020
37 		#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4		0x0040
38 		#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR		0x0080
39 	#define	MDIO_CL73_IEEEB1_AN_LP_ADV1			0x03
40 		#define	MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE		0x0400
41 		#define	MDIO_CL73_IEEEB1_AN_LP_ADV1_ASYMMETRIC		0x0800
42 		#define	MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_BOTH		0x0C00
43 		#define	MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK		0x0C00
44 	#define	MDIO_CL73_IEEEB1_AN_LP_ADV2			0x04
45 
46 #define	MDIO_REG_BANK_RX0				0x80b0
47 	#define	MDIO_RX0_RX_STATUS				0x10
48 		#define	MDIO_RX0_RX_STATUS_SIGDET			0x8000
49 		#define	MDIO_RX0_RX_STATUS_RX_SEQ_DONE			0x1000
50 	#define	MDIO_RX0_RX_EQ_BOOST				0x1c
51 		#define	MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
52 		#define	MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL		0x10
53 
54 #define	MDIO_REG_BANK_RX1				0x80c0
55 	#define	MDIO_RX1_RX_EQ_BOOST				0x1c
56 		#define	MDIO_RX1_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
57 		#define	MDIO_RX1_RX_EQ_BOOST_OFFSET_CTRL		0x10
58 
59 #define	MDIO_REG_BANK_RX2				0x80d0
60 	#define	MDIO_RX2_RX_EQ_BOOST				0x1c
61 		#define	MDIO_RX2_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
62 		#define	MDIO_RX2_RX_EQ_BOOST_OFFSET_CTRL		0x10
63 
64 #define	MDIO_REG_BANK_RX3				0x80e0
65 	#define	MDIO_RX3_RX_EQ_BOOST				0x1c
66 		#define	MDIO_RX3_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
67 		#define	MDIO_RX3_RX_EQ_BOOST_OFFSET_CTRL		0x10
68 
69 #define	MDIO_REG_BANK_RX_ALL				0x80f0
70 	#define	MDIO_RX_ALL_RX_EQ_BOOST				0x1c
71 		#define	MDIO_RX_ALL_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
72 		#define	MDIO_RX_ALL_RX_EQ_BOOST_OFFSET_CTRL	0x10
73 
74 #define	MDIO_REG_BANK_TX0				0x8060
75 	#define	MDIO_TX0_TX_DRIVER				0x17
76 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
77 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
78 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_MASK			0x0f00
79 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
80 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
81 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
82 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
83 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
84 		#define	MDIO_TX0_TX_DRIVER_ICBUF1T			1
85 
86 #define	MDIO_REG_BANK_TX1				0x8070
87 	#define	MDIO_TX1_TX_DRIVER				0x17
88 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
89 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
90 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_MASK			0x0f00
91 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
92 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
93 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
94 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
95 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
96 		#define	MDIO_TX0_TX_DRIVER_ICBUF1T			1
97 
98 #define	MDIO_REG_BANK_TX2				0x8080
99 	#define	MDIO_TX2_TX_DRIVER				0x17
100 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
101 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
102 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_MASK			0x0f00
103 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
104 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
105 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
106 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
107 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
108 		#define	MDIO_TX0_TX_DRIVER_ICBUF1T			1
109 
110 #define	MDIO_REG_BANK_TX3				0x8090
111 	#define	MDIO_TX3_TX_DRIVER				0x17
112 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
113 		#define	MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
114 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_MASK			0x0f00
115 		#define	MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
116 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
117 		#define	MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
118 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
119 		#define	MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
120 		#define	MDIO_TX0_TX_DRIVER_ICBUF1T			1
121 
122 #define	MDIO_REG_BANK_XGXS_BLOCK0			0x8000
123 	#define	MDIO_BLOCK0_XGXS_CONTROL			0x10
124 
125 #define	MDIO_REG_BANK_XGXS_BLOCK1			0x8010
126 	#define	MDIO_BLOCK1_LANE_CTRL0				0x15
127 	#define	MDIO_BLOCK1_LANE_CTRL1				0x16
128 	#define	MDIO_BLOCK1_LANE_CTRL2				0x17
129 	#define	MDIO_BLOCK1_LANE_PRBS				0x19
130 
131 #define	MDIO_REG_BANK_XGXS_BLOCK2			0x8100
132 	#define	MDIO_XGXS_BLOCK2_RX_LN_SWAP			0x10
133 		#define	MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE		0x8000
134 		#define	MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE	0x4000
135 		#define	MDIO_XGXS_BLOCK2_TX_LN_SWAP		0x11
136 		#define	MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE		0x8000
137 		#define	MDIO_XGXS_BLOCK2_UNICORE_MODE_10G	0x14
138 		#define	MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS	0x0001
139 		#define	MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS	0x0010
140 		#define	MDIO_XGXS_BLOCK2_TEST_MODE_LANE		0x15
141 
142 #define	MDIO_REG_BANK_GP_STATUS				0x8120
143 #define	MDIO_GP_STATUS_TOP_AN_STATUS1				0x1B
144 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE	0x0001
145 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE	0x0002
146 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS		0x0004
147 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS		0x0008
148 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE	0x0010
149 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_LP_NP_BAM_ABLE	0x0020
150 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE	0x0040
151 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE	0x0080
152 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK		0x3f00
153 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M		0x0000
154 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M		0x0100
155 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G		0x0200
156 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G		0x0300
157 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G		0x0400
158 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G		0x0500
159 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG	0x0600
160 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4	0x0700
161 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG	0x0800
162 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G	0x0900
163 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G		0x0A00
164 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G		0x0B00
165 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G		0x0C00
166 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX	0x0D00
167 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4	0x0E00
168 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR	0x0F00
169 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI	0x1B00
170 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS	0x1E00
171 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI	0x1F00
172 	#define	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_KR2	0x3900
173 
174 
175 #define	MDIO_REG_BANK_10G_PARALLEL_DETECT		0x8130
176 #define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS		0x10
177 #define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK		0x8000
178 #define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL		0x11
179 #define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN	0x1
180 #define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK		0x13
181 #define	MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT		(0xb71<<1)
182 
183 #define	MDIO_REG_BANK_SERDES_DIGITAL			0x8300
184 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1			0x10
185 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE			0x0001
186 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_TBI_IF			0x0002
187 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN		0x0004
188 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT	0x0008
189 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET			0x0010
190 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE			0x0020
191 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL2			0x11
192 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN			0x0001
193 #define	MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_AN_FST_TMR			0x0040
194 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1			0x14
195 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SGMII			0x0001
196 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_LINK			0x0002
197 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_DUPLEX			0x0004
198 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_MASK			0x0018
199 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_SHIFT			3
200 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_2_5G			0x0018
201 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_1G			0x0010
202 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_100M			0x0008
203 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_10M			0x0000
204 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS2			0x15
205 #define	MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED			0x0002
206 #define	MDIO_SERDES_DIGITAL_MISC1				0x18
207 #define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_MASK			0xE000
208 #define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_25M			0x0000
209 #define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_100M			0x2000
210 #define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_125M			0x4000
211 #define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M			0x6000
212 #define	MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_187_5M			0x8000
213 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL			0x0010
214 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK			0x000f
215 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_2_5G			0x0000
216 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_5G			0x0001
217 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_6G			0x0002
218 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_HIG			0x0003
219 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4			0x0004
220 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12G			0x0005
221 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12_5G			0x0006
222 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G			0x0007
223 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_15G			0x0008
224 #define	MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_16G			0x0009
225 
226 #define	MDIO_REG_BANK_OVER_1G				0x8320
227 #define	MDIO_OVER_1G_DIGCTL_3_4					0x14
228 #define	MDIO_OVER_1G_DIGCTL_3_4_MP_ID_MASK				0xffe0
229 #define	MDIO_OVER_1G_DIGCTL_3_4_MP_ID_SHIFT				5
230 #define	MDIO_OVER_1G_UP1					0x19
231 #define	MDIO_OVER_1G_UP1_2_5G						0x0001
232 #define	MDIO_OVER_1G_UP1_5G						0x0002
233 #define	MDIO_OVER_1G_UP1_6G						0x0004
234 #define	MDIO_OVER_1G_UP1_10G						0x0010
235 #define	MDIO_OVER_1G_UP1_10GH						0x0008
236 #define	MDIO_OVER_1G_UP1_12G						0x0020
237 #define	MDIO_OVER_1G_UP1_12_5G						0x0040
238 #define	MDIO_OVER_1G_UP1_13G						0x0080
239 #define	MDIO_OVER_1G_UP1_15G						0x0100
240 #define	MDIO_OVER_1G_UP1_16G						0x0200
241 #define	MDIO_OVER_1G_UP2					0x1A
242 #define	MDIO_OVER_1G_UP2_IPREDRIVER_MASK				0x0007
243 #define	MDIO_OVER_1G_UP2_IDRIVER_MASK					0x0038
244 #define	MDIO_OVER_1G_UP2_PREEMPHASIS_MASK				0x03C0
245 #define	MDIO_OVER_1G_UP3					0x1B
246 #define	MDIO_OVER_1G_UP3_HIGIG2						0x0001
247 #define	MDIO_OVER_1G_LP_UP1					0x1C
248 #define	MDIO_OVER_1G_LP_UP2					0x1D
249 #define	MDIO_OVER_1G_LP_UP2_MR_ADV_OVER_1G_MASK				0x03ff
250 #define	MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK				0x0780
251 #define	MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT				7
252 #define	MDIO_OVER_1G_LP_UP3						0x1E
253 
254 #define	MDIO_REG_BANK_REMOTE_PHY			0x8330
255 #define	MDIO_REMOTE_PHY_MISC_RX_STATUS				0x10
256 #define	MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG	0x0010
257 #define	MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG	0x0600
258 
259 #define	MDIO_REG_BANK_BAM_NEXT_PAGE			0x8350
260 #define	MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL			0x10
261 #define	MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE			0x0001
262 #define	MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN			0x0002
263 
264 #define	MDIO_REG_BANK_CL73_USERB0		0x8370
265 #define	MDIO_CL73_USERB0_CL73_UCTRL				0x10
266 #define	MDIO_CL73_USERB0_CL73_UCTRL_USTAT1_MUXSEL			0x0002
267 #define	MDIO_CL73_USERB0_CL73_USTAT1				0x11
268 #define	MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK			0x0100
269 #define	MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37		0x0400
270 #define	MDIO_CL73_USERB0_CL73_BAM_CTRL1				0x12
271 #define	MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN				0x8000
272 #define	MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN		0x4000
273 #define	MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN		0x2000
274 #define	MDIO_CL73_USERB0_CL73_BAM_CTRL3				0x14
275 #define	MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR			0x0001
276 
277 #define	MDIO_REG_BANK_AER_BLOCK			0xFFD0
278 #define	MDIO_AER_BLOCK_AER_REG					0x1E
279 
280 #define	MDIO_REG_BANK_COMBO_IEEE0		0xFFE0
281 #define	MDIO_COMBO_IEEE0_MII_CONTROL				0x10
282 #define	MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK			0x2040
283 #define	MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_10			0x0000
284 #define	MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100			0x2000
285 #define	MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000			0x0040
286 #define	MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX				0x0100
287 #define	MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN				0x0200
288 #define	MDIO_COMBO_IEEO_MII_CONTROL_AN_EN				0x1000
289 #define	MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK				0x4000
290 #define	MDIO_COMBO_IEEO_MII_CONTROL_RESET				0x8000
291 #define	MDIO_COMBO_IEEE0_MII_STATUS				0x11
292 #define	MDIO_COMBO_IEEE0_MII_STATUS_LINK_PASS				0x0004
293 #define	MDIO_COMBO_IEEE0_MII_STATUS_AUTONEG_COMPLETE			0x0020
294 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV				0x14
295 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX			0x0020
296 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_HALF_DUPLEX			0x0040
297 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK			0x0180
298 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE			0x0000
299 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC			0x0080
300 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC			0x0100
301 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH			0x0180
302 #define	MDIO_COMBO_IEEE0_AUTO_NEG_ADV_NEXT_PAGE				0x8000
303 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1		0x15
304 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_NEXT_PAGE	0x8000
305 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_ACK		0x4000
306 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_MASK	0x0180
307 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_NONE	0x0000
308 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_BOTH	0x0180
309 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_HALF_DUP_CAP	0x0040
310 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_FULL_DUP_CAP	0x0020
311 /*WhenthelinkpartnerisinSGMIImode(bit0=1),then
312 bit15=link,bit12=duplex,bits11:10=speed,bit14=acknowledge.
313 Theotherbitsarereservedandshouldbezero*/
314 #define	MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_SGMII_MODE	0x0001
315 
316 
317 #define	MDIO_PMA_DEVAD			0x1
318 /*ieee*/
319 #define	MDIO_PMA_REG_CTRL		0x0
320 #define	MDIO_PMA_REG_STATUS		0x1
321 #define	MDIO_PMA_REG_10G_CTRL2		0x7
322 #define MDIO_PMA_REG_TX_DISABLE		0x0009
323 #define	MDIO_PMA_REG_RX_SD		0xa
324 /*bnx2x*/
325 #define	MDIO_PMA_REG_BCM_CTRL		0x0096
326 #define MDIO_PMA_REG_FEC_CTRL		0x00ab
327 #define	MDIO_PMA_LASI_RXCTRL		0x9000
328 #define	MDIO_PMA_LASI_TXCTRL		0x9001
329 #define	MDIO_PMA_LASI_CTRL		0x9002
330 #define	MDIO_PMA_LASI_RXSTAT		0x9003
331 #define	MDIO_PMA_LASI_TXSTAT		0x9004
332 #define	MDIO_PMA_LASI_STAT		0x9005
333 #define	MDIO_PMA_REG_PHY_IDENTIFIER	0xc800
334 #define	MDIO_PMA_REG_DIGITAL_CTRL	0xc808
335 #define	MDIO_PMA_REG_DIGITAL_STATUS	0xc809
336 #define	MDIO_PMA_REG_TX_POWER_DOWN	0xca02
337 #define	MDIO_PMA_REG_CMU_PLL_BYPASS	0xca09
338 #define	MDIO_PMA_REG_MISC_CTRL		0xca0a
339 #define	MDIO_PMA_REG_GEN_CTRL		0xca10
340 	#define	MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP	0x0188
341 	#define	MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET		0x018a
342 #define	MDIO_PMA_REG_M8051_MSGIN_REG	0xca12
343 #define	MDIO_PMA_REG_M8051_MSGOUT_REG	0xca13
344 #define	MDIO_PMA_REG_ROM_VER1		0xca19
345 #define	MDIO_PMA_REG_ROM_VER2		0xca1a
346 #define	MDIO_PMA_REG_EDC_FFE_MAIN	0xca1b
347 #define	MDIO_PMA_REG_PLL_BANDWIDTH	0xca1d
348 #define MDIO_PMA_REG_PLL_CTRL 		0xca1e
349 #define MDIO_PMA_REG_MISC_CTRL0 	0xca23
350 #define MDIO_PMA_REG_LRM_MODE	 	0xca3f
351 #define	MDIO_PMA_REG_CDR_BANDWIDTH 	0xca46
352 #define	MDIO_PMA_REG_MISC_CTRL1		0xca85
353 
354 #define MDIO_PMA_REG_SFP_TWO_WIRE_CTRL		0x8000
355 #define MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK	0x000c
356 #define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE		0x0000
357 #define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE	0x0004
358 #define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IN_PROGRESS	0x0008
359 #define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_FAILED		0x000c
360 #define MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT 	0x8002
361 #define MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR 	0x8003
362 #define MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF	0xc820
363 	#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK 0xff
364 #define MDIO_PMA_REG_8726_TX_CTRL1		0xca01
365 #define MDIO_PMA_REG_8726_TX_CTRL2		0xca05
366 
367 #define MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR	0x8005
368 #define MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF	0x8007
369 	#define MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK 0xff
370 #define MDIO_PMA_REG_8727_MISC_CTRL		0x8309
371 #define MDIO_PMA_REG_8727_TX_CTRL1		0xca02
372 #define MDIO_PMA_REG_8727_TX_CTRL2		0xca05
373 #define MDIO_PMA_REG_8727_PCS_OPT_CTRL		0xc808
374 #define MDIO_PMA_REG_8727_GPIO_CTRL		0xc80e
375 #define MDIO_PMA_REG_8727_PCS_GP		0xc842
376 #define MDIO_PMA_REG_8727_OPT_CFG_REG		0xc8e4
377 
378 #define MDIO_AN_REG_8727_MISC_CTRL		0x8309
379 #define	MDIO_PMA_REG_8073_CHIP_REV			0xc801
380 #define MDIO_PMA_REG_8073_SPEED_LINK_STATUS		0xc820
381 #define MDIO_PMA_REG_8073_XAUI_WA 			0xc841
382 #define MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL 		0xcd08
383 
384 #define MDIO_PMA_REG_7101_RESET		0xc000
385 #define	MDIO_PMA_REG_7107_LED_CNTL	0xc007
386 #define	MDIO_PMA_REG_7107_LINK_LED_CNTL	0xc009
387 #define	MDIO_PMA_REG_7101_VER1		0xc026
388 #define	MDIO_PMA_REG_7101_VER2		0xc027
389 
390 #define MDIO_PMA_REG_8481_PMD_SIGNAL	0xa811
391 #define MDIO_PMA_REG_8481_LED1_MASK	0xa82c
392 #define MDIO_PMA_REG_8481_LED2_MASK	0xa82f
393 #define MDIO_PMA_REG_8481_LED3_MASK	0xa832
394 #define MDIO_PMA_REG_8481_LED3_BLINK	0xa834
395 #define MDIO_PMA_REG_8481_LED5_MASK	                0xa838
396 #define MDIO_PMA_REG_8481_SIGNAL_MASK	0xa835
397 #define MDIO_PMA_REG_8481_LINK_SIGNAL	0xa83b
398 #define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK	0x800
399 #define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT	11
400 
401 
402 
403 #define	MDIO_WIS_DEVAD			0x2
404 /*bnx2x*/
405 #define	MDIO_WIS_REG_LASI_CNTL		0x9002
406 #define	MDIO_WIS_REG_LASI_STATUS	0x9005
407 
408 #define	MDIO_PCS_DEVAD			0x3
409 #define	MDIO_PCS_REG_STATUS		0x0020
410 #define MDIO_PCS_REG_LASI_STATUS	0x9005
411 #define MDIO_PCS_REG_7101_DSP_ACCESS	0xD000
412 #define MDIO_PCS_REG_7101_SPI_MUX 	0xD008
413 #define MDIO_PCS_REG_7101_SPI_CTRL_ADDR 0xE12A
414 	#define MDIO_PCS_REG_7101_SPI_RESET_BIT (5)
415 #define MDIO_PCS_REG_7101_SPI_FIFO_ADDR 0xE02A
416 	#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD (6)
417 	#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD   (0xC7)
418 	#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD (2)
419 #define MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR 0xE028
420 
421 
422 
423 #define	MDIO_XS_DEVAD			0x4
424 #define	MDIO_XS_REG_STATUS		0x0001
425 #define MDIO_XS_PLL_SEQUENCER 		0x8000
426 #define	MDIO_XS_SFX7101_XGXS_TEST1	0xc00a
427 
428 #define MDIO_XS_8706_REG_BANK_RX0	0x80bc
429 #define MDIO_XS_8706_REG_BANK_RX1	0x80cc
430 #define MDIO_XS_8706_REG_BANK_RX2	0x80dc
431 #define MDIO_XS_8706_REG_BANK_RX3	0x80ec
432 #define MDIO_XS_8706_REG_BANK_RXA	0x80fc
433 
434 #define MDIO_XS_REG_8073_RX_CTRL_PCIE	0x80FA
435 
436 #define	MDIO_AN_DEVAD			0x7
437 /*ieee*/
438 #define	MDIO_AN_REG_CTRL		0x0000
439 #define	MDIO_AN_REG_STATUS		0x0001
440 	#define	MDIO_AN_REG_STATUS_AN_COMPLETE		0x0020
441 #define	MDIO_AN_REG_ADV_PAUSE		0x0010
442 	#define	MDIO_AN_REG_ADV_PAUSE_PAUSE		0x0400
443 	#define	MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC	0x0800
444 	#define	MDIO_AN_REG_ADV_PAUSE_BOTH		0x0C00
445 	#define	MDIO_AN_REG_ADV_PAUSE_MASK		0x0C00
446 #define	MDIO_AN_REG_ADV			0x0011
447 #define MDIO_AN_REG_ADV2		0x0012
448 #define	MDIO_AN_REG_LP_AUTO_NEG		0x0013
449 #define	MDIO_AN_REG_LP_AUTO_NEG2	0x0014
450 #define	MDIO_AN_REG_MASTER_STATUS	0x0021
451 #define	MDIO_AN_REG_EEE_ADV		0x003c
452 #define	MDIO_AN_REG_LP_EEE_ADV		0x003d
453 /*bnx2x*/
454 #define	MDIO_AN_REG_LINK_STATUS		0x8304
455 #define	MDIO_AN_REG_CL37_CL73		0x8370
456 #define	MDIO_AN_REG_CL37_AN		0xffe0
457 #define	MDIO_AN_REG_CL37_FC_LD		0xffe4
458 #define 	MDIO_AN_REG_CL37_FC_LP		0xffe5
459 #define 	MDIO_AN_REG_1000T_STATUS	0xffea
460 
461 #define MDIO_AN_REG_8073_2_5G		0x8329
462 #define MDIO_AN_REG_8073_BAM		0x8350
463 
464 #define MDIO_AN_REG_8481_10GBASE_T_AN_CTRL	0x0020
465 #define MDIO_AN_REG_8481_LEGACY_MII_CTRL	0xffe0
466 	#define MDIO_AN_REG_8481_MII_CTRL_FORCE_1G	0x40
467 #define MDIO_AN_REG_8481_LEGACY_MII_STATUS	0xffe1
468 #define MDIO_AN_REG_848xx_ID_MSB		0xffe2
469 	#define BNX2X84858_PHY_ID					0x600d
470 #define MDIO_AN_REG_848xx_ID_LSB		0xffe3
471 #define MDIO_AN_REG_8481_LEGACY_AN_ADV		0xffe4
472 #define MDIO_AN_REG_8481_LEGACY_AN_EXPANSION	0xffe6
473 #define MDIO_AN_REG_8481_1000T_CTRL		0xffe9
474 #define MDIO_AN_REG_8481_1G_100T_EXT_CTRL	0xfff0
475 	#define MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF	0x0008
476 #define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW	0xfff5
477 #define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS	0xfff7
478 #define MDIO_AN_REG_8481_AUX_CTRL		0xfff8
479 #define MDIO_AN_REG_8481_LEGACY_SHADOW		0xfffc
480 
481 /* BNX2X84823 only */
482 #define	MDIO_CTL_DEVAD			0x1e
483 #define MDIO_CTL_REG_84823_MEDIA		0x401a
484 	#define MDIO_CTL_REG_84823_MEDIA_MAC_MASK		0x0018
485 	/* These pins configure the BNX2X84823 interface to MAC after reset. */
486 		#define MDIO_CTL_REG_84823_CTRL_MAC_XFI			0x0008
487 		#define MDIO_CTL_REG_84823_MEDIA_MAC_XAUI_M		0x0010
488 	/* These pins configure the BNX2X84823 interface to Line after reset. */
489 	#define MDIO_CTL_REG_84823_MEDIA_LINE_MASK		0x0060
490 		#define MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L		0x0020
491 		#define MDIO_CTL_REG_84823_MEDIA_LINE_XFI		0x0040
492 	/* When this pin is active high during reset, 10GBASE-T core is power
493 	 * down, When it is active low the 10GBASE-T is power up
494 	 */
495 	#define MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN	0x0080
496 	#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK		0x0100
497 		#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER	0x0000
498 		#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER		0x0100
499 	#define MDIO_CTL_REG_84823_MEDIA_FIBER_1G			0x1000
500 #define MDIO_CTL_REG_84823_USER_CTRL_REG			0x4005
501 	#define MDIO_CTL_REG_84823_USER_CTRL_CMS			0x0080
502 #define MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH		0xa82b
503 	#define MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ	0x2f
504 #define MDIO_PMA_REG_84823_CTL_LED_CTL_1			0xa8e3
505 #define MDIO_PMA_REG_84833_CTL_LED_CTL_1			0xa8ec
506 	#define MDIO_PMA_REG_84823_LED3_STRETCH_EN			0x0080
507 
508 /* BNX2X84833 only */
509 #define MDIO_84833_TOP_CFG_FW_REV			0x400f
510 #define MDIO_84833_TOP_CFG_FW_EEE			0x10b1
511 #define MDIO_84833_TOP_CFG_FW_NO_EEE			0x1f81
512 #define MDIO_84833_TOP_CFG_XGPHY_STRAP1 		0x401a
513 #define MDIO_84833_SUPER_ISOLATE			0x8000
514 /* These are mailbox register set used by 84833/84858. */
515 #define MDIO_848xx_TOP_CFG_SCRATCH_REG0			0x4005
516 #define MDIO_848xx_TOP_CFG_SCRATCH_REG1			0x4006
517 #define MDIO_848xx_TOP_CFG_SCRATCH_REG2			0x4007
518 #define MDIO_848xx_TOP_CFG_SCRATCH_REG3			0x4008
519 #define MDIO_848xx_TOP_CFG_SCRATCH_REG4			0x4009
520 #define MDIO_848xx_TOP_CFG_SCRATCH_REG26		0x4037
521 #define MDIO_848xx_TOP_CFG_SCRATCH_REG27		0x4038
522 #define MDIO_848xx_TOP_CFG_SCRATCH_REG28		0x4039
523 #define MDIO_848xx_TOP_CFG_SCRATCH_REG29		0x403a
524 #define MDIO_848xx_TOP_CFG_SCRATCH_REG30		0x403b
525 #define MDIO_848xx_TOP_CFG_SCRATCH_REG31		0x403c
526 #define MDIO_848xx_CMD_HDLR_COMMAND	(MDIO_848xx_TOP_CFG_SCRATCH_REG0)
527 #define MDIO_848xx_CMD_HDLR_STATUS	(MDIO_848xx_TOP_CFG_SCRATCH_REG26)
528 #define MDIO_848xx_CMD_HDLR_DATA1	(MDIO_848xx_TOP_CFG_SCRATCH_REG27)
529 #define MDIO_848xx_CMD_HDLR_DATA2	(MDIO_848xx_TOP_CFG_SCRATCH_REG28)
530 #define MDIO_848xx_CMD_HDLR_DATA3	(MDIO_848xx_TOP_CFG_SCRATCH_REG29)
531 #define MDIO_848xx_CMD_HDLR_DATA4	(MDIO_848xx_TOP_CFG_SCRATCH_REG30)
532 #define MDIO_848xx_CMD_HDLR_DATA5	(MDIO_848xx_TOP_CFG_SCRATCH_REG31)
533 
534 /* Mailbox command set used by 84833/84858 */
535 #define PHY848xx_CMD_SET_PAIR_SWAP			0x8001
536 #define PHY848xx_CMD_GET_EEE_MODE			0x8008
537 #define PHY848xx_CMD_SET_EEE_MODE			0x8009
538 #define PHY848xx_CMD_GET_CURRENT_TEMP			0x8031
539 /* Mailbox status set used by 84833 only */
540 #define PHY84833_STATUS_CMD_RECEIVED			0x0001
541 #define PHY84833_STATUS_CMD_IN_PROGRESS			0x0002
542 #define PHY84833_STATUS_CMD_COMPLETE_PASS		0x0004
543 #define PHY84833_STATUS_CMD_COMPLETE_ERROR		0x0008
544 #define PHY84833_STATUS_CMD_OPEN_FOR_CMDS		0x0010
545 #define PHY84833_STATUS_CMD_SYSTEM_BOOT			0x0020
546 #define PHY84833_STATUS_CMD_NOT_OPEN_FOR_CMDS		0x0040
547 #define PHY84833_STATUS_CMD_CLEAR_COMPLETE		0x0080
548 #define PHY84833_STATUS_CMD_OPEN_OVERRIDE		0xa5a5
549 /* Mailbox Process */
550 #define PHY84833_MB_PROCESS1				1
551 #define PHY84833_MB_PROCESS2				2
552 #define PHY84833_MB_PROCESS3				3
553 
554 
555 /* Mailbox status set used by 84858 only */
556 #define PHY84858_STATUS_CMD_RECEIVED			0x0001
557 #define PHY84858_STATUS_CMD_IN_PROGRESS			0x0002
558 #define PHY84858_STATUS_CMD_COMPLETE_PASS		0x0004
559 #define PHY84858_STATUS_CMD_COMPLETE_ERROR		0x0008
560 #define PHY84858_STATUS_CMD_SYSTEM_BUSY                 0xbbbb
561 
562 
563 /* Warpcore clause 45 addressing */
564 #define MDIO_WC_DEVAD					0x3
565 #define MDIO_WC_REG_IEEE0BLK_MIICNTL                    0x0
566 #define MDIO_WC_REG_IEEE0BLK_AUTONEGNP                  0x7
567 #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT0       0x10
568 #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1       0x11
569 #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2       0x12
570 	#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY	0x4000
571 	#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ		0x8000
572 #define MDIO_WC_REG_PCS_STATUS2				0x0021
573 #define MDIO_WC_REG_PMD_KR_CONTROL			0x0096
574 #define MDIO_WC_REG_XGXSBLK0_XGXSCONTROL                0x8000
575 #define MDIO_WC_REG_XGXSBLK0_MISCCONTROL1               0x800e
576 #define MDIO_WC_REG_XGXSBLK1_DESKEW                     0x8010
577 #define MDIO_WC_REG_XGXSBLK1_LANECTRL0                  0x8015
578 #define MDIO_WC_REG_XGXSBLK1_LANECTRL1                  0x8016
579 #define MDIO_WC_REG_XGXSBLK1_LANECTRL2                  0x8017
580 #define MDIO_WC_REG_XGXSBLK1_LANECTRL3                  0x8018
581 #define MDIO_WC_REG_XGXSBLK1_LANETEST0                  0x801a
582 #define MDIO_WC_REG_TX0_ANA_CTRL0			0x8061
583 #define MDIO_WC_REG_TX1_ANA_CTRL0			0x8071
584 #define MDIO_WC_REG_TX2_ANA_CTRL0			0x8081
585 #define MDIO_WC_REG_TX3_ANA_CTRL0			0x8091
586 #define MDIO_WC_REG_TX0_TX_DRIVER			0x8067
587 #define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET			0x01
588 #define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_MASK				0x000e
589 #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET		0x04
590 #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_MASK			0x00f0
591 #define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET		0x08
592 #define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_MASK				0x0f00
593 #define MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET		0x0c
594 #define MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_MASK			0x7000
595 #define MDIO_WC_REG_TX1_TX_DRIVER			0x8077
596 #define MDIO_WC_REG_TX2_TX_DRIVER			0x8087
597 #define MDIO_WC_REG_TX3_TX_DRIVER			0x8097
598 #define MDIO_WC_REG_RX0_ANARXCONTROL1G                  0x80b9
599 #define MDIO_WC_REG_RX2_ANARXCONTROL1G                  0x80d9
600 #define MDIO_WC_REG_RX0_PCI_CTRL			0x80ba
601 #define MDIO_WC_REG_RX1_PCI_CTRL			0x80ca
602 #define MDIO_WC_REG_RX2_PCI_CTRL			0x80da
603 #define MDIO_WC_REG_RX3_PCI_CTRL			0x80ea
604 #define MDIO_WC_REG_RXB_ANA_RX_CONTROL_PCI		0x80fa
605 #define MDIO_WC_REG_XGXSBLK2_UNICORE_MODE_10G 		0x8104
606 #define MDIO_WC_REG_XGXSBLK2_LANE_RESET			0x810a
607 #define MDIO_WC_REG_XGXS_STATUS3			0x8129
608 #define MDIO_WC_REG_PAR_DET_10G_STATUS			0x8130
609 #define MDIO_WC_REG_PAR_DET_10G_CTRL			0x8131
610 #define MDIO_WC_REG_XGXS_STATUS4                        0x813c
611 #define MDIO_WC_REG_XGXS_X2_CONTROL2 		        0x8141
612 #define MDIO_WC_REG_XGXS_X2_CONTROL3 		        0x8142
613 #define MDIO_WC_REG_XGXS_RX_LN_SWAP1		      	0x816B
614 #define MDIO_WC_REG_XGXS_TX_LN_SWAP1		      	0x8169
615 #define MDIO_WC_REG_GP2_STATUS_GP_2_0			0x81d0
616 #define MDIO_WC_REG_GP2_STATUS_GP_2_1			0x81d1
617 #define MDIO_WC_REG_GP2_STATUS_GP_2_2			0x81d2
618 #define MDIO_WC_REG_GP2_STATUS_GP_2_3			0x81d3
619 #define MDIO_WC_REG_GP2_STATUS_GP_2_4			0x81d4
620 	#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL 0x1000
621 	#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CMPL 0x0100
622 	#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP 0x0010
623 	#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CAP 0x1
624 #define MDIO_WC_REG_UC_INFO_B0_DEAD_TRAP                0x81EE
625 #define MDIO_WC_REG_UC_INFO_B1_VERSION                  0x81F0
626 #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE		0x81F2
627 	#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE0_OFFSET	0x0
628 		#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT        0x0
629 		#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_OPT_LR     0x1
630 		#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC        0x2
631 		#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_XLAUI      0x3
632 		#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_LONG_CH_6G     0x4
633 	#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE1_OFFSET	0x4
634 	#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE2_OFFSET	0x8
635 	#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE3_OFFSET	0xc
636 #define MDIO_WC_REG_UC_INFO_B1_CRC                      0x81FE
637 #define MDIO_WC_REG_DSC1B0_UC_CTRL				0x820e
638 #define MDIO_WC_REG_DSC1B0_UC_CTRL_RDY4CMD			(1<<7)
639 #define MDIO_WC_REG_DSC_SMC				0x8213
640 #define MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0		0x821e
641 #define MDIO_WC_REG_TX_FIR_TAP				0x82e2
642 	#define MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET		0x00
643 	#define MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_MASK			0x000f
644 	#define MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET		0x04
645 	#define MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_MASK		0x03f0
646 	#define MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET		0x0a
647 	#define MDIO_WC_REG_TX_FIR_TAP_POST_TAP_MASK		0x7c00
648 	#define MDIO_WC_REG_TX_FIR_TAP_ENABLE		0x8000
649 #define MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP		0x82e2
650 #define MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL      0x82e3
651 #define MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL	0x82e6
652 #define MDIO_WC_REG_CL72_USERB0_CL72_BR_DEF_CTRL	0x82e7
653 #define MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL	0x82e8
654 #define MDIO_WC_REG_CL72_USERB0_CL72_MISC4_CONTROL      0x82ec
655 #define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1         0x8300
656 #define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2         0x8301
657 #define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3         0x8302
658 #define MDIO_WC_REG_SERDESDIGITAL_STATUS1000X1          0x8304
659 #define MDIO_WC_REG_SERDESDIGITAL_MISC1                 0x8308
660 #define MDIO_WC_REG_SERDESDIGITAL_MISC2                 0x8309
661 #define MDIO_WC_REG_DIGITAL3_UP1                        0x8329
662 #define MDIO_WC_REG_DIGITAL3_LP_UP1                     0x832c
663 #define MDIO_WC_REG_DIGITAL4_MISC3                      0x833c
664 #define MDIO_WC_REG_DIGITAL4_MISC5                      0x833e
665 #define MDIO_WC_REG_DIGITAL5_MISC6                      0x8345
666 #define MDIO_WC_REG_DIGITAL5_MISC7                      0x8349
667 #define MDIO_WC_REG_DIGITAL5_LINK_STATUS		0x834d
668 #define MDIO_WC_REG_DIGITAL5_ACTUAL_SPEED               0x834e
669 #define MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL           0x8350
670 #define MDIO_WC_REG_CL49_USERB0_CTRL	                0x8368
671 #define MDIO_WC_REG_CL73_USERB0_CTRL                    0x8370
672 #define MDIO_WC_REG_CL73_USERB0_USTAT                   0x8371
673 #define MDIO_WC_REG_CL73_BAM_CTRL1			0x8372
674 #define MDIO_WC_REG_CL73_BAM_CTRL2			0x8373
675 #define MDIO_WC_REG_CL73_BAM_CTRL3			0x8374
676 #define MDIO_WC_REG_CL73_BAM_CODE_FIELD			0x837b
677 #define MDIO_WC_REG_EEE_COMBO_CONTROL0                  0x8390
678 #define MDIO_WC_REG_TX66_CONTROL                        0x83b0
679 #define MDIO_WC_REG_RX66_CONTROL                        0x83c0
680 #define MDIO_WC_REG_RX66_SCW0                           0x83c2
681 #define MDIO_WC_REG_RX66_SCW1                           0x83c3
682 #define MDIO_WC_REG_RX66_SCW2                           0x83c4
683 #define MDIO_WC_REG_RX66_SCW3                           0x83c5
684 #define MDIO_WC_REG_RX66_SCW0_MASK                      0x83c6
685 #define MDIO_WC_REG_RX66_SCW1_MASK                      0x83c7
686 #define MDIO_WC_REG_RX66_SCW2_MASK                      0x83c8
687 #define MDIO_WC_REG_RX66_SCW3_MASK                      0x83c9
688 #define MDIO_WC_REG_FX100_CTRL1				0x8400
689 #define MDIO_WC_REG_FX100_CTRL3				0x8402
690 #define MDIO_WC_REG_CL82_USERB1_TX_CTRL5		0x8436
691 #define MDIO_WC_REG_CL82_USERB1_TX_CTRL6		0x8437
692 #define MDIO_WC_REG_CL82_USERB1_TX_CTRL7		0x8438
693 #define MDIO_WC_REG_CL82_USERB1_TX_CTRL9		0x8439
694 #define MDIO_WC_REG_CL82_USERB1_RX_CTRL10		0x843a
695 #define MDIO_WC_REG_CL82_USERB1_RX_CTRL11		0x843b
696 #define MDIO_WC_REG_ETA_CL73_OUI1			0x8453
697 #define MDIO_WC_REG_ETA_CL73_OUI2			0x8454
698 #define MDIO_WC_REG_ETA_CL73_OUI3			0x8455
699 #define MDIO_WC_REG_ETA_CL73_LD_BAM_CODE		0x8456
700 #define MDIO_WC_REG_ETA_CL73_LD_UD_CODE			0x8457
701 #define MDIO_WC_REG_MICROBLK_CMD                        0xffc2
702 #define MDIO_WC_REG_MICROBLK_DL_STATUS                  0xffc5
703 #define MDIO_WC_REG_MICROBLK_CMD3                       0xffcc
704 
705 #define MDIO_WC_REG_AERBLK_AER                          0xffde
706 #define MDIO_WC_REG_COMBO_IEEE0_MIICTRL			0xffe0
707 #define MDIO_WC_REG_COMBO_IEEE0_MIIISTAT                0xffe1
708 
709 #define MDIO_WC0_XGXS_BLK2_LANE_RESET                   0x810A
710 #define MDIO_WC0_XGXS_BLK2_LANE_RESET_RX_BITSHIFT	0
711 #define MDIO_WC0_XGXS_BLK2_LANE_RESET_TX_BITSHIFT	4
712 
713 #define MDIO_WC0_XGXS_BLK6_XGXS_X2_CONTROL2             0x8141
714 
715 #define DIGITAL5_ACTUAL_SPEED_TX_MASK                   0x003f
716 
717 /* 54618se */
718 #define MDIO_REG_GPHY_MII_STATUS			0x1
719 #define MDIO_REG_GPHY_PHYID_LSB				0x3
720 #define MDIO_REG_GPHY_CL45_ADDR_REG			0xd
721 	#define MDIO_REG_GPHY_CL45_REG_WRITE		0x4000
722 	#define MDIO_REG_GPHY_CL45_REG_READ		0xc000
723 #define MDIO_REG_GPHY_CL45_DATA_REG			0xe
724 	#define MDIO_REG_GPHY_EEE_RESOLVED		0x803e
725 #define MDIO_REG_GPHY_EXP_ACCESS_GATE			0x15
726 #define MDIO_REG_GPHY_EXP_ACCESS			0x17
727 	#define MDIO_REG_GPHY_EXP_ACCESS_TOP		0xd00
728 	#define MDIO_REG_GPHY_EXP_TOP_2K_BUF		0x40
729 #define MDIO_REG_GPHY_AUX_STATUS			0x19
730 #define MDIO_REG_INTR_STATUS				0x1a
731 #define MDIO_REG_INTR_MASK				0x1b
732 	#define MDIO_REG_INTR_MASK_LINK_STATUS			(0x1 << 1)
733 #define MDIO_REG_GPHY_SHADOW				0x1c
734 	#define MDIO_REG_GPHY_SHADOW_LED_SEL1			(0x0d << 10)
735 	#define MDIO_REG_GPHY_SHADOW_LED_SEL2			(0x0e << 10)
736 	#define MDIO_REG_GPHY_SHADOW_WR_ENA			(0x1 << 15)
737 	#define MDIO_REG_GPHY_SHADOW_AUTO_DET_MED		(0x1e << 10)
738 	#define MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD		(0x1 << 8)
739 
740 
741 typedef elink_status_t (*read_sfp_module_eeprom_func_p)(struct elink_phy *phy,
742 					     struct elink_params *params,
743 					     uint8_t dev_addr, uint16_t addr,
744 					     uint8_t byte_cnt,
745 					     uint8_t *o_buf, uint8_t);
746 /********************************************************/
747 #define ELINK_ETH_HLEN			14
748 /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
749 #define ELINK_ETH_OVREHEAD			(ELINK_ETH_HLEN + 8 + 8)
750 #define ELINK_ETH_MIN_PACKET_SIZE		60
751 #define ELINK_ETH_MAX_PACKET_SIZE		1500
752 #define ELINK_ETH_MAX_JUMBO_PACKET_SIZE	9600
753 #define ELINK_MDIO_ACCESS_TIMEOUT		1000
754 #define WC_LANE_MAX			4
755 #define I2C_SWITCH_WIDTH		2
756 #define I2C_BSC0			0
757 #define I2C_BSC1			1
758 #define I2C_WA_RETRY_CNT		3
759 #define I2C_WA_PWR_ITER			(I2C_WA_RETRY_CNT - 1)
760 #define MCPR_IMC_COMMAND_READ_OP	1
761 #define MCPR_IMC_COMMAND_WRITE_OP	2
762 
763 /* LED Blink rate that will achieve ~15.9Hz */
764 #define LED_BLINK_RATE_VAL_E3		354
765 #define LED_BLINK_RATE_VAL_E1X_E2	480
766 /***********************************************************/
767 /*			Shortcut definitions		   */
768 /***********************************************************/
769 
770 #define ELINK_NIG_LATCH_BC_ENABLE_MI_INT 0
771 
772 #define ELINK_NIG_STATUS_EMAC0_MI_INT \
773 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
774 #define ELINK_NIG_STATUS_XGXS0_LINK10G \
775 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
776 #define ELINK_NIG_STATUS_XGXS0_LINK_STATUS \
777 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
778 #define ELINK_NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
779 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
780 #define ELINK_NIG_STATUS_SERDES0_LINK_STATUS \
781 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
782 #define ELINK_NIG_MASK_MI_INT \
783 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
784 #define ELINK_NIG_MASK_XGXS0_LINK10G \
785 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
786 #define ELINK_NIG_MASK_XGXS0_LINK_STATUS \
787 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
788 #define ELINK_NIG_MASK_SERDES0_LINK_STATUS \
789 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
790 
791 #define ELINK_MDIO_AN_CL73_OR_37_COMPLETE \
792 		(MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
793 		 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
794 
795 #define ELINK_XGXS_RESET_BITS \
796 	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
797 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
798 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
799 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
800 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
801 
802 #define ELINK_SERDES_RESET_BITS \
803 	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
804 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
805 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
806 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
807 
808 #define ELINK_AUTONEG_CL37		SHARED_HW_CFG_AN_ENABLE_CL37
809 #define ELINK_AUTONEG_CL73		SHARED_HW_CFG_AN_ENABLE_CL73
810 #define ELINK_AUTONEG_BAM		SHARED_HW_CFG_AN_ENABLE_BAM
811 #define ELINK_AUTONEG_PARALLEL \
812 				SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
813 #define ELINK_AUTONEG_SGMII_FIBER_AUTODET \
814 				SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
815 #define ELINK_AUTONEG_REMOTE_PHY	SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
816 
817 #define ELINK_GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
818 			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
819 #define ELINK_GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
820 			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
821 #define ELINK_GP_STATUS_SPEED_MASK \
822 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
823 #define ELINK_GP_STATUS_10M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
824 #define ELINK_GP_STATUS_100M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
825 #define ELINK_GP_STATUS_1G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
826 #define ELINK_GP_STATUS_2_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
827 #define ELINK_GP_STATUS_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
828 #define ELINK_GP_STATUS_6G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
829 #define ELINK_GP_STATUS_10G_HIG \
830 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
831 #define ELINK_GP_STATUS_10G_CX4 \
832 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
833 #define ELINK_GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
834 #define ELINK_GP_STATUS_10G_KX4 \
835 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
836 #define	ELINK_GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
837 #define	ELINK_GP_STATUS_10G_XFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
838 #define	ELINK_GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
839 #define	ELINK_GP_STATUS_10G_SFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
840 #define	ELINK_GP_STATUS_20G_KR2 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_KR2
841 #define ELINK_LINK_10THD		LINK_STATUS_SPEED_AND_DUPLEX_10THD
842 #define ELINK_LINK_10TFD		LINK_STATUS_SPEED_AND_DUPLEX_10TFD
843 #define ELINK_LINK_100TXHD		LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
844 #define ELINK_LINK_100T4		LINK_STATUS_SPEED_AND_DUPLEX_100T4
845 #define ELINK_LINK_100TXFD		LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
846 #define ELINK_LINK_1000THD		LINK_STATUS_SPEED_AND_DUPLEX_1000THD
847 #define ELINK_LINK_1000TFD		LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
848 #define ELINK_LINK_1000XFD		LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
849 #define ELINK_LINK_2500THD		LINK_STATUS_SPEED_AND_DUPLEX_2500THD
850 #define ELINK_LINK_2500TFD		LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
851 #define ELINK_LINK_2500XFD		LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
852 #define ELINK_LINK_10GTFD		LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
853 #define ELINK_LINK_10GXFD		LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
854 #define ELINK_LINK_20GTFD		LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
855 #define ELINK_LINK_20GXFD		LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
856 
857 #define ELINK_LINK_UPDATE_MASK \
858 			(LINK_STATUS_SPEED_AND_DUPLEX_MASK | \
859 			 LINK_STATUS_LINK_UP | \
860 			 LINK_STATUS_PHYSICAL_LINK_FLAG | \
861 			 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \
862 			 LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \
863 			 LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \
864 			 LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \
865 			 LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \
866 			 LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE)
867 
868 #define ELINK_SFP_EEPROM_CON_TYPE_ADDR		0x2
869 	#define ELINK_SFP_EEPROM_CON_TYPE_VAL_UNKNOWN	0x0
870 	#define ELINK_SFP_EEPROM_CON_TYPE_VAL_SC        0x1
871 	#define ELINK_SFP_EEPROM_CON_TYPE_VAL_LC	0x7
872 	#define ELINK_SFP_EEPROM_CON_TYPE_VAL_COPPER	0x21
873 	#define ELINK_SFP_EEPROM_CON_TYPE_VAL_RJ45	0x22
874 
875 
876 #define ELINK_SFP_EEPROM_10G_COMP_CODE_ADDR		0x3
877 	#define ELINK_SFP_EEPROM_10G_COMP_CODE_SR_MASK	(1 << 4)
878 	#define ELINK_SFP_EEPROM_10G_COMP_CODE_LR_MASK	(1 << 5)
879 	#define ELINK_SFP_EEPROM_10G_COMP_CODE_LRM_MASK	(1 << 6)
880 
881 #define ELINK_SFP_EEPROM_1G_COMP_CODE_ADDR		0x6
882 	#define ELINK_SFP_EEPROM_1G_COMP_CODE_SX	(1 << 0)
883 	#define ELINK_SFP_EEPROM_1G_COMP_CODE_LX	(1 << 1)
884 	#define ELINK_SFP_EEPROM_1G_COMP_CODE_CX	(1 << 2)
885 	#define ELINK_SFP_EEPROM_1G_COMP_CODE_BASE_T	(1 << 3)
886 
887 #define ELINK_SFP_EEPROM_FC_TX_TECH_ADDR		0x8
888 	#define ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
889 	#define ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE  0x8
890 
891 #define ELINK_SFP_EEPROM_OPTIONS_ADDR			0x40
892 	#define ELINK_SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
893 #define ELINK_SFP_EEPROM_OPTIONS_SIZE			2
894 
895 #define ELINK_EDC_MODE_LINEAR				0x0022
896 #define ELINK_EDC_MODE_LIMITING				0x0044
897 #define ELINK_EDC_MODE_PASSIVE_DAC			0x0055
898 #define ELINK_EDC_MODE_ACTIVE_DAC			0x0066
899 
900 /* ETS defines*/
901 #define DCBX_INVALID_COS					(0xFF)
902 
903 #define ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND		(0x5000)
904 #define ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT		(0x5000)
905 #define ELINK_ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS		(1360)
906 #define ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS			(2720)
907 #define ELINK_ETS_E3B0_PBF_MIN_W_VAL				(10000)
908 
909 #define ELINK_MAX_PACKET_SIZE					(9700)
910 #define MAX_KR_LINK_RETRY				4
911 #define DEFAULT_TX_DRV_BRDCT		2
912 #define DEFAULT_TX_DRV_IFIR		0
913 #define DEFAULT_TX_DRV_POST2		3
914 #define DEFAULT_TX_DRV_IPRE_DRIVER	6
915 
916 /**********************************************************/
917 /*                     INTERFACE                          */
918 /**********************************************************/
919 
920 #define CL22_WR_OVER_CL45(_sc, _phy, _bank, _addr, _val) \
921 	elink_cl45_write(_sc, _phy, \
922 		(_phy)->def_md_devad, \
923 		(_bank + (_addr & 0xf)), \
924 		_val)
925 
926 #define CL22_RD_OVER_CL45(_sc, _phy, _bank, _addr, _val) \
927 	elink_cl45_read(_sc, _phy, \
928 		(_phy)->def_md_devad, \
929 		(_bank + (_addr & 0xf)), \
930 		_val)
931 
932 static elink_status_t elink_check_half_open_conn(struct elink_params *params,
933 				      struct elink_vars *vars, uint8_t notify);
934 static elink_status_t elink_sfp_module_detection(struct elink_phy *phy,
935 				      struct elink_params *params);
936 
elink_bits_en(struct bnx2x_softc * sc,uint32_t reg,uint32_t bits)937 static uint32_t elink_bits_en(struct bnx2x_softc *sc, uint32_t reg, uint32_t bits)
938 {
939 	uint32_t val = REG_RD(sc, reg);
940 
941 	val |= bits;
942 	REG_WR(sc, reg, val);
943 	return val;
944 }
945 
elink_bits_dis(struct bnx2x_softc * sc,uint32_t reg,uint32_t bits)946 static uint32_t elink_bits_dis(struct bnx2x_softc *sc, uint32_t reg,
947 			       uint32_t bits)
948 {
949 	uint32_t val = REG_RD(sc, reg);
950 
951 	val &= ~bits;
952 	REG_WR(sc, reg, val);
953 	return val;
954 }
955 
956 /*
957  * elink_check_lfa - This function checks if link reinitialization is required,
958  *                   or link flap can be avoided.
959  *
960  * @params:	link parameters
961  * Returns 0 if Link Flap Avoidance conditions are met otherwise, the failed
962  *         condition code.
963  */
elink_check_lfa(struct elink_params * params)964 static int elink_check_lfa(struct elink_params *params)
965 {
966 	uint32_t link_status, cfg_idx, lfa_mask, cfg_size;
967 	uint32_t cur_speed_cap_mask, cur_req_fc_auto_adv, additional_config;
968 	uint32_t saved_val, req_val, eee_status;
969 	struct bnx2x_softc *sc = params->sc;
970 
971 	additional_config =
972 		REG_RD(sc, params->lfa_base +
973 			   offsetof(struct shmem_lfa, additional_config));
974 
975 	/* NOTE: must be first condition checked -
976 	* to verify DCC bit is cleared in any case!
977 	*/
978 	if (additional_config & NO_LFA_DUE_TO_DCC_MASK) {
979 		ELINK_DEBUG_P0(sc, "No LFA due to DCC flap after clp exit");
980 		REG_WR(sc, params->lfa_base +
981 			   offsetof(struct shmem_lfa, additional_config),
982 		       additional_config & ~NO_LFA_DUE_TO_DCC_MASK);
983 		return LFA_DCC_LFA_DISABLED;
984 	}
985 
986 	/* Verify that link is up */
987 	link_status = REG_RD(sc, params->shmem_base +
988 			     offsetof(struct shmem_region,
989 				      port_mb[params->port].link_status));
990 	if (!(link_status & LINK_STATUS_LINK_UP))
991 		return LFA_LINK_DOWN;
992 
993 	/* if loaded after BOOT from SAN, don't flap the link in any case and
994 	 * rely on link set by preboot driver
995 	 */
996 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_BOOT_FROM_SAN)
997 		return 0;
998 
999 	/* Verify that loopback mode is not set */
1000 	if (params->loopback_mode)
1001 		return LFA_LOOPBACK_ENABLED;
1002 
1003 	/* Verify that MFW supports LFA */
1004 	if (!params->lfa_base)
1005 		return LFA_MFW_IS_TOO_OLD;
1006 
1007 	if (params->num_phys == 3) {
1008 		cfg_size = 2;
1009 		lfa_mask = 0xffffffff;
1010 	} else {
1011 		cfg_size = 1;
1012 		lfa_mask = 0xffff;
1013 	}
1014 
1015 	/* Compare Duplex */
1016 	saved_val = REG_RD(sc, params->lfa_base +
1017 			   offsetof(struct shmem_lfa, req_duplex));
1018 	req_val = params->req_duplex[0] | (params->req_duplex[1] << 16);
1019 	if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
1020 		ELINK_DEBUG_P2(sc, "Duplex mismatch %x vs. %x",
1021 			       (saved_val & lfa_mask), (req_val & lfa_mask));
1022 		return LFA_DUPLEX_MISMATCH;
1023 	}
1024 	/* Compare Flow Control */
1025 	saved_val = REG_RD(sc, params->lfa_base +
1026 			   offsetof(struct shmem_lfa, req_flow_ctrl));
1027 	req_val = params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16);
1028 	if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
1029 		ELINK_DEBUG_P2(sc, "Flow control mismatch %x vs. %x",
1030 			       (saved_val & lfa_mask), (req_val & lfa_mask));
1031 		return LFA_FLOW_CTRL_MISMATCH;
1032 	}
1033 	/* Compare Link Speed */
1034 	saved_val = REG_RD(sc, params->lfa_base +
1035 			   offsetof(struct shmem_lfa, req_line_speed));
1036 	req_val = params->req_line_speed[0] | (params->req_line_speed[1] << 16);
1037 	if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
1038 		ELINK_DEBUG_P2(sc, "Link speed mismatch %x vs. %x",
1039 			       (saved_val & lfa_mask), (req_val & lfa_mask));
1040 		return LFA_LINK_SPEED_MISMATCH;
1041 	}
1042 
1043 	for (cfg_idx = 0; cfg_idx < cfg_size; cfg_idx++) {
1044 		cur_speed_cap_mask = REG_RD(sc, params->lfa_base +
1045 					    offsetof(struct shmem_lfa,
1046 						     speed_cap_mask[cfg_idx]));
1047 
1048 		if (cur_speed_cap_mask != params->speed_cap_mask[cfg_idx]) {
1049 			ELINK_DEBUG_P2(sc, "Speed Cap mismatch %x vs. %x",
1050 				       cur_speed_cap_mask,
1051 				       params->speed_cap_mask[cfg_idx]);
1052 			return LFA_SPEED_CAP_MISMATCH;
1053 		}
1054 	}
1055 
1056 	cur_req_fc_auto_adv =
1057 		REG_RD(sc, params->lfa_base +
1058 		       offsetof(struct shmem_lfa, additional_config)) &
1059 		REQ_FC_AUTO_ADV_MASK;
1060 
1061 	if ((uint16_t)cur_req_fc_auto_adv != params->req_fc_auto_adv) {
1062 		ELINK_DEBUG_P2(sc, "Flow Ctrl AN mismatch %x vs. %x",
1063 			       cur_req_fc_auto_adv, params->req_fc_auto_adv);
1064 		return LFA_FLOW_CTRL_MISMATCH;
1065 	}
1066 
1067 	eee_status = REG_RD(sc, params->shmem2_base +
1068 			    offsetof(struct shmem2_region,
1069 				     eee_status[params->port]));
1070 
1071 	if (((eee_status & SHMEM_EEE_LPI_REQUESTED_BIT) ^
1072 	     (params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)) ||
1073 	    ((eee_status & SHMEM_EEE_REQUESTED_BIT) ^
1074 	     (params->eee_mode & ELINK_EEE_MODE_ADV_LPI))) {
1075 		ELINK_DEBUG_P2(sc, "EEE mismatch %x vs. %x", params->eee_mode,
1076 			       eee_status);
1077 		return LFA_EEE_MISMATCH;
1078 	}
1079 
1080 	/* LFA conditions are met */
1081 	return 0;
1082 }
1083 /******************************************************************/
1084 /*			EPIO/GPIO section			  */
1085 /******************************************************************/
elink_get_epio(struct bnx2x_softc * sc,uint32_t epio_pin,uint32_t * en)1086 static void elink_get_epio(struct bnx2x_softc *sc, uint32_t epio_pin,
1087 			   uint32_t *en)
1088 {
1089 	uint32_t epio_mask, gp_oenable;
1090 	*en = 0;
1091 	/* Sanity check */
1092 	if (epio_pin > 31) {
1093 		ELINK_DEBUG_P1(sc, "Invalid EPIO pin %d to get", epio_pin);
1094 		return;
1095 	}
1096 
1097 	epio_mask = 1 << epio_pin;
1098 	/* Set this EPIO to output */
1099 	gp_oenable = REG_RD(sc, MCP_REG_MCPR_GP_OENABLE);
1100 	REG_WR(sc, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask);
1101 
1102 	*en = (REG_RD(sc, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin;
1103 }
elink_set_epio(struct bnx2x_softc * sc,uint32_t epio_pin,uint32_t en)1104 static void elink_set_epio(struct bnx2x_softc *sc, uint32_t epio_pin, uint32_t en)
1105 {
1106 	uint32_t epio_mask, gp_output, gp_oenable;
1107 
1108 	/* Sanity check */
1109 	if (epio_pin > 31) {
1110 		ELINK_DEBUG_P1(sc, "Invalid EPIO pin %d to set", epio_pin);
1111 		return;
1112 	}
1113 	ELINK_DEBUG_P2(sc, "Setting EPIO pin %d to %d", epio_pin, en);
1114 	epio_mask = 1 << epio_pin;
1115 	/* Set this EPIO to output */
1116 	gp_output = REG_RD(sc, MCP_REG_MCPR_GP_OUTPUTS);
1117 	if (en)
1118 		gp_output |= epio_mask;
1119 	else
1120 		gp_output &= ~epio_mask;
1121 
1122 	REG_WR(sc, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
1123 
1124 	/* Set the value for this EPIO */
1125 	gp_oenable = REG_RD(sc, MCP_REG_MCPR_GP_OENABLE);
1126 	REG_WR(sc, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
1127 }
1128 
elink_set_cfg_pin(struct bnx2x_softc * sc,uint32_t pin_cfg,uint32_t val)1129 static void elink_set_cfg_pin(struct bnx2x_softc *sc, uint32_t pin_cfg,
1130 			      uint32_t val)
1131 {
1132 	if (pin_cfg == PIN_CFG_NA)
1133 		return;
1134 	if (pin_cfg >= PIN_CFG_EPIO0) {
1135 		elink_set_epio(sc, pin_cfg - PIN_CFG_EPIO0, val);
1136 	} else {
1137 		uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
1138 		uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
1139 		elink_cb_gpio_write(sc, gpio_num, (uint8_t)val, gpio_port);
1140 	}
1141 }
1142 
elink_get_cfg_pin(struct bnx2x_softc * sc,uint32_t pin_cfg,uint32_t * val)1143 static uint32_t elink_get_cfg_pin(struct bnx2x_softc *sc, uint32_t pin_cfg,
1144 				  uint32_t *val)
1145 {
1146 	if (pin_cfg == PIN_CFG_NA)
1147 		return ELINK_STATUS_ERROR;
1148 	if (pin_cfg >= PIN_CFG_EPIO0) {
1149 		elink_get_epio(sc, pin_cfg - PIN_CFG_EPIO0, val);
1150 	} else {
1151 		uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
1152 		uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
1153 		*val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
1154 	}
1155 	return ELINK_STATUS_OK;
1156 }
1157 
1158 /******************************************************************/
1159 /*				ETS section			  */
1160 /******************************************************************/
elink_ets_e2e3a0_disabled(struct elink_params * params)1161 static void elink_ets_e2e3a0_disabled(struct elink_params *params)
1162 {
1163 	/* ETS disabled configuration*/
1164 	struct bnx2x_softc *sc = params->sc;
1165 
1166 	ELINK_DEBUG_P0(sc, "ETS E2E3 disabled configuration");
1167 
1168 	/* mapping between entry  priority to client number (0,1,2 -debug and
1169 	 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
1170 	 * 3bits client num.
1171 	 *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1172 	 * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
1173 	 */
1174 
1175 	REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
1176 	/* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1177 	 * as strict.  Bits 0,1,2 - debug and management entries, 3 -
1178 	 * COS0 entry, 4 - COS1 entry.
1179 	 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
1180 	 * bit4   bit3	  bit2   bit1	  bit0
1181 	 * MCP and debug are strict
1182 	 */
1183 
1184 	REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
1185 	/* defines which entries (clients) are subjected to WFQ arbitration */
1186 	REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
1187 	/* For strict priority entries defines the number of consecutive
1188 	 * slots for the highest priority.
1189 	 */
1190 	REG_WR(sc, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1191 	/* mapping between the CREDIT_WEIGHT registers and actual client
1192 	 * numbers
1193 	 */
1194 	REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
1195 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
1196 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
1197 
1198 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
1199 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
1200 	REG_WR(sc, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
1201 	/* ETS mode disable */
1202 	REG_WR(sc, PBF_REG_ETS_ENABLED, 0);
1203 	/* If ETS mode is enabled (there is no strict priority) defines a WFQ
1204 	 * weight for COS0/COS1.
1205 	 */
1206 	REG_WR(sc, PBF_REG_COS0_WEIGHT, 0x2710);
1207 	REG_WR(sc, PBF_REG_COS1_WEIGHT, 0x2710);
1208 	/* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
1209 	REG_WR(sc, PBF_REG_COS0_UPPER_BOUND, 0x989680);
1210 	REG_WR(sc, PBF_REG_COS1_UPPER_BOUND, 0x989680);
1211 	/* Defines the number of consecutive slots for the strict priority */
1212 	REG_WR(sc, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1213 }
1214 /******************************************************************************
1215  * Description:
1216  *	Getting min_w_val will be set according to line speed .
1217  *.
1218  ******************************************************************************/
elink_ets_get_min_w_val_nig(const struct elink_vars * vars)1219 static uint32_t elink_ets_get_min_w_val_nig(const struct elink_vars *vars)
1220 {
1221 	uint32_t min_w_val = 0;
1222 	/* Calculate min_w_val.*/
1223 	if (vars->link_up) {
1224 		if (vars->line_speed == ELINK_SPEED_20000)
1225 			min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
1226 		else
1227 			min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS;
1228 	} else {
1229 		min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
1230 	}
1231 	/* If the link isn't up (static configuration for example ) The
1232 	 * link will be according to 20GBPS.
1233 	 */
1234 	return min_w_val;
1235 }
1236 /******************************************************************************
1237  * Description:
1238  *	Getting credit upper bound form min_w_val.
1239  *.
1240  ******************************************************************************/
elink_ets_get_credit_upper_bound(const uint32_t min_w_val)1241 static uint32_t elink_ets_get_credit_upper_bound(const uint32_t min_w_val)
1242 {
1243 	const uint32_t credit_upper_bound = (uint32_t)
1244 						ELINK_MAXVAL((150 * min_w_val),
1245 							ELINK_MAX_PACKET_SIZE);
1246 	return credit_upper_bound;
1247 }
1248 /******************************************************************************
1249  * Description:
1250  *	Set credit upper bound for NIG.
1251  *.
1252  ******************************************************************************/
elink_ets_e3b0_set_credit_upper_bound_nig(const struct elink_params * params,const uint32_t min_w_val)1253 static void elink_ets_e3b0_set_credit_upper_bound_nig(
1254 	const struct elink_params *params,
1255 	const uint32_t min_w_val)
1256 {
1257 	struct bnx2x_softc *sc = params->sc;
1258 	const uint8_t port = params->port;
1259 	const uint32_t credit_upper_bound =
1260 	    elink_ets_get_credit_upper_bound(min_w_val);
1261 
1262 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 :
1263 		NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound);
1264 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 :
1265 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound);
1266 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 :
1267 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound);
1268 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 :
1269 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound);
1270 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 :
1271 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound);
1272 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 :
1273 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound);
1274 
1275 	if (!port) {
1276 		REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6,
1277 			credit_upper_bound);
1278 		REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7,
1279 			credit_upper_bound);
1280 		REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8,
1281 			credit_upper_bound);
1282 	}
1283 }
1284 /******************************************************************************
1285  * Description:
1286  *	Will return the NIG ETS registers to init values.Except
1287  *	credit_upper_bound.
1288  *	That isn't used in this configuration (No WFQ is enabled) and will be
1289  *	configured according to spec
1290  *.
1291  ******************************************************************************/
elink_ets_e3b0_nig_disabled(const struct elink_params * params,const struct elink_vars * vars)1292 static void elink_ets_e3b0_nig_disabled(const struct elink_params *params,
1293 					const struct elink_vars *vars)
1294 {
1295 	struct bnx2x_softc *sc = params->sc;
1296 	const uint8_t port = params->port;
1297 	const uint32_t min_w_val = elink_ets_get_min_w_val_nig(vars);
1298 	/* Mapping between entry  priority to client number (0,1,2 -debug and
1299 	 * management clients, 3 - COS0 client, 4 - COS1, ... 8 -
1300 	 * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
1301 	 * reset value or init tool
1302 	 */
1303 	if (port) {
1304 		REG_WR(sc, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210);
1305 		REG_WR(sc, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0);
1306 	} else {
1307 		REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210);
1308 		REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8);
1309 	}
1310 	/* For strict priority entries defines the number of consecutive
1311 	 * slots for the highest priority.
1312 	 */
1313 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
1314 		   NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1315 	/* Mapping between the CREDIT_WEIGHT registers and actual client
1316 	 * numbers
1317 	 */
1318 	if (port) {
1319 		/*Port 1 has 6 COS*/
1320 		REG_WR(sc, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543);
1321 		REG_WR(sc, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0);
1322 	} else {
1323 		/*Port 0 has 9 COS*/
1324 		REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB,
1325 		       0x43210876);
1326 		REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5);
1327 	}
1328 
1329 	/* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1330 	 * as strict.  Bits 0,1,2 - debug and management entries, 3 -
1331 	 * COS0 entry, 4 - COS1 entry.
1332 	 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
1333 	 * bit4   bit3	  bit2   bit1	  bit0
1334 	 * MCP and debug are strict
1335 	 */
1336 	if (port)
1337 		REG_WR(sc, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f);
1338 	else
1339 		REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff);
1340 	/* defines which entries (clients) are subjected to WFQ arbitration */
1341 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
1342 		   NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
1343 
1344 	/* Please notice the register address are note continuous and a
1345 	 * for here is note appropriate.In 2 port mode port0 only COS0-5
1346 	 * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
1347 	 * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
1348 	 * are never used for WFQ
1349 	 */
1350 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
1351 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0);
1352 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
1353 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0);
1354 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
1355 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0);
1356 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 :
1357 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0);
1358 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 :
1359 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0);
1360 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 :
1361 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0);
1362 	if (!port) {
1363 		REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0);
1364 		REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0);
1365 		REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0);
1366 	}
1367 
1368 	elink_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val);
1369 }
1370 /******************************************************************************
1371  * Description:
1372  *	Set credit upper bound for PBF.
1373  *.
1374  ******************************************************************************/
elink_ets_e3b0_set_credit_upper_bound_pbf(const struct elink_params * params,const uint32_t min_w_val)1375 static void elink_ets_e3b0_set_credit_upper_bound_pbf(
1376 	const struct elink_params *params,
1377 	const uint32_t min_w_val)
1378 {
1379 	struct bnx2x_softc *sc = params->sc;
1380 	const uint32_t credit_upper_bound =
1381 	    elink_ets_get_credit_upper_bound(min_w_val);
1382 	const uint8_t port = params->port;
1383 	uint32_t base_upper_bound = 0;
1384 	uint8_t max_cos = 0;
1385 	uint8_t i = 0;
1386 	/* In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
1387 	 * port mode port1 has COS0-2 that can be used for WFQ.
1388 	 */
1389 	if (!port) {
1390 		base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0;
1391 		max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1392 	} else {
1393 		base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1;
1394 		max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1;
1395 	}
1396 
1397 	for (i = 0; i < max_cos; i++)
1398 		REG_WR(sc, base_upper_bound + (i << 2), credit_upper_bound);
1399 }
1400 
1401 /******************************************************************************
1402  * Description:
1403  *	Will return the PBF ETS registers to init values.Except
1404  *	credit_upper_bound.
1405  *	That isn't used in this configuration (No WFQ is enabled) and will be
1406  *	configured according to spec
1407  *.
1408  ******************************************************************************/
elink_ets_e3b0_pbf_disabled(const struct elink_params * params)1409 static void elink_ets_e3b0_pbf_disabled(const struct elink_params *params)
1410 {
1411 	struct bnx2x_softc *sc = params->sc;
1412 	const uint8_t port = params->port;
1413 	const uint32_t min_w_val_pbf = ELINK_ETS_E3B0_PBF_MIN_W_VAL;
1414 	uint8_t i = 0;
1415 	uint32_t base_weight = 0;
1416 	uint8_t max_cos = 0;
1417 
1418 	/* Mapping between entry  priority to client number 0 - COS0
1419 	 * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
1420 	 * TODO_ETS - Should be done by reset value or init tool
1421 	 */
1422 	if (port)
1423 		/*  0x688 (|011|0 10|00 1|000) */
1424 		REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1, 0x688);
1425 	else
1426 		/*  (10 1|100 |011|0 10|00 1|000) */
1427 		REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0, 0x2C688);
1428 
1429 	/* TODO_ETS - Should be done by reset value or init tool */
1430 	if (port)
1431 		/* 0x688 (|011|0 10|00 1|000)*/
1432 		REG_WR(sc, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688);
1433 	else
1434 	/* 0x2C688 (10 1|100 |011|0 10|00 1|000) */
1435 	REG_WR(sc, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688);
1436 
1437 	REG_WR(sc, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 :
1438 		   PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0, 0x100);
1439 
1440 
1441 	REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
1442 		   PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0, 0);
1443 
1444 	REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
1445 		   PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0, 0);
1446 	/* In 2 port mode port0 has COS0-5 that can be used for WFQ.
1447 	 * In 4 port mode port1 has COS0-2 that can be used for WFQ.
1448 	 */
1449 	if (!port) {
1450 		base_weight = PBF_REG_COS0_WEIGHT_P0;
1451 		max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1452 	} else {
1453 		base_weight = PBF_REG_COS0_WEIGHT_P1;
1454 		max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1;
1455 	}
1456 
1457 	for (i = 0; i < max_cos; i++)
1458 		REG_WR(sc, base_weight + (0x4 * i), 0);
1459 
1460 	elink_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1461 }
1462 /******************************************************************************
1463  * Description:
1464  *	E3B0 disable will return basically the values to init values.
1465  *.
1466  ******************************************************************************/
elink_ets_e3b0_disabled(const struct elink_params * params,const struct elink_vars * vars)1467 static elink_status_t elink_ets_e3b0_disabled(const struct elink_params *params,
1468 				   const struct elink_vars *vars)
1469 {
1470 	struct bnx2x_softc *sc = params->sc;
1471 
1472 	if (!CHIP_IS_E3B0(sc)) {
1473 		ELINK_DEBUG_P0(sc,
1474 		   "elink_ets_e3b0_disabled the chip isn't E3B0");
1475 		return ELINK_STATUS_ERROR;
1476 	}
1477 
1478 	elink_ets_e3b0_nig_disabled(params, vars);
1479 
1480 	elink_ets_e3b0_pbf_disabled(params);
1481 
1482 	return ELINK_STATUS_OK;
1483 }
1484 
1485 /******************************************************************************
1486  * Description:
1487  *	Disable will return basically the values to init values.
1488  *
1489  ******************************************************************************/
elink_ets_disabled(struct elink_params * params,struct elink_vars * vars)1490 elink_status_t elink_ets_disabled(struct elink_params *params,
1491 		      struct elink_vars *vars)
1492 {
1493 	struct bnx2x_softc *sc = params->sc;
1494 	elink_status_t elink_status = ELINK_STATUS_OK;
1495 
1496 	if ((CHIP_IS_E2(sc)) || (CHIP_IS_E3A0(sc))) {
1497 		elink_ets_e2e3a0_disabled(params);
1498 	} else if (CHIP_IS_E3B0(sc)) {
1499 		elink_status = elink_ets_e3b0_disabled(params, vars);
1500 	} else {
1501 		ELINK_DEBUG_P0(sc, "elink_ets_disabled - chip not supported");
1502 		return ELINK_STATUS_ERROR;
1503 	}
1504 
1505 	return elink_status;
1506 }
1507 
1508 /******************************************************************************
1509  * Description
1510  *	Set the COS mapping to SP and BW until this point all the COS are not
1511  *	set as SP or BW.
1512  ******************************************************************************/
elink_ets_e3b0_cli_map(const struct elink_params * params,__rte_unused const struct elink_ets_params * ets_params,const uint8_t cos_sp_bitmap,const uint8_t cos_bw_bitmap)1513 static elink_status_t elink_ets_e3b0_cli_map(const struct elink_params *params,
1514 		  __rte_unused const struct elink_ets_params *ets_params,
1515 		  const uint8_t cos_sp_bitmap,
1516 		  const uint8_t cos_bw_bitmap)
1517 {
1518 	struct bnx2x_softc *sc = params->sc;
1519 	const uint8_t port = params->port;
1520 	const uint8_t nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3);
1521 	const uint8_t pbf_cli_sp_bitmap = cos_sp_bitmap;
1522 	const uint8_t nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3;
1523 	const uint8_t pbf_cli_subject2wfq_bitmap = cos_bw_bitmap;
1524 
1525 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT :
1526 	       NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap);
1527 
1528 	REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
1529 	       PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0, pbf_cli_sp_bitmap);
1530 
1531 	REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
1532 	       NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ,
1533 	       nig_cli_subject2wfq_bitmap);
1534 
1535 	REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
1536 	       PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0,
1537 	       pbf_cli_subject2wfq_bitmap);
1538 
1539 	return ELINK_STATUS_OK;
1540 }
1541 
1542 /******************************************************************************
1543  * Description:
1544  *	This function is needed because NIG ARB_CREDIT_WEIGHT_X are
1545  *	not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
1546  ******************************************************************************/
elink_ets_e3b0_set_cos_bw(struct bnx2x_softc * sc,const uint8_t cos_entry,const uint32_t min_w_val_nig,const uint32_t min_w_val_pbf,const uint16_t total_bw,const uint8_t bw,const uint8_t port)1547 static elink_status_t elink_ets_e3b0_set_cos_bw(struct bnx2x_softc *sc,
1548 				     const uint8_t cos_entry,
1549 				     const uint32_t min_w_val_nig,
1550 				     const uint32_t min_w_val_pbf,
1551 				     const uint16_t total_bw,
1552 				     const uint8_t bw,
1553 				     const uint8_t port)
1554 {
1555 	uint32_t nig_reg_address_crd_weight = 0;
1556 	uint32_t pbf_reg_address_crd_weight = 0;
1557 	/* Calculate and set BW for this COS - use 1 instead of 0 for BW */
1558 	const uint32_t cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw;
1559 	const uint32_t cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw;
1560 
1561 	switch (cos_entry) {
1562 	case 0:
1563 	    nig_reg_address_crd_weight =
1564 		 (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
1565 		     NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0;
1566 	     pbf_reg_address_crd_weight = (port) ?
1567 		 PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0;
1568 		break;
1569 	case 1:
1570 	     nig_reg_address_crd_weight = (port) ?
1571 		 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
1572 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1;
1573 	     pbf_reg_address_crd_weight = (port) ?
1574 		 PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0;
1575 		break;
1576 	case 2:
1577 	     nig_reg_address_crd_weight = (port) ?
1578 		 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
1579 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2;
1580 
1581 		 pbf_reg_address_crd_weight = (port) ?
1582 		     PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0;
1583 		break;
1584 	case 3:
1585 		if (port)
1586 			return ELINK_STATUS_ERROR;
1587 		nig_reg_address_crd_weight =
1588 			NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3;
1589 		pbf_reg_address_crd_weight =
1590 			PBF_REG_COS3_WEIGHT_P0;
1591 		break;
1592 	case 4:
1593 		if (port)
1594 		return ELINK_STATUS_ERROR;
1595 	     nig_reg_address_crd_weight =
1596 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4;
1597 	     pbf_reg_address_crd_weight = PBF_REG_COS4_WEIGHT_P0;
1598 		break;
1599 	case 5:
1600 		if (port)
1601 		return ELINK_STATUS_ERROR;
1602 	     nig_reg_address_crd_weight =
1603 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5;
1604 	     pbf_reg_address_crd_weight = PBF_REG_COS5_WEIGHT_P0;
1605 		break;
1606 	}
1607 
1608 	REG_WR(sc, nig_reg_address_crd_weight, cos_bw_nig);
1609 
1610 	REG_WR(sc, pbf_reg_address_crd_weight, cos_bw_pbf);
1611 
1612 	return ELINK_STATUS_OK;
1613 }
1614 /******************************************************************************
1615  * Description:
1616  *	Calculate the total BW.A value of 0 isn't legal.
1617  *
1618  ******************************************************************************/
elink_ets_e3b0_get_total_bw(const struct elink_params * params,struct elink_ets_params * ets_params,uint16_t * total_bw)1619 static elink_status_t elink_ets_e3b0_get_total_bw(
1620 	const struct elink_params *params,
1621 	struct elink_ets_params *ets_params,
1622 	uint16_t *total_bw)
1623 {
1624 	struct bnx2x_softc *sc = params->sc;
1625 	uint8_t cos_idx = 0;
1626 	uint8_t is_bw_cos_exist = 0;
1627 
1628 	*total_bw = 0;
1629 	/* Calculate total BW requested */
1630 	for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
1631 		if (ets_params->cos[cos_idx].state == elink_cos_state_bw) {
1632 			is_bw_cos_exist = 1;
1633 			if (!ets_params->cos[cos_idx].params.bw_params.bw) {
1634 				ELINK_DEBUG_P0(sc, "elink_ets_E3B0_config BW"
1635 						   " was set to 0");
1636 				/* This is to prevent a state when ramrods
1637 				 * can't be sent
1638 				 */
1639 				ets_params->cos[cos_idx].params.bw_params.bw
1640 					 = 1;
1641 			}
1642 			*total_bw +=
1643 				ets_params->cos[cos_idx].params.bw_params.bw;
1644 		}
1645 	}
1646 
1647 	/* Check total BW is valid */
1648 	if ((is_bw_cos_exist == 1) && (*total_bw != 100)) {
1649 		if (*total_bw == 0) {
1650 			ELINK_DEBUG_P0(sc,
1651 			   "elink_ets_E3B0_config total BW shouldn't be 0");
1652 			return ELINK_STATUS_ERROR;
1653 		}
1654 		ELINK_DEBUG_P0(sc,
1655 		   "elink_ets_E3B0_config total BW should be 100");
1656 		/* We can handle a case where the BW isn't 100 this can happen
1657 		 * if the TC are joined.
1658 		 */
1659 	}
1660 	return ELINK_STATUS_OK;
1661 }
1662 
1663 /******************************************************************************
1664  * Description:
1665  *	Invalidate all the sp_pri_to_cos.
1666  *
1667  ******************************************************************************/
elink_ets_e3b0_sp_pri_to_cos_init(uint8_t * sp_pri_to_cos)1668 static void elink_ets_e3b0_sp_pri_to_cos_init(uint8_t *sp_pri_to_cos)
1669 {
1670 	uint8_t pri = 0;
1671 	for (pri = 0; pri < ELINK_DCBX_MAX_NUM_COS; pri++)
1672 		sp_pri_to_cos[pri] = DCBX_INVALID_COS;
1673 }
1674 /******************************************************************************
1675  * Description:
1676  *	Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1677  *	according to sp_pri_to_cos.
1678  *
1679  ******************************************************************************/
elink_ets_e3b0_sp_pri_to_cos_set(const struct elink_params * params,uint8_t * sp_pri_to_cos,const uint8_t pri,const uint8_t cos_entry)1680 static elink_status_t elink_ets_e3b0_sp_pri_to_cos_set(
1681 					    const struct elink_params *params,
1682 					    uint8_t *sp_pri_to_cos,
1683 					    const uint8_t pri,
1684 					    const uint8_t cos_entry)
1685 {
1686 	struct bnx2x_softc *sc = params->sc;
1687 	const uint8_t port = params->port;
1688 	const uint8_t max_num_of_cos = (port) ?
1689 		ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1690 		ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1691 
1692 	if (pri >= max_num_of_cos) {
1693 		ELINK_DEBUG_P0(sc, "elink_ets_e3b0_sp_pri_to_cos_set invalid "
1694 		   "parameter Illegal strict priority");
1695 		return ELINK_STATUS_ERROR;
1696 	}
1697 
1698 	if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {
1699 		ELINK_DEBUG_P0(sc, "elink_ets_e3b0_sp_pri_to_cos_set invalid "
1700 				   "parameter There can't be two COS's with "
1701 				   "the same strict pri");
1702 		return ELINK_STATUS_ERROR;
1703 	}
1704 
1705 	sp_pri_to_cos[pri] = cos_entry;
1706 	return ELINK_STATUS_OK;
1707 }
1708 
1709 /******************************************************************************
1710  * Description:
1711  *	Returns the correct value according to COS and priority in
1712  *	the sp_pri_cli register.
1713  *
1714  ******************************************************************************/
elink_e3b0_sp_get_pri_cli_reg(const uint8_t cos,const uint8_t cos_offset,const uint8_t pri_set,const uint8_t pri_offset,const uint8_t entry_size)1715 static uint64_t elink_e3b0_sp_get_pri_cli_reg(const uint8_t cos,
1716 					 const uint8_t cos_offset,
1717 					 const uint8_t pri_set,
1718 					 const uint8_t pri_offset,
1719 					 const uint8_t entry_size)
1720 {
1721 	uint64_t pri_cli_nig = 0;
1722 	pri_cli_nig = ((uint64_t)(cos + cos_offset)) << (entry_size *
1723 						    (pri_set + pri_offset));
1724 
1725 	return pri_cli_nig;
1726 }
1727 /******************************************************************************
1728  * Description:
1729  *	Returns the correct value according to COS and priority in the
1730  *	sp_pri_cli register for NIG.
1731  *
1732  ******************************************************************************/
elink_e3b0_sp_get_pri_cli_reg_nig(const uint8_t cos,const uint8_t pri_set)1733 static uint64_t elink_e3b0_sp_get_pri_cli_reg_nig(const uint8_t cos,
1734 						  const uint8_t pri_set)
1735 {
1736 	/* MCP Dbg0 and dbg1 are always with higher strict pri*/
1737 	const uint8_t nig_cos_offset = 3;
1738 	const uint8_t nig_pri_offset = 3;
1739 
1740 	return elink_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set,
1741 		nig_pri_offset, 4);
1742 }
1743 
1744 /******************************************************************************
1745  * Description:
1746  *	Returns the correct value according to COS and priority in the
1747  *	sp_pri_cli register for PBF.
1748  *
1749  ******************************************************************************/
elink_e3b0_sp_get_pri_cli_reg_pbf(const uint8_t cos,const uint8_t pri_set)1750 static uint64_t elink_e3b0_sp_get_pri_cli_reg_pbf(const uint8_t cos,
1751 						  const uint8_t pri_set)
1752 {
1753 	const uint8_t pbf_cos_offset = 0;
1754 	const uint8_t pbf_pri_offset = 0;
1755 
1756 	return elink_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set,
1757 		pbf_pri_offset, 3);
1758 }
1759 
1760 /******************************************************************************
1761  * Description:
1762  *	Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1763  *	according to sp_pri_to_cos.(which COS has higher priority)
1764  *
1765  ******************************************************************************/
elink_ets_e3b0_sp_set_pri_cli_reg(const struct elink_params * params,uint8_t * sp_pri_to_cos)1766 static elink_status_t elink_ets_e3b0_sp_set_pri_cli_reg(
1767 					     const struct elink_params *params,
1768 					     uint8_t *sp_pri_to_cos)
1769 {
1770 	struct bnx2x_softc *sc = params->sc;
1771 	uint8_t i = 0;
1772 	const uint8_t port = params->port;
1773 	/* MCP Dbg0 and dbg1 are always with higher strict pri*/
1774 	uint64_t pri_cli_nig = 0x210;
1775 	uint32_t pri_cli_pbf = 0x0;
1776 	uint8_t pri_set = 0;
1777 	uint8_t pri_bitmask = 0;
1778 	const uint8_t max_num_of_cos = (port) ?
1779 		ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1780 		ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1781 
1782 	uint8_t cos_bit_to_set = (1 << max_num_of_cos) - 1;
1783 
1784 	/* Set all the strict priority first */
1785 	for (i = 0; i < max_num_of_cos; i++) {
1786 		if (sp_pri_to_cos[i] != DCBX_INVALID_COS) {
1787 			if (sp_pri_to_cos[i] >= ELINK_DCBX_MAX_NUM_COS) {
1788 				ELINK_DEBUG_P0(sc,
1789 					   "elink_ets_e3b0_sp_set_pri_cli_reg "
1790 					   "invalid cos entry");
1791 				return ELINK_STATUS_ERROR;
1792 			}
1793 
1794 			pri_cli_nig |= elink_e3b0_sp_get_pri_cli_reg_nig(
1795 			    sp_pri_to_cos[i], pri_set);
1796 
1797 			pri_cli_pbf |= elink_e3b0_sp_get_pri_cli_reg_pbf(
1798 			    sp_pri_to_cos[i], pri_set);
1799 			pri_bitmask = 1 << sp_pri_to_cos[i];
1800 			/* COS is used remove it from bitmap.*/
1801 			if (!(pri_bitmask & cos_bit_to_set)) {
1802 				ELINK_DEBUG_P0(sc,
1803 					"elink_ets_e3b0_sp_set_pri_cli_reg "
1804 					"invalid There can't be two COS's with"
1805 					" the same strict pri");
1806 				return ELINK_STATUS_ERROR;
1807 			}
1808 			cos_bit_to_set &= ~pri_bitmask;
1809 			pri_set++;
1810 		}
1811 	}
1812 
1813 	/* Set all the Non strict priority i= COS*/
1814 	for (i = 0; i < max_num_of_cos; i++) {
1815 		pri_bitmask = 1 << i;
1816 		/* Check if COS was already used for SP */
1817 		if (pri_bitmask & cos_bit_to_set) {
1818 			/* COS wasn't used for SP */
1819 			pri_cli_nig |= elink_e3b0_sp_get_pri_cli_reg_nig(
1820 			    i, pri_set);
1821 
1822 			pri_cli_pbf |= elink_e3b0_sp_get_pri_cli_reg_pbf(
1823 			    i, pri_set);
1824 			/* COS is used remove it from bitmap.*/
1825 			cos_bit_to_set &= ~pri_bitmask;
1826 			pri_set++;
1827 		}
1828 	}
1829 
1830 	if (pri_set != max_num_of_cos) {
1831 		ELINK_DEBUG_P0(sc, "elink_ets_e3b0_sp_set_pri_cli_reg not all "
1832 				   "entries were set");
1833 		return ELINK_STATUS_ERROR;
1834 	}
1835 
1836 	if (port) {
1837 		/* Only 6 usable clients*/
1838 		REG_WR(sc, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB,
1839 		       (uint32_t)pri_cli_nig);
1840 
1841 		REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1, pri_cli_pbf);
1842 	} else {
1843 		/* Only 9 usable clients*/
1844 		const uint32_t pri_cli_nig_lsb = (uint32_t)(pri_cli_nig);
1845 		const uint32_t pri_cli_nig_msb = (uint32_t)
1846 						((pri_cli_nig >> 32) & 0xF);
1847 
1848 		REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB,
1849 		       pri_cli_nig_lsb);
1850 		REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB,
1851 		       pri_cli_nig_msb);
1852 
1853 		REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0, pri_cli_pbf);
1854 	}
1855 	return ELINK_STATUS_OK;
1856 }
1857 
1858 /******************************************************************************
1859  * Description:
1860  *	Configure the COS to ETS according to BW and SP settings.
1861  ******************************************************************************/
elink_ets_e3b0_config(const struct elink_params * params,const struct elink_vars * vars,struct elink_ets_params * ets_params)1862 elink_status_t elink_ets_e3b0_config(const struct elink_params *params,
1863 			 const struct elink_vars *vars,
1864 			 struct elink_ets_params *ets_params)
1865 {
1866 	struct bnx2x_softc *sc = params->sc;
1867 	elink_status_t elink_status = ELINK_STATUS_OK;
1868 	const uint8_t port = params->port;
1869 	uint16_t total_bw = 0;
1870 	const uint32_t min_w_val_nig = elink_ets_get_min_w_val_nig(vars);
1871 	const uint32_t min_w_val_pbf = ELINK_ETS_E3B0_PBF_MIN_W_VAL;
1872 	uint8_t cos_bw_bitmap = 0;
1873 	uint8_t cos_sp_bitmap = 0;
1874 	uint8_t sp_pri_to_cos[ELINK_DCBX_MAX_NUM_COS] = {0};
1875 	const uint8_t max_num_of_cos = (port) ?
1876 		ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1877 		ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1878 	uint8_t cos_entry = 0;
1879 
1880 	if (!CHIP_IS_E3B0(sc)) {
1881 		ELINK_DEBUG_P0(sc,
1882 		   "elink_ets_e3b0_disabled the chip isn't E3B0");
1883 		return ELINK_STATUS_ERROR;
1884 	}
1885 
1886 	if (ets_params->num_of_cos > max_num_of_cos) {
1887 		ELINK_DEBUG_P0(sc, "elink_ets_E3B0_config the number of COS "
1888 				   "isn't supported");
1889 		return ELINK_STATUS_ERROR;
1890 	}
1891 
1892 	/* Prepare sp strict priority parameters*/
1893 	elink_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos);
1894 
1895 	/* Prepare BW parameters*/
1896 	elink_status = elink_ets_e3b0_get_total_bw(params, ets_params,
1897 						   &total_bw);
1898 	if (elink_status != ELINK_STATUS_OK) {
1899 		ELINK_DEBUG_P0(sc,
1900 		   "elink_ets_E3B0_config get_total_bw failed");
1901 		return ELINK_STATUS_ERROR;
1902 	}
1903 
1904 	/* Upper bound is set according to current link speed (min_w_val
1905 	 * should be the same for upper bound and COS credit val).
1906 	 */
1907 	elink_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
1908 	elink_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1909 
1910 
1911 	for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) {
1912 		if (elink_cos_state_bw == ets_params->cos[cos_entry].state) {
1913 			cos_bw_bitmap |= (1 << cos_entry);
1914 			/* The function also sets the BW in HW(not the mappin
1915 			 * yet)
1916 			 */
1917 			elink_status = elink_ets_e3b0_set_cos_bw(
1918 				sc, cos_entry, min_w_val_nig, min_w_val_pbf,
1919 				total_bw,
1920 				ets_params->cos[cos_entry].params.bw_params.bw,
1921 				 port);
1922 		} else if (elink_cos_state_strict ==
1923 			ets_params->cos[cos_entry].state){
1924 			cos_sp_bitmap |= (1 << cos_entry);
1925 
1926 			elink_status = elink_ets_e3b0_sp_pri_to_cos_set(
1927 				params,
1928 				sp_pri_to_cos,
1929 				ets_params->cos[cos_entry].params.sp_params.pri,
1930 				cos_entry);
1931 
1932 		} else {
1933 			ELINK_DEBUG_P0(sc,
1934 			   "elink_ets_e3b0_config cos state not valid");
1935 			return ELINK_STATUS_ERROR;
1936 		}
1937 		if (elink_status != ELINK_STATUS_OK) {
1938 			ELINK_DEBUG_P0(sc,
1939 			   "elink_ets_e3b0_config set cos bw failed");
1940 			return elink_status;
1941 		}
1942 	}
1943 
1944 	/* Set SP register (which COS has higher priority) */
1945 	elink_status = elink_ets_e3b0_sp_set_pri_cli_reg(params,
1946 							 sp_pri_to_cos);
1947 
1948 	if (elink_status != ELINK_STATUS_OK) {
1949 		ELINK_DEBUG_P0(sc,
1950 		   "elink_ets_E3B0_config set_pri_cli_reg failed");
1951 		return elink_status;
1952 	}
1953 
1954 	/* Set client mapping of BW and strict */
1955 	elink_status = elink_ets_e3b0_cli_map(params, ets_params,
1956 					      cos_sp_bitmap,
1957 					      cos_bw_bitmap);
1958 
1959 	if (elink_status != ELINK_STATUS_OK) {
1960 		ELINK_DEBUG_P0(sc, "elink_ets_E3B0_config SP failed");
1961 		return elink_status;
1962 	}
1963 	return ELINK_STATUS_OK;
1964 }
elink_ets_bw_limit_common(const struct elink_params * params)1965 static void elink_ets_bw_limit_common(const struct elink_params *params)
1966 {
1967 	/* ETS disabled configuration */
1968 	struct bnx2x_softc *sc = params->sc;
1969 	ELINK_DEBUG_P0(sc, "ETS enabled BW limit configuration");
1970 	/* Defines which entries (clients) are subjected to WFQ arbitration
1971 	 * COS0 0x8
1972 	 * COS1 0x10
1973 	 */
1974 	REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
1975 	/* Mapping between the ARB_CREDIT_WEIGHT registers and actual
1976 	 * client numbers (WEIGHT_0 does not actually have to represent
1977 	 * client 0)
1978 	 *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1979 	 *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
1980 	 */
1981 	REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
1982 
1983 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
1984 	       ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1985 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
1986 	       ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1987 
1988 	/* ETS mode enabled*/
1989 	REG_WR(sc, PBF_REG_ETS_ENABLED, 1);
1990 
1991 	/* Defines the number of consecutive slots for the strict priority */
1992 	REG_WR(sc, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1993 	/* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1994 	 * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
1995 	 * entry, 4 - COS1 entry.
1996 	 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1997 	 * bit4   bit3	  bit2     bit1	   bit0
1998 	 * MCP and debug are strict
1999 	 */
2000 	REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
2001 
2002 	/* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
2003 	REG_WR(sc, PBF_REG_COS0_UPPER_BOUND,
2004 	       ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
2005 	REG_WR(sc, PBF_REG_COS1_UPPER_BOUND,
2006 	       ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
2007 }
2008 
elink_ets_bw_limit(const struct elink_params * params,const uint32_t cos0_bw,const uint32_t cos1_bw)2009 void elink_ets_bw_limit(const struct elink_params *params,
2010 			const uint32_t cos0_bw,
2011 			const uint32_t cos1_bw)
2012 {
2013 	/* ETS disabled configuration*/
2014 	struct bnx2x_softc *sc = params->sc;
2015 	const uint32_t total_bw = cos0_bw + cos1_bw;
2016 	uint32_t cos0_credit_weight = 0;
2017 	uint32_t cos1_credit_weight = 0;
2018 
2019 	ELINK_DEBUG_P0(sc, "ETS enabled BW limit configuration");
2020 
2021 	if ((!total_bw) ||
2022 	    (!cos0_bw) ||
2023 	    (!cos1_bw)) {
2024 		ELINK_DEBUG_P0(sc, "Total BW can't be zero");
2025 		return;
2026 	}
2027 
2028 	cos0_credit_weight = (cos0_bw * ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT) /
2029 		total_bw;
2030 	cos1_credit_weight = (cos1_bw * ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT) /
2031 		total_bw;
2032 
2033 	elink_ets_bw_limit_common(params);
2034 
2035 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
2036 	REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
2037 
2038 	REG_WR(sc, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
2039 	REG_WR(sc, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
2040 }
2041 
elink_ets_strict(const struct elink_params * params,const uint8_t strict_cos)2042 elink_status_t elink_ets_strict(const struct elink_params *params,
2043 				const uint8_t strict_cos)
2044 {
2045 	/* ETS disabled configuration*/
2046 	struct bnx2x_softc *sc = params->sc;
2047 	uint32_t val	= 0;
2048 
2049 	ELINK_DEBUG_P0(sc, "ETS enabled strict configuration");
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 /******************************************************************/
elink_update_pfc_xmac(struct elink_params * params,struct elink_vars * vars,__rte_unused uint8_t is_lb)2086 static void elink_update_pfc_xmac(struct elink_params *params,
2087 				  struct elink_vars *vars,
2088 				  __rte_unused uint8_t is_lb)
2089 {
2090 	struct bnx2x_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 
elink_emac_get_pfc_stat(struct elink_params * params,uint32_t pfc_frames_sent[2],uint32_t pfc_frames_received[2])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 bnx2x_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");
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*/
elink_pfc_statistic(struct elink_params * params,struct elink_vars * vars,uint32_t pfc_frames_sent[2],uint32_t pfc_frames_received[2])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 bnx2x_softc *sc = params->sc;
2185 
2186 	ELINK_DEBUG_P0(sc, "pfc statistic");
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");
2193 		elink_emac_get_pfc_stat(params, pfc_frames_sent,
2194 					pfc_frames_received);
2195 	}
2196 }
2197 /******************************************************************/
2198 /*			MAC/PBF section				  */
2199 /******************************************************************/
elink_set_mdio_clk(struct bnx2x_softc * sc,__rte_unused uint32_t chip_id,uint32_t emac_base)2200 static void elink_set_mdio_clk(struct bnx2x_softc *sc,
2201 			       __rte_unused uint32_t chip_id,
2202 			       uint32_t emac_base)
2203 {
2204 	uint32_t new_mode, cur_mode;
2205 	uint32_t clc_cnt;
2206 	/* Set clause 45 mode, slow down the MDIO clock to 2.5MHz
2207 	 * (a value of 49==0x31) and make sure that the AUTO poll is off
2208 	 */
2209 	cur_mode = REG_RD(sc, emac_base + EMAC_REG_EMAC_MDIO_MODE);
2210 
2211 	if (USES_WARPCORE(sc))
2212 		clc_cnt = 74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
2213 	else
2214 		clc_cnt = 49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
2215 
2216 	if (((cur_mode & EMAC_MDIO_MODE_CLOCK_CNT) == clc_cnt) &&
2217 	    (cur_mode & (EMAC_MDIO_MODE_CLAUSE_45)))
2218 		return;
2219 
2220 	new_mode = cur_mode &
2221 		~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
2222 	new_mode |= clc_cnt;
2223 	new_mode |= (EMAC_MDIO_MODE_CLAUSE_45);
2224 
2225 	ELINK_DEBUG_P2(sc, "Changing emac_mode from 0x%x to 0x%x",
2226 	   cur_mode, new_mode);
2227 	REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_MODE, new_mode);
2228 	DELAY(40);
2229 }
2230 
elink_is_4_port_mode(struct bnx2x_softc * sc)2231 static uint8_t elink_is_4_port_mode(struct bnx2x_softc *sc)
2232 {
2233 	uint32_t port4mode_ovwr_val;
2234 	/* Check 4-port override enabled */
2235 	port4mode_ovwr_val = REG_RD(sc, MISC_REG_PORT4MODE_EN_OVWR);
2236 	if (port4mode_ovwr_val & (1 << 0)) {
2237 		/* Return 4-port mode override value */
2238 		return ((port4mode_ovwr_val & (1 << 1)) == (1 << 1));
2239 	}
2240 	/* Return 4-port mode from input pin */
2241 	return (uint8_t)REG_RD(sc, MISC_REG_PORT4MODE_EN);
2242 }
2243 
elink_set_mdio_emac_per_phy(struct bnx2x_softc * sc,struct elink_params * params)2244 static void elink_set_mdio_emac_per_phy(struct bnx2x_softc *sc,
2245 					struct elink_params *params)
2246 {
2247 	uint8_t phy_index;
2248 
2249 	/* Set mdio clock per phy */
2250 	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
2251 	      phy_index++)
2252 		elink_set_mdio_clk(sc, params->chip_id,
2253 				   params->phy[phy_index].mdio_ctrl);
2254 }
2255 
elink_emac_init(struct elink_params * params,__rte_unused struct elink_vars * vars)2256 static void elink_emac_init(struct elink_params *params,
2257 			    __rte_unused struct elink_vars *vars)
2258 {
2259 	/* reset and unreset the emac core */
2260 	struct bnx2x_softc *sc = params->sc;
2261 	uint8_t port = params->port;
2262 	uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2263 	uint32_t val;
2264 	uint16_t timeout;
2265 
2266 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2267 	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
2268 	DELAY(5);
2269 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2270 	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
2271 
2272 	/* init emac - use read-modify-write */
2273 	/* self clear reset */
2274 	val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2275 	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE,
2276 			   (val | EMAC_MODE_RESET));
2277 
2278 	timeout = 200;
2279 	do {
2280 		val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2281 		ELINK_DEBUG_P1(sc, "EMAC reset reg is %u", val);
2282 		if (!timeout) {
2283 			ELINK_DEBUG_P0(sc, "EMAC timeout!");
2284 			return;
2285 		}
2286 		timeout--;
2287 	} while (val & EMAC_MODE_RESET);
2288 
2289 	elink_set_mdio_emac_per_phy(sc, params);
2290 	/* Set mac address */
2291 	val = ((params->mac_addr[0] << 8) |
2292 		params->mac_addr[1]);
2293 	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MAC_MATCH, val);
2294 
2295 	val = ((params->mac_addr[2] << 24) |
2296 	       (params->mac_addr[3] << 16) |
2297 	       (params->mac_addr[4] << 8) |
2298 		params->mac_addr[5]);
2299 	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MAC_MATCH + 4, val);
2300 }
2301 
elink_set_xumac_nig(struct elink_params * params,uint16_t tx_pause_en,uint8_t enable)2302 static void elink_set_xumac_nig(struct elink_params *params,
2303 				uint16_t tx_pause_en,
2304 				uint8_t enable)
2305 {
2306 	struct bnx2x_softc *sc = params->sc;
2307 
2308 	REG_WR(sc, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
2309 	       enable);
2310 	REG_WR(sc, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
2311 	       enable);
2312 	REG_WR(sc, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
2313 	       NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
2314 }
2315 
elink_set_umac_rxtx(struct elink_params * params,uint8_t en)2316 static void elink_set_umac_rxtx(struct elink_params *params, uint8_t en)
2317 {
2318 	uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
2319 	uint32_t val;
2320 	struct bnx2x_softc *sc = params->sc;
2321 	if (!(REG_RD(sc, MISC_REG_RESET_REG_2) &
2322 		   (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)))
2323 		return;
2324 	val = REG_RD(sc, umac_base + UMAC_REG_COMMAND_CONFIG);
2325 	if (en)
2326 		val |= (UMAC_COMMAND_CONFIG_REG_TX_ENA |
2327 			UMAC_COMMAND_CONFIG_REG_RX_ENA);
2328 	else
2329 		val &= ~(UMAC_COMMAND_CONFIG_REG_TX_ENA |
2330 			 UMAC_COMMAND_CONFIG_REG_RX_ENA);
2331 	/* Disable RX and TX */
2332 	REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2333 }
2334 
elink_umac_enable(struct elink_params * params,struct elink_vars * vars,uint8_t lb)2335 static void elink_umac_enable(struct elink_params *params,
2336 			    struct elink_vars *vars, uint8_t lb)
2337 {
2338 	uint32_t val;
2339 	uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
2340 	struct bnx2x_softc *sc = params->sc;
2341 	/* Reset UMAC */
2342 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2343 	       (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
2344 	DELAY(1000 * 1);
2345 
2346 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2347 	       (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
2348 
2349 	ELINK_DEBUG_P0(sc, "enabling UMAC");
2350 
2351 	/* This register opens the gate for the UMAC despite its name */
2352 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port * 4, 1);
2353 
2354 	val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
2355 		UMAC_COMMAND_CONFIG_REG_PAD_EN |
2356 		UMAC_COMMAND_CONFIG_REG_SW_RESET |
2357 		UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
2358 	switch (vars->line_speed) {
2359 	case ELINK_SPEED_10:
2360 		val |= (0 << 2);
2361 		break;
2362 	case ELINK_SPEED_100:
2363 		val |= (1 << 2);
2364 		break;
2365 	case ELINK_SPEED_1000:
2366 		val |= (2 << 2);
2367 		break;
2368 	case ELINK_SPEED_2500:
2369 		val |= (3 << 2);
2370 		break;
2371 	default:
2372 		ELINK_DEBUG_P1(sc, "Invalid speed for UMAC %d",
2373 			       vars->line_speed);
2374 		break;
2375 	}
2376 	if (!(vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2377 		val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE;
2378 
2379 	if (!(vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2380 		val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
2381 
2382 	if (vars->duplex == DUPLEX_HALF)
2383 		val |= UMAC_COMMAND_CONFIG_REG_HD_ENA;
2384 
2385 	REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2386 	DELAY(50);
2387 
2388 	/* Configure UMAC for EEE */
2389 	if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
2390 		ELINK_DEBUG_P0(sc, "configured UMAC for EEE");
2391 		REG_WR(sc, umac_base + UMAC_REG_UMAC_EEE_CTRL,
2392 		       UMAC_UMAC_EEE_CTRL_REG_EEE_EN);
2393 		REG_WR(sc, umac_base + UMAC_REG_EEE_WAKE_TIMER, 0x11);
2394 	} else {
2395 		REG_WR(sc, umac_base + UMAC_REG_UMAC_EEE_CTRL, 0x0);
2396 	}
2397 
2398 	/* Set MAC address for source TX Pause/PFC frames (under SW reset) */
2399 	REG_WR(sc, umac_base + UMAC_REG_MAC_ADDR0,
2400 	       ((params->mac_addr[2] << 24) |
2401 		(params->mac_addr[3] << 16) |
2402 		(params->mac_addr[4] << 8) |
2403 		(params->mac_addr[5])));
2404 	REG_WR(sc, umac_base + UMAC_REG_MAC_ADDR1,
2405 	       ((params->mac_addr[0] << 8) |
2406 		(params->mac_addr[1])));
2407 
2408 	/* Enable RX and TX */
2409 	val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
2410 	val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
2411 		UMAC_COMMAND_CONFIG_REG_RX_ENA;
2412 	REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2413 	DELAY(50);
2414 
2415 	/* Remove SW Reset */
2416 	val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
2417 
2418 	/* Check loopback mode */
2419 	if (lb)
2420 		val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
2421 	REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2422 
2423 	/* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
2424 	 * length used by the MAC receive logic to check frames.
2425 	 */
2426 	REG_WR(sc, umac_base + UMAC_REG_MAXFR, 0x2710);
2427 	elink_set_xumac_nig(params,
2428 			    ((vars->flow_ctrl & ELINK_FLOW_CTRL_TX) != 0), 1);
2429 	vars->mac_type = ELINK_MAC_TYPE_UMAC;
2430 
2431 }
2432 
2433 /* Define the XMAC mode */
elink_xmac_init(struct elink_params * params,uint32_t max_speed)2434 static void elink_xmac_init(struct elink_params *params, uint32_t max_speed)
2435 {
2436 	struct bnx2x_softc *sc = params->sc;
2437 	uint32_t is_port4mode = elink_is_4_port_mode(sc);
2438 
2439 	/* In 4-port mode, need to set the mode only once, so if XMAC is
2440 	 * already out of reset, it means the mode has already been set,
2441 	 * and it must not* reset the XMAC again, since it controls both
2442 	 * ports of the path
2443 	 */
2444 
2445 	if (((CHIP_NUM(sc) == CHIP_NUM_57840_4_10) ||
2446 	     (CHIP_NUM(sc) == CHIP_NUM_57840_2_20) ||
2447 	     (CHIP_NUM(sc) == CHIP_NUM_57840_OBS)) &&
2448 	    is_port4mode &&
2449 	    (REG_RD(sc, MISC_REG_RESET_REG_2) &
2450 	     MISC_REGISTERS_RESET_REG_2_XMAC)) {
2451 		ELINK_DEBUG_P0(sc,
2452 		   "XMAC already out of reset in 4-port mode");
2453 		return;
2454 	}
2455 
2456 	/* Hard reset */
2457 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2458 	       MISC_REGISTERS_RESET_REG_2_XMAC);
2459 	DELAY(1000 * 1);
2460 
2461 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2462 	       MISC_REGISTERS_RESET_REG_2_XMAC);
2463 	if (is_port4mode) {
2464 		ELINK_DEBUG_P0(sc, "Init XMAC to 2 ports x 10G per path");
2465 
2466 		/* Set the number of ports on the system side to up to 2 */
2467 		REG_WR(sc, MISC_REG_XMAC_CORE_PORT_MODE, 1);
2468 
2469 		/* Set the number of ports on the Warp Core to 10G */
2470 		REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 3);
2471 	} else {
2472 		/* Set the number of ports on the system side to 1 */
2473 		REG_WR(sc, MISC_REG_XMAC_CORE_PORT_MODE, 0);
2474 		if (max_speed == ELINK_SPEED_10000) {
2475 			ELINK_DEBUG_P0(sc,
2476 			   "Init XMAC to 10G x 1 port per path");
2477 			/* Set the number of ports on the Warp Core to 10G */
2478 			REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 3);
2479 		} else {
2480 			ELINK_DEBUG_P0(sc,
2481 			   "Init XMAC to 20G x 2 ports per path");
2482 			/* Set the number of ports on the Warp Core to 20G */
2483 			REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 1);
2484 		}
2485 	}
2486 	/* Soft reset */
2487 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2488 	       MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
2489 	DELAY(1000 * 1);
2490 
2491 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2492 	       MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
2493 
2494 }
2495 
elink_set_xmac_rxtx(struct elink_params * params,uint8_t en)2496 static void elink_set_xmac_rxtx(struct elink_params *params, uint8_t en)
2497 {
2498 	uint8_t port = params->port;
2499 	struct bnx2x_softc *sc = params->sc;
2500 	uint32_t pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
2501 	uint32_t val;
2502 
2503 	if (REG_RD(sc, MISC_REG_RESET_REG_2) &
2504 	    MISC_REGISTERS_RESET_REG_2_XMAC) {
2505 		/* Send an indication to change the state in the NIG back to XON
2506 		 * Clearing this bit enables the next set of this bit to get
2507 		 * rising edge
2508 		 */
2509 		pfc_ctrl = REG_RD(sc, xmac_base + XMAC_REG_PFC_CTRL_HI);
2510 		REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI,
2511 		       (pfc_ctrl & ~(1 << 1)));
2512 		REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI,
2513 		       (pfc_ctrl | (1 << 1)));
2514 		ELINK_DEBUG_P1(sc, "Disable XMAC on port %x", port);
2515 		val = REG_RD(sc, xmac_base + XMAC_REG_CTRL);
2516 		if (en)
2517 			val |= (XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
2518 		else
2519 			val &= ~(XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
2520 		REG_WR(sc, xmac_base + XMAC_REG_CTRL, val);
2521 	}
2522 }
2523 
elink_xmac_enable(struct elink_params * params,struct elink_vars * vars,uint8_t lb)2524 static elink_status_t elink_xmac_enable(struct elink_params *params,
2525 			     struct elink_vars *vars, uint8_t lb)
2526 {
2527 	uint32_t val, xmac_base;
2528 	struct bnx2x_softc *sc = params->sc;
2529 	ELINK_DEBUG_P0(sc, "enabling XMAC");
2530 
2531 	xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
2532 
2533 	elink_xmac_init(params, vars->line_speed);
2534 
2535 	/* This register determines on which events the MAC will assert
2536 	 * error on the i/f to the NIG along w/ EOP.
2537 	 */
2538 
2539 	/* This register tells the NIG whether to send traffic to UMAC
2540 	 * or XMAC
2541 	 */
2542 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port * 4, 0);
2543 
2544 	/* When XMAC is in XLGMII mode, disable sending idles for fault
2545 	 * detection.
2546 	 */
2547 	if (!(params->phy[ELINK_INT_PHY].flags & ELINK_FLAGS_TX_ERROR_CHECK)) {
2548 		REG_WR(sc, xmac_base + XMAC_REG_RX_LSS_CTRL,
2549 		       (XMAC_RX_LSS_CTRL_REG_LOCAL_FAULT_DISABLE |
2550 			XMAC_RX_LSS_CTRL_REG_REMOTE_FAULT_DISABLE));
2551 		REG_WR(sc, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
2552 		REG_WR(sc, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
2553 		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
2554 		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
2555 	}
2556 	/* Set Max packet size */
2557 	REG_WR(sc, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
2558 
2559 	/* CRC append for Tx packets */
2560 	REG_WR(sc, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
2561 
2562 	/* update PFC */
2563 	elink_update_pfc_xmac(params, vars, 0);
2564 
2565 	if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
2566 		ELINK_DEBUG_P0(sc, "Setting XMAC for EEE");
2567 		REG_WR(sc, xmac_base + XMAC_REG_EEE_TIMERS_HI, 0x1380008);
2568 		REG_WR(sc, xmac_base + XMAC_REG_EEE_CTRL, 0x1);
2569 	} else {
2570 		REG_WR(sc, xmac_base + XMAC_REG_EEE_CTRL, 0x0);
2571 	}
2572 
2573 	/* Enable TX and RX */
2574 	val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
2575 
2576 	/* Set MAC in XLGMII mode for dual-mode */
2577 	if ((vars->line_speed == ELINK_SPEED_20000) &&
2578 	    (params->phy[ELINK_INT_PHY].supported &
2579 	     ELINK_SUPPORTED_20000baseKR2_Full))
2580 		val |= XMAC_CTRL_REG_XLGMII_ALIGN_ENB;
2581 
2582 	/* Check loopback mode */
2583 	if (lb)
2584 		val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK;
2585 	REG_WR(sc, xmac_base + XMAC_REG_CTRL, val);
2586 	elink_set_xumac_nig(params,
2587 			    ((vars->flow_ctrl & ELINK_FLOW_CTRL_TX) != 0), 1);
2588 
2589 	vars->mac_type = ELINK_MAC_TYPE_XMAC;
2590 
2591 	return ELINK_STATUS_OK;
2592 }
2593 
elink_emac_enable(struct elink_params * params,struct elink_vars * vars,uint8_t lb)2594 static elink_status_t elink_emac_enable(struct elink_params *params,
2595 			     struct elink_vars *vars, uint8_t lb)
2596 {
2597 	struct bnx2x_softc *sc = params->sc;
2598 	uint8_t port = params->port;
2599 	uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2600 	uint32_t val;
2601 
2602 	ELINK_DEBUG_P0(sc, "enabling EMAC");
2603 
2604 	/* Disable BMAC */
2605 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2606 	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2607 
2608 	/* enable emac and not bmac */
2609 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + port * 4, 1);
2610 
2611 #ifdef ELINK_INCLUDE_EMUL
2612 	/* for palladium */
2613 	if (CHIP_REV_IS_EMUL(sc)) {
2614 		/* Use lane 1 (of lanes 0-3) */
2615 		REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, 1);
2616 		REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 1);
2617 	}
2618 	/* for fpga */
2619 	else
2620 #endif
2621 #ifdef ELINK_INCLUDE_FPGA
2622 	if (CHIP_REV_IS_FPGA(sc)) {
2623 		/* Use lane 1 (of lanes 0-3) */
2624 		ELINK_DEBUG_P0(sc, "elink_emac_enable: Setting FPGA");
2625 
2626 		REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, 1);
2627 		REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 0);
2628 	} else
2629 #endif
2630 	/* ASIC */
2631 	if (vars->phy_flags & PHY_XGXS_FLAG) {
2632 		uint32_t ser_lane = ((params->lane_config &
2633 				 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
2634 				PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
2635 
2636 		ELINK_DEBUG_P0(sc, "XGXS");
2637 		/* select the master lanes (out of 0-3) */
2638 		REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, ser_lane);
2639 		/* select XGXS */
2640 		REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 1);
2641 
2642 	} else { /* SerDes */
2643 		ELINK_DEBUG_P0(sc, "SerDes");
2644 		/* select SerDes */
2645 		REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 0);
2646 	}
2647 
2648 	elink_bits_en(sc, emac_base + EMAC_REG_EMAC_RX_MODE,
2649 		      EMAC_RX_MODE_RESET);
2650 	elink_bits_en(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
2651 		      EMAC_TX_MODE_RESET);
2652 
2653 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
2654 	if (CHIP_REV_IS_SLOW(sc)) {
2655 		/* config GMII mode */
2656 		val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2657 		elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE,
2658 				   (val | EMAC_MODE_PORT_GMII));
2659 	} else { /* ASIC */
2660 #endif
2661 		/* pause enable/disable */
2662 		elink_bits_dis(sc, emac_base + EMAC_REG_EMAC_RX_MODE,
2663 			       EMAC_RX_MODE_FLOW_EN);
2664 
2665 		elink_bits_dis(sc,  emac_base + EMAC_REG_EMAC_TX_MODE,
2666 			       (EMAC_TX_MODE_EXT_PAUSE_EN |
2667 				EMAC_TX_MODE_FLOW_EN));
2668 		if (!(params->feature_config_flags &
2669 		      ELINK_FEATURE_CONFIG_PFC_ENABLED)) {
2670 			if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
2671 				elink_bits_en(sc, emac_base +
2672 					      EMAC_REG_EMAC_RX_MODE,
2673 					      EMAC_RX_MODE_FLOW_EN);
2674 
2675 			if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
2676 				elink_bits_en(sc, emac_base +
2677 					      EMAC_REG_EMAC_TX_MODE,
2678 					      (EMAC_TX_MODE_EXT_PAUSE_EN |
2679 					       EMAC_TX_MODE_FLOW_EN));
2680 		} else
2681 			elink_bits_en(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
2682 				      EMAC_TX_MODE_FLOW_EN);
2683 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
2684 	}
2685 #endif
2686 
2687 	/* KEEP_VLAN_TAG, promiscuous */
2688 	val = REG_RD(sc, emac_base + EMAC_REG_EMAC_RX_MODE);
2689 	val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
2690 
2691 	/* Setting this bit causes MAC control frames (except for pause
2692 	 * frames) to be passed on for processing. This setting has no
2693 	 * affect on the operation of the pause frames. This bit effects
2694 	 * all packets regardless of RX Parser packet sorting logic.
2695 	 * Turn the PFC off to make sure we are in Xon state before
2696 	 * enabling it.
2697 	 */
2698 	elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_MODE, 0);
2699 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED) {
2700 		ELINK_DEBUG_P0(sc, "PFC is enabled");
2701 		/* Enable PFC again */
2702 		elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_MODE,
2703 			EMAC_REG_RX_PFC_MODE_RX_EN |
2704 			EMAC_REG_RX_PFC_MODE_TX_EN |
2705 			EMAC_REG_RX_PFC_MODE_PRIORITIES);
2706 
2707 		elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_PARAM,
2708 			((0x0101 <<
2709 			  EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
2710 			 (0x00ff <<
2711 			  EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
2712 		val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
2713 	}
2714 	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_RX_MODE, val);
2715 
2716 	/* Set Loopback */
2717 	val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2718 	if (lb)
2719 		val |= 0x810;
2720 	else
2721 		val &= ~0x810;
2722 	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE, val);
2723 
2724 	/* Enable emac */
2725 	REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port * 4, 1);
2726 
2727 	/* Enable emac for jumbo packets */
2728 	elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_RX_MTU_SIZE,
2729 		(EMAC_RX_MTU_SIZE_JUMBO_ENA |
2730 		 (ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD)));
2731 
2732 	/* Strip CRC */
2733 	REG_WR(sc, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port * 4, 0x1);
2734 
2735 	/* Disable the NIG in/out to the bmac */
2736 	REG_WR(sc, NIG_REG_BMAC0_IN_EN + port * 4, 0x0);
2737 	REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + port * 4, 0x0);
2738 	REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port * 4, 0x0);
2739 
2740 	/* Enable the NIG in/out to the emac */
2741 	REG_WR(sc, NIG_REG_EMAC0_IN_EN + port * 4, 0x1);
2742 	val = 0;
2743 	if ((params->feature_config_flags &
2744 	      ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
2745 	    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2746 		val = 1;
2747 
2748 	REG_WR(sc, NIG_REG_EMAC0_PAUSE_OUT_EN + port * 4, val);
2749 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port * 4, 0x1);
2750 
2751 #ifdef ELINK_INCLUDE_EMUL
2752 	if (CHIP_REV_IS_EMUL(sc)) {
2753 		/* Take the BigMac out of reset */
2754 		REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2755 		       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2756 
2757 		/* Enable access for bmac registers */
2758 		REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port * 4, 0x1);
2759 	} else
2760 #endif
2761 	REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port * 4, 0x0);
2762 
2763 	vars->mac_type = ELINK_MAC_TYPE_EMAC;
2764 	return ELINK_STATUS_OK;
2765 }
2766 
elink_update_pfc_bmac1(struct elink_params * params,struct elink_vars * vars)2767 static void elink_update_pfc_bmac1(struct elink_params *params,
2768 				   struct elink_vars *vars)
2769 {
2770 	uint32_t wb_data[2];
2771 	struct bnx2x_softc *sc = params->sc;
2772 	uint32_t bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
2773 		NIG_REG_INGRESS_BMAC0_MEM;
2774 
2775 	uint32_t val = 0x14;
2776 	if ((!(params->feature_config_flags &
2777 	      ELINK_FEATURE_CONFIG_PFC_ENABLED)) &&
2778 		(vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2779 		/* Enable BigMAC to react on received Pause packets */
2780 		val |= (1 << 5);
2781 	wb_data[0] = val;
2782 	wb_data[1] = 0;
2783 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
2784 
2785 	/* TX control */
2786 	val = 0xc0;
2787 	if (!(params->feature_config_flags &
2788 	      ELINK_FEATURE_CONFIG_PFC_ENABLED) &&
2789 		(vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2790 		val |= 0x800000;
2791 	wb_data[0] = val;
2792 	wb_data[1] = 0;
2793 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
2794 }
2795 
elink_update_pfc_bmac2(struct elink_params * params,struct elink_vars * vars,uint8_t is_lb)2796 static void elink_update_pfc_bmac2(struct elink_params *params,
2797 				   struct elink_vars *vars,
2798 				   uint8_t is_lb)
2799 {
2800 	/* Set rx control: Strip CRC and enable BigMAC to relay
2801 	 * control packets to the system as well
2802 	 */
2803 	uint32_t wb_data[2];
2804 	struct bnx2x_softc *sc = params->sc;
2805 	uint32_t bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
2806 		NIG_REG_INGRESS_BMAC0_MEM;
2807 	uint32_t val = 0x14;
2808 
2809 	if ((!(params->feature_config_flags &
2810 	      ELINK_FEATURE_CONFIG_PFC_ENABLED)) &&
2811 		(vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2812 		/* Enable BigMAC to react on received Pause packets */
2813 		val |= (1 << 5);
2814 	wb_data[0] = val;
2815 	wb_data[1] = 0;
2816 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
2817 	DELAY(30);
2818 
2819 	/* Tx control */
2820 	val = 0xc0;
2821 	if (!(params->feature_config_flags &
2822 				ELINK_FEATURE_CONFIG_PFC_ENABLED) &&
2823 	    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2824 		val |= 0x800000;
2825 	wb_data[0] = val;
2826 	wb_data[1] = 0;
2827 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
2828 
2829 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED) {
2830 		ELINK_DEBUG_P0(sc, "PFC is enabled");
2831 		/* Enable PFC RX & TX & STATS and set 8 COS  */
2832 		wb_data[0] = 0x0;
2833 		wb_data[0] |= (1 << 0);  /* RX */
2834 		wb_data[0] |= (1 << 1);  /* TX */
2835 		wb_data[0] |= (1 << 2);  /* Force initial Xon */
2836 		wb_data[0] |= (1 << 3);  /* 8 cos */
2837 		wb_data[0] |= (1 << 5);  /* STATS */
2838 		wb_data[1] = 0;
2839 		REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
2840 			    wb_data, 2);
2841 		/* Clear the force Xon */
2842 		wb_data[0] &= ~(1 << 2);
2843 	} else {
2844 		ELINK_DEBUG_P0(sc, "PFC is disabled");
2845 		/* Disable PFC RX & TX & STATS and set 8 COS */
2846 		wb_data[0] = 0x8;
2847 		wb_data[1] = 0;
2848 	}
2849 
2850 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
2851 
2852 	/* Set Time (based unit is 512 bit time) between automatic
2853 	 * re-sending of PP packets amd enable automatic re-send of
2854 	 * Per-Priority Packet as long as pp_gen is asserted and
2855 	 * pp_disable is low.
2856 	 */
2857 	val = 0x8000;
2858 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
2859 		val |= (1 << 16); /* enable automatic re-send */
2860 
2861 	wb_data[0] = val;
2862 	wb_data[1] = 0;
2863 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
2864 		    wb_data, 2);
2865 
2866 	/* mac control */
2867 	val = 0x3; /* Enable RX and TX */
2868 	if (is_lb) {
2869 		val |= 0x4; /* Local loopback */
2870 		ELINK_DEBUG_P0(sc, "enable bmac loopback");
2871 	}
2872 	/* When PFC enabled, Pass pause frames towards the NIG. */
2873 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
2874 		val |= ((1 << 6) | (1 << 5));
2875 
2876 	wb_data[0] = val;
2877 	wb_data[1] = 0;
2878 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2879 }
2880 
2881 /******************************************************************************
2882  * Description:
2883  *  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2884  *  not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2885  ******************************************************************************/
elink_pfc_nig_rx_priority_mask(struct bnx2x_softc * sc,uint8_t cos_entry,uint32_t priority_mask,uint8_t port)2886 static elink_status_t elink_pfc_nig_rx_priority_mask(struct bnx2x_softc *sc,
2887 					   uint8_t cos_entry,
2888 					   uint32_t priority_mask, uint8_t port)
2889 {
2890 	uint32_t nig_reg_rx_priority_mask_add = 0;
2891 
2892 	switch (cos_entry) {
2893 	case 0:
2894 	     nig_reg_rx_priority_mask_add = (port) ?
2895 		 NIG_REG_P1_RX_COS0_PRIORITY_MASK :
2896 		 NIG_REG_P0_RX_COS0_PRIORITY_MASK;
2897 		break;
2898 	case 1:
2899 	    nig_reg_rx_priority_mask_add = (port) ?
2900 		NIG_REG_P1_RX_COS1_PRIORITY_MASK :
2901 		NIG_REG_P0_RX_COS1_PRIORITY_MASK;
2902 		break;
2903 	case 2:
2904 	    nig_reg_rx_priority_mask_add = (port) ?
2905 		NIG_REG_P1_RX_COS2_PRIORITY_MASK :
2906 		NIG_REG_P0_RX_COS2_PRIORITY_MASK;
2907 		break;
2908 	case 3:
2909 		if (port)
2910 		return ELINK_STATUS_ERROR;
2911 	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
2912 		break;
2913 	case 4:
2914 		if (port)
2915 		return ELINK_STATUS_ERROR;
2916 	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
2917 		break;
2918 	case 5:
2919 		if (port)
2920 		return ELINK_STATUS_ERROR;
2921 	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
2922 		break;
2923 	}
2924 
2925 	REG_WR(sc, nig_reg_rx_priority_mask_add, priority_mask);
2926 
2927 	return ELINK_STATUS_OK;
2928 }
elink_update_mng(struct elink_params * params,uint32_t link_status)2929 static void elink_update_mng(struct elink_params *params, uint32_t link_status)
2930 {
2931 	struct bnx2x_softc *sc = params->sc;
2932 
2933 	REG_WR(sc, params->shmem_base +
2934 	       offsetof(struct shmem_region,
2935 			port_mb[params->port].link_status), link_status);
2936 }
2937 
elink_update_pfc_nig(struct elink_params * params,__rte_unused struct elink_vars * vars,struct elink_nig_brb_pfc_port_params * nig_params)2938 static void elink_update_pfc_nig(struct elink_params *params,
2939 		__rte_unused struct elink_vars *vars,
2940 		struct elink_nig_brb_pfc_port_params *nig_params)
2941 {
2942 	uint32_t xcm_mask = 0, ppp_enable = 0, pause_enable = 0;
2943 	uint32_t llfc_out_en = 0;
2944 	uint32_t llfc_enable = 0, xcm_out_en = 0, hwpfc_enable = 0;
2945 	uint32_t pkt_priority_to_cos = 0;
2946 	struct bnx2x_softc *sc = params->sc;
2947 	uint8_t port = params->port;
2948 
2949 	int set_pfc = params->feature_config_flags &
2950 		ELINK_FEATURE_CONFIG_PFC_ENABLED;
2951 	ELINK_DEBUG_P0(sc, "updating pfc nig parameters");
2952 
2953 	/* When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2954 	 * MAC control frames (that are not pause packets)
2955 	 * will be forwarded to the XCM.
2956 	 */
2957 	xcm_mask = REG_RD(sc, port ? NIG_REG_LLH1_XCM_MASK :
2958 			  NIG_REG_LLH0_XCM_MASK);
2959 	/* NIG params will override non PFC params, since it's possible to
2960 	 * do transition from PFC to SAFC
2961 	 */
2962 	if (set_pfc) {
2963 		pause_enable = 0;
2964 		llfc_out_en = 0;
2965 		llfc_enable = 0;
2966 		if (CHIP_IS_E3(sc))
2967 			ppp_enable = 0;
2968 		else
2969 			ppp_enable = 1;
2970 		xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2971 				     NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2972 		xcm_out_en = 0;
2973 		hwpfc_enable = 1;
2974 	} else  {
2975 		if (nig_params) {
2976 			llfc_out_en = nig_params->llfc_out_en;
2977 			llfc_enable = nig_params->llfc_enable;
2978 			pause_enable = nig_params->pause_enable;
2979 		} else  /* Default non PFC mode - PAUSE */
2980 			pause_enable = 1;
2981 
2982 		xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2983 			NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2984 		xcm_out_en = 1;
2985 	}
2986 
2987 	if (CHIP_IS_E3(sc))
2988 		REG_WR(sc, port ? NIG_REG_BRB1_PAUSE_IN_EN :
2989 		       NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
2990 	REG_WR(sc, port ? NIG_REG_LLFC_OUT_EN_1 :
2991 	       NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
2992 	REG_WR(sc, port ? NIG_REG_LLFC_ENABLE_1 :
2993 	       NIG_REG_LLFC_ENABLE_0, llfc_enable);
2994 	REG_WR(sc, port ? NIG_REG_PAUSE_ENABLE_1 :
2995 	       NIG_REG_PAUSE_ENABLE_0, pause_enable);
2996 
2997 	REG_WR(sc, port ? NIG_REG_PPP_ENABLE_1 :
2998 	       NIG_REG_PPP_ENABLE_0, ppp_enable);
2999 
3000 	REG_WR(sc, port ? NIG_REG_LLH1_XCM_MASK :
3001 	       NIG_REG_LLH0_XCM_MASK, xcm_mask);
3002 
3003 	REG_WR(sc, port ? NIG_REG_LLFC_EGRESS_SRC_ENABLE_1 :
3004 	       NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
3005 
3006 	/* Output enable for RX_XCM # IF */
3007 	REG_WR(sc, port ? NIG_REG_XCM1_OUT_EN :
3008 	       NIG_REG_XCM0_OUT_EN, xcm_out_en);
3009 
3010 	/* HW PFC TX enable */
3011 	REG_WR(sc, port ? NIG_REG_P1_HWPFC_ENABLE :
3012 	       NIG_REG_P0_HWPFC_ENABLE, hwpfc_enable);
3013 
3014 	if (nig_params) {
3015 		uint8_t i = 0;
3016 		pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
3017 
3018 		for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
3019 			elink_pfc_nig_rx_priority_mask(sc, i,
3020 		nig_params->rx_cos_priority_mask[i], port);
3021 
3022 		REG_WR(sc, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
3023 		       NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
3024 		       nig_params->llfc_high_priority_classes);
3025 
3026 		REG_WR(sc, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
3027 		       NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
3028 		       nig_params->llfc_low_priority_classes);
3029 	}
3030 	REG_WR(sc, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
3031 	       NIG_REG_P0_PKT_PRIORITY_TO_COS,
3032 	       pkt_priority_to_cos);
3033 }
3034 
elink_update_pfc(struct elink_params * params,struct elink_vars * vars,struct elink_nig_brb_pfc_port_params * pfc_params)3035 elink_status_t elink_update_pfc(struct elink_params *params,
3036 		      struct elink_vars *vars,
3037 		      struct elink_nig_brb_pfc_port_params *pfc_params)
3038 {
3039 	/* The PFC and pause are orthogonal to one another, meaning when
3040 	 * PFC is enabled, the pause are disabled, and when PFC is
3041 	 * disabled, pause are set according to the pause result.
3042 	 */
3043 	uint32_t val;
3044 	struct bnx2x_softc *sc = params->sc;
3045 	uint8_t bmac_loopback = (params->loopback_mode == ELINK_LOOPBACK_BMAC);
3046 
3047 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
3048 		vars->link_status |= LINK_STATUS_PFC_ENABLED;
3049 	else
3050 		vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
3051 
3052 	elink_update_mng(params, vars->link_status);
3053 
3054 	/* Update NIG params */
3055 	elink_update_pfc_nig(params, vars, pfc_params);
3056 
3057 	if (!vars->link_up)
3058 		return ELINK_STATUS_OK;
3059 
3060 	ELINK_DEBUG_P0(sc, "About to update PFC in BMAC");
3061 
3062 	if (CHIP_IS_E3(sc)) {
3063 		if (vars->mac_type == ELINK_MAC_TYPE_XMAC)
3064 			elink_update_pfc_xmac(params, vars, 0);
3065 	} else {
3066 		val = REG_RD(sc, MISC_REG_RESET_REG_2);
3067 		if ((val &
3068 		     (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
3069 		    == 0) {
3070 			ELINK_DEBUG_P0(sc, "About to update PFC in EMAC");
3071 			elink_emac_enable(params, vars, 0);
3072 			return ELINK_STATUS_OK;
3073 		}
3074 		if (CHIP_IS_E2(sc))
3075 			elink_update_pfc_bmac2(params, vars, bmac_loopback);
3076 		else
3077 			elink_update_pfc_bmac1(params, vars);
3078 
3079 		val = 0;
3080 		if ((params->feature_config_flags &
3081 		     ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
3082 		    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
3083 			val = 1;
3084 		REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port * 4, val);
3085 	}
3086 	return ELINK_STATUS_OK;
3087 }
3088 
elink_bmac1_enable(struct elink_params * params,struct elink_vars * vars,uint8_t is_lb)3089 static elink_status_t elink_bmac1_enable(struct elink_params *params,
3090 			      struct elink_vars *vars,
3091 			      uint8_t is_lb)
3092 {
3093 	struct bnx2x_softc *sc = params->sc;
3094 	uint8_t port = params->port;
3095 	uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
3096 			       NIG_REG_INGRESS_BMAC0_MEM;
3097 	uint32_t wb_data[2];
3098 	uint32_t val;
3099 
3100 	ELINK_DEBUG_P0(sc, "Enabling BigMAC1");
3101 
3102 	/* XGXS control */
3103 	wb_data[0] = 0x3c;
3104 	wb_data[1] = 0;
3105 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
3106 		    wb_data, 2);
3107 
3108 	/* TX MAC SA */
3109 	wb_data[0] = ((params->mac_addr[2] << 24) |
3110 		       (params->mac_addr[3] << 16) |
3111 		       (params->mac_addr[4] << 8) |
3112 			params->mac_addr[5]);
3113 	wb_data[1] = ((params->mac_addr[0] << 8) |
3114 			params->mac_addr[1]);
3115 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
3116 
3117 	/* MAC control */
3118 	val = 0x3;
3119 	if (is_lb) {
3120 		val |= 0x4;
3121 		ELINK_DEBUG_P0(sc,  "enable bmac loopback");
3122 	}
3123 	wb_data[0] = val;
3124 	wb_data[1] = 0;
3125 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
3126 
3127 	/* Set rx mtu */
3128 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3129 	wb_data[1] = 0;
3130 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
3131 
3132 	elink_update_pfc_bmac1(params, vars);
3133 
3134 	/* Set tx mtu */
3135 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3136 	wb_data[1] = 0;
3137 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
3138 
3139 	/* Set cnt max size */
3140 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3141 	wb_data[1] = 0;
3142 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
3143 
3144 	/* Configure SAFC */
3145 	wb_data[0] = 0x1000200;
3146 	wb_data[1] = 0;
3147 	REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
3148 		    wb_data, 2);
3149 #ifdef ELINK_INCLUDE_EMUL
3150 	/* Fix for emulation */
3151 	if (CHIP_REV_IS_EMUL(sc)) {
3152 		wb_data[0] = 0xf000;
3153 		wb_data[1] = 0;
3154 		REG_WR_DMAE(sc,	bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
3155 			    wb_data, 2);
3156 	}
3157 #endif
3158 
3159 	return ELINK_STATUS_OK;
3160 }
3161 
elink_bmac2_enable(struct elink_params * params,struct elink_vars * vars,uint8_t is_lb)3162 static elink_status_t elink_bmac2_enable(struct elink_params *params,
3163 			      struct elink_vars *vars,
3164 			      uint8_t is_lb)
3165 {
3166 	struct bnx2x_softc *sc = params->sc;
3167 	uint8_t port = params->port;
3168 	uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
3169 			       NIG_REG_INGRESS_BMAC0_MEM;
3170 	uint32_t wb_data[2];
3171 
3172 	ELINK_DEBUG_P0(sc, "Enabling BigMAC2");
3173 
3174 	wb_data[0] = 0;
3175 	wb_data[1] = 0;
3176 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
3177 	DELAY(30);
3178 
3179 	/* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
3180 	wb_data[0] = 0x3c;
3181 	wb_data[1] = 0;
3182 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
3183 		    wb_data, 2);
3184 
3185 	DELAY(30);
3186 
3187 	/* TX MAC SA */
3188 	wb_data[0] = ((params->mac_addr[2] << 24) |
3189 		       (params->mac_addr[3] << 16) |
3190 		       (params->mac_addr[4] << 8) |
3191 			params->mac_addr[5]);
3192 	wb_data[1] = ((params->mac_addr[0] << 8) |
3193 			params->mac_addr[1]);
3194 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
3195 		    wb_data, 2);
3196 
3197 	DELAY(30);
3198 
3199 	/* Configure SAFC */
3200 	wb_data[0] = 0x1000200;
3201 	wb_data[1] = 0;
3202 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
3203 		    wb_data, 2);
3204 	DELAY(30);
3205 
3206 	/* Set RX MTU */
3207 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3208 	wb_data[1] = 0;
3209 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
3210 	DELAY(30);
3211 
3212 	/* Set TX MTU */
3213 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3214 	wb_data[1] = 0;
3215 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
3216 	DELAY(30);
3217 	/* Set cnt max size */
3218 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD - 2;
3219 	wb_data[1] = 0;
3220 	REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
3221 	DELAY(30);
3222 	elink_update_pfc_bmac2(params, vars, is_lb);
3223 
3224 	return ELINK_STATUS_OK;
3225 }
3226 
elink_bmac_enable(struct elink_params * params,struct elink_vars * vars,uint8_t is_lb,uint8_t reset_bmac)3227 static elink_status_t elink_bmac_enable(struct elink_params *params,
3228 			     struct elink_vars *vars,
3229 			     uint8_t is_lb, uint8_t reset_bmac)
3230 {
3231 	elink_status_t rc = ELINK_STATUS_OK;
3232 	uint8_t port = params->port;
3233 	struct bnx2x_softc *sc = params->sc;
3234 	uint32_t val;
3235 	/* Reset and unreset the BigMac */
3236 	if (reset_bmac) {
3237 		REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
3238 		       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
3239 		DELAY(1000 * 1);
3240 	}
3241 
3242 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
3243 	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
3244 
3245 	/* Enable access for bmac registers */
3246 	REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port * 4, 0x1);
3247 
3248 	/* Enable BMAC according to BMAC type*/
3249 	if (CHIP_IS_E2(sc))
3250 		rc = elink_bmac2_enable(params, vars, is_lb);
3251 	else
3252 		rc = elink_bmac1_enable(params, vars, is_lb);
3253 	REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 0x1);
3254 	REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, 0x0);
3255 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + port * 4, 0x0);
3256 	val = 0;
3257 	if ((params->feature_config_flags &
3258 	      ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
3259 	    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
3260 		val = 1;
3261 	REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + port * 4, val);
3262 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port * 4, 0x0);
3263 	REG_WR(sc, NIG_REG_EMAC0_IN_EN + port * 4, 0x0);
3264 	REG_WR(sc, NIG_REG_EMAC0_PAUSE_OUT_EN + port * 4, 0x0);
3265 	REG_WR(sc, NIG_REG_BMAC0_IN_EN + port * 4, 0x1);
3266 	REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port * 4, 0x1);
3267 
3268 	vars->mac_type = ELINK_MAC_TYPE_BMAC;
3269 	return rc;
3270 }
3271 
elink_set_bmac_rx(struct bnx2x_softc * sc,__rte_unused uint32_t chip_id,uint8_t port,uint8_t en)3272 static void elink_set_bmac_rx(struct bnx2x_softc *sc,
3273 			      __rte_unused uint32_t chip_id,
3274 			      uint8_t port, uint8_t en)
3275 {
3276 	uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
3277 			NIG_REG_INGRESS_BMAC0_MEM;
3278 	uint32_t wb_data[2];
3279 	uint32_t nig_bmac_enable = REG_RD(sc, NIG_REG_BMAC0_REGS_OUT_EN +
3280 					  port * 4);
3281 
3282 	if (CHIP_IS_E2(sc))
3283 		bmac_addr += BIGMAC2_REGISTER_BMAC_CONTROL;
3284 	else
3285 		bmac_addr += BIGMAC_REGISTER_BMAC_CONTROL;
3286 	/* Only if the bmac is out of reset */
3287 	if (REG_RD(sc, MISC_REG_RESET_REG_2) &
3288 			(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
3289 	    nig_bmac_enable) {
3290 		/* Clear Rx Enable bit in BMAC_CONTROL register */
3291 		REG_RD_DMAE(sc, bmac_addr, wb_data, 2);
3292 		if (en)
3293 			wb_data[0] |= ELINK_BMAC_CONTROL_RX_ENABLE;
3294 		else
3295 			wb_data[0] &= ~ELINK_BMAC_CONTROL_RX_ENABLE;
3296 		REG_WR_DMAE(sc, bmac_addr, wb_data, 2);
3297 		DELAY(1000 * 1);
3298 	}
3299 }
3300 
elink_pbf_update(struct elink_params * params,uint32_t flow_ctrl,uint32_t line_speed)3301 static elink_status_t elink_pbf_update(struct elink_params *params,
3302 			    uint32_t flow_ctrl,
3303 			    uint32_t line_speed)
3304 {
3305 	struct bnx2x_softc *sc = params->sc;
3306 	uint8_t port = params->port;
3307 	uint32_t init_crd, crd;
3308 	uint32_t count = 1000;
3309 
3310 	/* Disable port */
3311 	REG_WR(sc, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port * 4, 0x1);
3312 
3313 	/* Wait for init credit */
3314 	init_crd = REG_RD(sc, PBF_REG_P0_INIT_CRD + port * 4);
3315 	crd = REG_RD(sc, PBF_REG_P0_CREDIT + port * 8);
3316 	ELINK_DEBUG_P2(sc, "init_crd 0x%x  crd 0x%x", init_crd, crd);
3317 
3318 	while ((init_crd != crd) && count) {
3319 		DELAY(1000 * 5);
3320 		crd = REG_RD(sc, PBF_REG_P0_CREDIT + port * 8);
3321 		count--;
3322 	}
3323 	crd = REG_RD(sc, PBF_REG_P0_CREDIT + port * 8);
3324 	if (init_crd != crd) {
3325 		ELINK_DEBUG_P2(sc, "BUG! init_crd 0x%x != crd 0x%x",
3326 			  init_crd, crd);
3327 		return ELINK_STATUS_ERROR;
3328 	}
3329 
3330 	if (flow_ctrl & ELINK_FLOW_CTRL_RX ||
3331 	    line_speed == ELINK_SPEED_10 ||
3332 	    line_speed == ELINK_SPEED_100 ||
3333 	    line_speed == ELINK_SPEED_1000 ||
3334 	    line_speed == ELINK_SPEED_2500) {
3335 		REG_WR(sc, PBF_REG_P0_PAUSE_ENABLE + port * 4, 1);
3336 		/* Update threshold */
3337 		REG_WR(sc, PBF_REG_P0_ARB_THRSH + port * 4, 0);
3338 		/* Update init credit */
3339 		init_crd = 778;		/* (800-18-4) */
3340 
3341 	} else {
3342 		uint32_t thresh = (ELINK_ETH_MAX_JUMBO_PACKET_SIZE +
3343 			      ELINK_ETH_OVREHEAD) / 16;
3344 		REG_WR(sc, PBF_REG_P0_PAUSE_ENABLE + port * 4, 0);
3345 		/* Update threshold */
3346 		REG_WR(sc, PBF_REG_P0_ARB_THRSH + port * 4, thresh);
3347 		/* Update init credit */
3348 		switch (line_speed) {
3349 		case ELINK_SPEED_10000:
3350 			init_crd = thresh + 553 - 22;
3351 			break;
3352 		default:
3353 			ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x",
3354 				  line_speed);
3355 			return ELINK_STATUS_ERROR;
3356 		}
3357 	}
3358 	REG_WR(sc, PBF_REG_P0_INIT_CRD + port * 4, init_crd);
3359 	ELINK_DEBUG_P2(sc, "PBF updated to speed %d credit %d",
3360 		 line_speed, init_crd);
3361 
3362 	/* Probe the credit changes */
3363 	REG_WR(sc, PBF_REG_INIT_P0 + port * 4, 0x1);
3364 	DELAY(1000 * 5);
3365 	REG_WR(sc, PBF_REG_INIT_P0 + port * 4, 0x0);
3366 
3367 	/* Enable port */
3368 	REG_WR(sc, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port * 4, 0x0);
3369 	return ELINK_STATUS_OK;
3370 }
3371 
3372 /**
3373  * elink_get_emac_base - retrieve emac base address
3374  *
3375  * @bp:			driver handle
3376  * @mdc_mdio_access:	access type
3377  * @port:		port id
3378  *
3379  * This function selects the MDC/MDIO access (through emac0 or
3380  * emac1) depend on the mdc_mdio_access, port, port swapped. Each
3381  * phy has a default access mode, which could also be overridden
3382  * by nvram configuration. This parameter, whether this is the
3383  * default phy configuration, or the nvram overrun
3384  * configuration, is passed here as mdc_mdio_access and selects
3385  * the emac_base for the CL45 read/writes operations
3386  */
elink_get_emac_base(struct bnx2x_softc * sc,uint32_t mdc_mdio_access,uint8_t port)3387 static uint32_t elink_get_emac_base(struct bnx2x_softc *sc,
3388 			       uint32_t mdc_mdio_access, uint8_t port)
3389 {
3390 	uint32_t emac_base = 0;
3391 	switch (mdc_mdio_access) {
3392 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
3393 		break;
3394 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
3395 		if (REG_RD(sc, NIG_REG_PORT_SWAP))
3396 			emac_base = GRCBASE_EMAC1;
3397 		else
3398 			emac_base = GRCBASE_EMAC0;
3399 		break;
3400 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
3401 		if (REG_RD(sc, NIG_REG_PORT_SWAP))
3402 			emac_base = GRCBASE_EMAC0;
3403 		else
3404 			emac_base = GRCBASE_EMAC1;
3405 		break;
3406 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
3407 		emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3408 		break;
3409 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
3410 		emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
3411 		break;
3412 	default:
3413 		break;
3414 	}
3415 	return emac_base;
3416 
3417 }
3418 
3419 /******************************************************************/
3420 /*			CL22 access functions			  */
3421 /******************************************************************/
elink_cl22_write(struct bnx2x_softc * sc,struct elink_phy * phy,uint16_t reg,uint16_t val)3422 static elink_status_t elink_cl22_write(struct bnx2x_softc *sc,
3423 				       struct elink_phy *phy,
3424 				       uint16_t reg, uint16_t val)
3425 {
3426 	uint32_t tmp, mode;
3427 	uint8_t i;
3428 	elink_status_t rc = ELINK_STATUS_OK;
3429 	/* Switch to CL22 */
3430 	mode = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
3431 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
3432 	       mode & ~EMAC_MDIO_MODE_CLAUSE_45);
3433 
3434 	/* Address */
3435 	tmp = ((phy->addr << 21) | (reg << 16) | val |
3436 	       EMAC_MDIO_COMM_COMMAND_WRITE_22 |
3437 	       EMAC_MDIO_COMM_START_BUSY);
3438 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3439 
3440 	for (i = 0; i < 50; i++) {
3441 		DELAY(10);
3442 
3443 		tmp = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3444 		if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3445 			DELAY(5);
3446 			break;
3447 		}
3448 	}
3449 	if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3450 		ELINK_DEBUG_P0(sc, "write phy register failed");
3451 		rc = ELINK_STATUS_TIMEOUT;
3452 	}
3453 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
3454 	return rc;
3455 }
3456 
elink_cl22_read(struct bnx2x_softc * sc,struct elink_phy * phy,uint16_t reg,uint16_t * ret_val)3457 static elink_status_t elink_cl22_read(struct bnx2x_softc *sc,
3458 				      struct elink_phy *phy,
3459 				      uint16_t reg, uint16_t *ret_val)
3460 {
3461 	uint32_t val, mode;
3462 	uint16_t i;
3463 	elink_status_t rc = ELINK_STATUS_OK;
3464 
3465 	/* Switch to CL22 */
3466 	mode = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
3467 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
3468 	       mode & ~EMAC_MDIO_MODE_CLAUSE_45);
3469 
3470 	/* Address */
3471 	val = ((phy->addr << 21) | (reg << 16) |
3472 	       EMAC_MDIO_COMM_COMMAND_READ_22 |
3473 	       EMAC_MDIO_COMM_START_BUSY);
3474 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3475 
3476 	for (i = 0; i < 50; i++) {
3477 		DELAY(10);
3478 
3479 		val = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3480 		if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3481 			*ret_val = (uint16_t)(val & EMAC_MDIO_COMM_DATA);
3482 			DELAY(5);
3483 			break;
3484 		}
3485 	}
3486 	if (val & EMAC_MDIO_COMM_START_BUSY) {
3487 		ELINK_DEBUG_P0(sc, "read phy register failed");
3488 
3489 		*ret_val = 0;
3490 		rc = ELINK_STATUS_TIMEOUT;
3491 	}
3492 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
3493 	return rc;
3494 }
3495 
3496 /******************************************************************/
3497 /*			CL45 access functions			  */
3498 /******************************************************************/
elink_cl45_read(struct bnx2x_softc * sc,struct elink_phy * phy,uint8_t devad,uint16_t reg,uint16_t * ret_val)3499 static elink_status_t elink_cl45_read(struct bnx2x_softc *sc,
3500 			   struct elink_phy *phy,
3501 			   uint8_t devad, uint16_t reg, uint16_t *ret_val)
3502 {
3503 	uint32_t val;
3504 	uint16_t i;
3505 	elink_status_t rc = ELINK_STATUS_OK;
3506 	uint32_t chip_id;
3507 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_G) {
3508 		chip_id = (REG_RD(sc, MISC_REG_CHIP_NUM) << 16) |
3509 			  ((REG_RD(sc, MISC_REG_CHIP_REV) & 0xf) << 12);
3510 		elink_set_mdio_clk(sc, chip_id, phy->mdio_ctrl);
3511 	}
3512 
3513 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3514 		elink_bits_en(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3515 			      EMAC_MDIO_STATUS_10MB);
3516 	/* Address */
3517 	val = ((phy->addr << 21) | (devad << 16) | reg |
3518 	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
3519 	       EMAC_MDIO_COMM_START_BUSY);
3520 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3521 
3522 	for (i = 0; i < 50; i++) {
3523 		DELAY(10);
3524 
3525 		val = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3526 		if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3527 			DELAY(5);
3528 			break;
3529 		}
3530 	}
3531 	if (val & EMAC_MDIO_COMM_START_BUSY) {
3532 		ELINK_DEBUG_P0(sc, "read phy register failed");
3533 		elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT);
3534 		/* "MDC/MDIO access timeout" */
3535 
3536 		*ret_val = 0;
3537 		rc = ELINK_STATUS_TIMEOUT;
3538 	} else {
3539 		/* Data */
3540 		val = ((phy->addr << 21) | (devad << 16) |
3541 		       EMAC_MDIO_COMM_COMMAND_READ_45 |
3542 		       EMAC_MDIO_COMM_START_BUSY);
3543 		REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3544 
3545 		for (i = 0; i < 50; i++) {
3546 			DELAY(10);
3547 
3548 			val = REG_RD(sc, phy->mdio_ctrl +
3549 				     EMAC_REG_EMAC_MDIO_COMM);
3550 			if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3551 				*ret_val = (uint16_t)
3552 						(val & EMAC_MDIO_COMM_DATA);
3553 				break;
3554 			}
3555 		}
3556 		if (val & EMAC_MDIO_COMM_START_BUSY) {
3557 			ELINK_DEBUG_P0(sc, "read phy register failed");
3558 			elink_cb_event_log(sc,
3559 					   ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT);
3560 			/* "MDC/MDIO access timeout" */
3561 
3562 			*ret_val = 0;
3563 			rc = ELINK_STATUS_TIMEOUT;
3564 		}
3565 	}
3566 	/* Work around for E3 A0 */
3567 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA) {
3568 		phy->flags ^= ELINK_FLAGS_DUMMY_READ;
3569 		if (phy->flags & ELINK_FLAGS_DUMMY_READ) {
3570 			uint16_t temp_val;
3571 			elink_cl45_read(sc, phy, devad, 0xf, &temp_val);
3572 		}
3573 	}
3574 
3575 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3576 		elink_bits_dis(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3577 			       EMAC_MDIO_STATUS_10MB);
3578 	return rc;
3579 }
3580 
elink_cl45_write(struct bnx2x_softc * sc,struct elink_phy * phy,uint8_t devad,uint16_t reg,uint16_t val)3581 static elink_status_t elink_cl45_write(struct bnx2x_softc *sc,
3582 			    struct elink_phy *phy,
3583 			    uint8_t devad, uint16_t reg, uint16_t val)
3584 {
3585 	uint32_t tmp;
3586 	uint8_t i;
3587 	elink_status_t rc = ELINK_STATUS_OK;
3588 	uint32_t chip_id;
3589 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_G) {
3590 		chip_id = (REG_RD(sc, MISC_REG_CHIP_NUM) << 16) |
3591 			  ((REG_RD(sc, MISC_REG_CHIP_REV) & 0xf) << 12);
3592 		elink_set_mdio_clk(sc, chip_id, phy->mdio_ctrl);
3593 	}
3594 
3595 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3596 		elink_bits_en(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3597 			      EMAC_MDIO_STATUS_10MB);
3598 
3599 	/* Address */
3600 	tmp = ((phy->addr << 21) | (devad << 16) | reg |
3601 	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
3602 	       EMAC_MDIO_COMM_START_BUSY);
3603 	REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3604 
3605 	for (i = 0; i < 50; i++) {
3606 		DELAY(10);
3607 
3608 		tmp = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3609 		if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3610 			DELAY(5);
3611 			break;
3612 		}
3613 	}
3614 	if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3615 		ELINK_DEBUG_P0(sc, "write phy register failed");
3616 		elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT);
3617 		/* "MDC/MDIO access timeout" */
3618 
3619 		rc = ELINK_STATUS_TIMEOUT;
3620 	} else {
3621 		/* Data */
3622 		tmp = ((phy->addr << 21) | (devad << 16) | val |
3623 		       EMAC_MDIO_COMM_COMMAND_WRITE_45 |
3624 		       EMAC_MDIO_COMM_START_BUSY);
3625 		REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3626 
3627 		for (i = 0; i < 50; i++) {
3628 			DELAY(10);
3629 
3630 			tmp = REG_RD(sc, phy->mdio_ctrl +
3631 				     EMAC_REG_EMAC_MDIO_COMM);
3632 			if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3633 				DELAY(5);
3634 				break;
3635 			}
3636 		}
3637 		if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3638 			ELINK_DEBUG_P0(sc, "write phy register failed");
3639 			elink_cb_event_log(sc,
3640 					   ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT);
3641 			/* "MDC/MDIO access timeout" */
3642 
3643 			rc = ELINK_STATUS_TIMEOUT;
3644 		}
3645 	}
3646 	/* Work around for E3 A0 */
3647 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA) {
3648 		phy->flags ^= ELINK_FLAGS_DUMMY_READ;
3649 		if (phy->flags & ELINK_FLAGS_DUMMY_READ) {
3650 			uint16_t temp_val;
3651 			elink_cl45_read(sc, phy, devad, 0xf, &temp_val);
3652 		}
3653 	}
3654 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3655 		elink_bits_dis(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3656 			       EMAC_MDIO_STATUS_10MB);
3657 	return rc;
3658 }
3659 
3660 /******************************************************************/
3661 /*			EEE section				   */
3662 /******************************************************************/
elink_eee_has_cap(struct elink_params * params)3663 static uint8_t elink_eee_has_cap(struct elink_params *params)
3664 {
3665 	struct bnx2x_softc *sc = params->sc;
3666 
3667 	if (REG_RD(sc, params->shmem2_base) <=
3668 		   offsetof(struct shmem2_region, eee_status[params->port]))
3669 		return 0;
3670 
3671 	return 1;
3672 }
3673 
elink_eee_nvram_to_time(uint32_t nvram_mode,uint32_t * idle_timer)3674 static elink_status_t elink_eee_nvram_to_time(uint32_t nvram_mode,
3675 					      uint32_t *idle_timer)
3676 {
3677 	switch (nvram_mode) {
3678 	case PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED:
3679 		*idle_timer = ELINK_EEE_MODE_NVRAM_BALANCED_TIME;
3680 		break;
3681 	case PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE:
3682 		*idle_timer = ELINK_EEE_MODE_NVRAM_AGGRESSIVE_TIME;
3683 		break;
3684 	case PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY:
3685 		*idle_timer = ELINK_EEE_MODE_NVRAM_LATENCY_TIME;
3686 		break;
3687 	default:
3688 		*idle_timer = 0;
3689 		break;
3690 	}
3691 
3692 	return ELINK_STATUS_OK;
3693 }
3694 
elink_eee_time_to_nvram(uint32_t idle_timer,uint32_t * nvram_mode)3695 static elink_status_t elink_eee_time_to_nvram(uint32_t idle_timer,
3696 					      uint32_t *nvram_mode)
3697 {
3698 	switch (idle_timer) {
3699 	case ELINK_EEE_MODE_NVRAM_BALANCED_TIME:
3700 		*nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED;
3701 		break;
3702 	case ELINK_EEE_MODE_NVRAM_AGGRESSIVE_TIME:
3703 		*nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE;
3704 		break;
3705 	case ELINK_EEE_MODE_NVRAM_LATENCY_TIME:
3706 		*nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY;
3707 		break;
3708 	default:
3709 		*nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED;
3710 		break;
3711 	}
3712 
3713 	return ELINK_STATUS_OK;
3714 }
3715 
elink_eee_calc_timer(struct elink_params * params)3716 static uint32_t elink_eee_calc_timer(struct elink_params *params)
3717 {
3718 	uint32_t eee_mode, eee_idle;
3719 	struct bnx2x_softc *sc = params->sc;
3720 
3721 	if (params->eee_mode & ELINK_EEE_MODE_OVERRIDE_NVRAM) {
3722 		if (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME) {
3723 			/* time value in eee_mode --> used directly*/
3724 			eee_idle = params->eee_mode & ELINK_EEE_MODE_TIMER_MASK;
3725 		} else {
3726 			/* hsi value in eee_mode --> time */
3727 			if (elink_eee_nvram_to_time(params->eee_mode &
3728 						    ELINK_EEE_MODE_NVRAM_MASK,
3729 						    &eee_idle))
3730 				return 0;
3731 		}
3732 	} else {
3733 		/* hsi values in nvram --> time*/
3734 		eee_mode = ((REG_RD(sc, params->shmem_base +
3735 				    offsetof(struct shmem_region, dev_info.
3736 				    port_feature_config[params->port].
3737 				    eee_power_mode)) &
3738 			     PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >>
3739 			    PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT);
3740 
3741 		if (elink_eee_nvram_to_time(eee_mode, &eee_idle))
3742 			return 0;
3743 	}
3744 
3745 	return eee_idle;
3746 }
3747 
elink_eee_set_timers(struct elink_params * params,struct elink_vars * vars)3748 static elink_status_t elink_eee_set_timers(struct elink_params *params,
3749 				   struct elink_vars *vars)
3750 {
3751 	uint32_t eee_idle = 0, eee_mode;
3752 	struct bnx2x_softc *sc = params->sc;
3753 
3754 	eee_idle = elink_eee_calc_timer(params);
3755 
3756 	if (eee_idle) {
3757 		REG_WR(sc, MISC_REG_CPMU_LP_IDLE_THR_P0 + (params->port << 2),
3758 		       eee_idle);
3759 	} else if ((params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI) &&
3760 		   (params->eee_mode & ELINK_EEE_MODE_OVERRIDE_NVRAM) &&
3761 		   (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME)) {
3762 		ELINK_DEBUG_P0(sc, "Error: Tx LPI is enabled with timer 0");
3763 		return ELINK_STATUS_ERROR;
3764 	}
3765 
3766 	vars->eee_status &= ~(SHMEM_EEE_TIMER_MASK | SHMEM_EEE_TIME_OUTPUT_BIT);
3767 	if (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME) {
3768 		/* eee_idle in 1u --> eee_status in 16u */
3769 		eee_idle >>= 4;
3770 		vars->eee_status |= (eee_idle & SHMEM_EEE_TIMER_MASK) |
3771 				    SHMEM_EEE_TIME_OUTPUT_BIT;
3772 	} else {
3773 		if (elink_eee_time_to_nvram(eee_idle, &eee_mode))
3774 			return ELINK_STATUS_ERROR;
3775 		vars->eee_status |= eee_mode;
3776 	}
3777 
3778 	return ELINK_STATUS_OK;
3779 }
3780 
elink_eee_initial_config(struct elink_params * params,struct elink_vars * vars,uint8_t mode)3781 static elink_status_t elink_eee_initial_config(struct elink_params *params,
3782 				     struct elink_vars *vars, uint8_t mode)
3783 {
3784 	vars->eee_status |= ((uint32_t) mode) << SHMEM_EEE_SUPPORTED_SHIFT;
3785 
3786 	/* Propagate params' bits --> vars (for migration exposure) */
3787 	if (params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)
3788 		vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT;
3789 	else
3790 		vars->eee_status &= ~SHMEM_EEE_LPI_REQUESTED_BIT;
3791 
3792 	if (params->eee_mode & ELINK_EEE_MODE_ADV_LPI)
3793 		vars->eee_status |= SHMEM_EEE_REQUESTED_BIT;
3794 	else
3795 		vars->eee_status &= ~SHMEM_EEE_REQUESTED_BIT;
3796 
3797 	return elink_eee_set_timers(params, vars);
3798 }
3799 
elink_eee_disable(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)3800 static elink_status_t elink_eee_disable(struct elink_phy *phy,
3801 				struct elink_params *params,
3802 				struct elink_vars *vars)
3803 {
3804 	struct bnx2x_softc *sc = params->sc;
3805 
3806 	/* Make Certain LPI is disabled */
3807 	REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), 0);
3808 
3809 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0x0);
3810 
3811 	vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
3812 
3813 	return ELINK_STATUS_OK;
3814 }
3815 
elink_eee_advertise(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars,uint8_t modes)3816 static elink_status_t elink_eee_advertise(struct elink_phy *phy,
3817 				  struct elink_params *params,
3818 				  struct elink_vars *vars, uint8_t modes)
3819 {
3820 	struct bnx2x_softc *sc = params->sc;
3821 	uint16_t val = 0;
3822 
3823 	/* Mask events preventing LPI generation */
3824 	REG_WR(sc, MISC_REG_CPMU_LP_MASK_EXT_P0 + (params->port << 2), 0xfc20);
3825 
3826 	if (modes & SHMEM_EEE_10G_ADV) {
3827 		ELINK_DEBUG_P0(sc, "Advertise 10GBase-T EEE");
3828 		val |= 0x8;
3829 	}
3830 	if (modes & SHMEM_EEE_1G_ADV) {
3831 		ELINK_DEBUG_P0(sc, "Advertise 1GBase-T EEE");
3832 		val |= 0x4;
3833 	}
3834 
3835 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, val);
3836 
3837 	vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
3838 	vars->eee_status |= (modes << SHMEM_EEE_ADV_STATUS_SHIFT);
3839 
3840 	return ELINK_STATUS_OK;
3841 }
3842 
elink_update_mng_eee(struct elink_params * params,uint32_t eee_status)3843 static void elink_update_mng_eee(struct elink_params *params,
3844 				 uint32_t eee_status)
3845 {
3846 	struct bnx2x_softc *sc = params->sc;
3847 
3848 	if (elink_eee_has_cap(params))
3849 		REG_WR(sc, params->shmem2_base +
3850 		       offsetof(struct shmem2_region,
3851 				eee_status[params->port]), eee_status);
3852 }
3853 
elink_eee_an_resolve(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)3854 static void elink_eee_an_resolve(struct elink_phy *phy,
3855 				  struct elink_params *params,
3856 				  struct elink_vars *vars)
3857 {
3858 	struct bnx2x_softc *sc = params->sc;
3859 	uint16_t adv = 0, lp = 0;
3860 	uint32_t lp_adv = 0;
3861 	uint8_t neg = 0;
3862 
3863 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, &adv);
3864 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LP_EEE_ADV, &lp);
3865 
3866 	if (lp & 0x2) {
3867 		lp_adv |= SHMEM_EEE_100M_ADV;
3868 		if (adv & 0x2) {
3869 			if (vars->line_speed == ELINK_SPEED_100)
3870 				neg = 1;
3871 			ELINK_DEBUG_P0(sc, "EEE negotiated - 100M");
3872 		}
3873 	}
3874 	if (lp & 0x14) {
3875 		lp_adv |= SHMEM_EEE_1G_ADV;
3876 		if (adv & 0x14) {
3877 			if (vars->line_speed == ELINK_SPEED_1000)
3878 				neg = 1;
3879 			ELINK_DEBUG_P0(sc, "EEE negotiated - 1G");
3880 		}
3881 	}
3882 	if (lp & 0x68) {
3883 		lp_adv |= SHMEM_EEE_10G_ADV;
3884 		if (adv & 0x68) {
3885 			if (vars->line_speed == ELINK_SPEED_10000)
3886 				neg = 1;
3887 			ELINK_DEBUG_P0(sc, "EEE negotiated - 10G");
3888 		}
3889 	}
3890 
3891 	vars->eee_status &= ~SHMEM_EEE_LP_ADV_STATUS_MASK;
3892 	vars->eee_status |= (lp_adv << SHMEM_EEE_LP_ADV_STATUS_SHIFT);
3893 
3894 	if (neg) {
3895 		ELINK_DEBUG_P0(sc, "EEE is active");
3896 		vars->eee_status |= SHMEM_EEE_ACTIVE_BIT;
3897 	}
3898 }
3899 
3900 /******************************************************************/
3901 /*			BSC access functions from E3	          */
3902 /******************************************************************/
elink_bsc_module_sel(struct elink_params * params)3903 static void elink_bsc_module_sel(struct elink_params *params)
3904 {
3905 	int idx;
3906 	uint32_t board_cfg, sfp_ctrl;
3907 	uint32_t i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
3908 	struct bnx2x_softc *sc = params->sc;
3909 	uint8_t port = params->port;
3910 	/* Read I2C output PINs */
3911 	board_cfg = REG_RD(sc, params->shmem_base +
3912 			   offsetof(struct shmem_region,
3913 				    dev_info.shared_hw_config.board));
3914 	i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
3915 	i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
3916 			SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
3917 
3918 	/* Read I2C output value */
3919 	sfp_ctrl = REG_RD(sc, params->shmem_base +
3920 			  offsetof(struct shmem_region,
3921 				 dev_info.port_hw_config[port].e3_cmn_pin_cfg));
3922 	i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
3923 	i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
3924 	ELINK_DEBUG_P0(sc, "Setting BSC switch");
3925 	for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
3926 		elink_set_cfg_pin(sc, i2c_pins[idx], i2c_val[idx]);
3927 }
3928 
elink_bsc_read(struct bnx2x_softc * sc,uint8_t sl_devid,uint16_t sl_addr,uint8_t lc_addr,uint8_t xfer_cnt,uint32_t * data_array)3929 static elink_status_t elink_bsc_read(struct bnx2x_softc *sc,
3930 			  uint8_t sl_devid,
3931 			  uint16_t sl_addr,
3932 			  uint8_t lc_addr,
3933 			  uint8_t xfer_cnt,
3934 			  uint32_t *data_array)
3935 {
3936 	uint32_t val, i;
3937 	elink_status_t rc = ELINK_STATUS_OK;
3938 
3939 	if (xfer_cnt > 16) {
3940 		ELINK_DEBUG_P1(sc, "invalid xfer_cnt %d. Max is 16 bytes",
3941 					xfer_cnt);
3942 		return ELINK_STATUS_ERROR;
3943 	}
3944 
3945 	xfer_cnt = 16 - lc_addr;
3946 
3947 	/* Enable the engine */
3948 	val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3949 	val |= MCPR_IMC_COMMAND_ENABLE;
3950 	REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
3951 
3952 	/* Program slave device ID */
3953 	val = (sl_devid << 16) | sl_addr;
3954 	REG_WR(sc, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
3955 
3956 	/* Start xfer with 0 byte to update the address pointer ???*/
3957 	val = (MCPR_IMC_COMMAND_ENABLE) |
3958 	      (MCPR_IMC_COMMAND_WRITE_OP <<
3959 		MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3960 		(lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
3961 	REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
3962 
3963 	/* Poll for completion */
3964 	i = 0;
3965 	val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3966 	while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3967 		DELAY(10);
3968 		val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3969 		if (i++ > 1000) {
3970 			ELINK_DEBUG_P1(sc, "wr 0 byte timed out after %d try",
3971 								i);
3972 			rc = ELINK_STATUS_TIMEOUT;
3973 			break;
3974 		}
3975 	}
3976 	if (rc == ELINK_STATUS_TIMEOUT)
3977 		return rc;
3978 
3979 	/* Start xfer with read op */
3980 	val = (MCPR_IMC_COMMAND_ENABLE) |
3981 		(MCPR_IMC_COMMAND_READ_OP <<
3982 		MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3983 		(lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
3984 		  (xfer_cnt);
3985 	REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
3986 
3987 	/* Poll for completion */
3988 	i = 0;
3989 	val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3990 	while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3991 		DELAY(10);
3992 		val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3993 		if (i++ > 1000) {
3994 			ELINK_DEBUG_P1(sc, "rd op timed out after %d try", i);
3995 			rc = ELINK_STATUS_TIMEOUT;
3996 			break;
3997 		}
3998 	}
3999 	if (rc == ELINK_STATUS_TIMEOUT)
4000 		return rc;
4001 
4002 	for (i = (lc_addr >> 2); i < 4; i++) {
4003 		data_array[i] = REG_RD(sc, (MCP_REG_MCPR_IMC_DATAREG0 + i * 4));
4004 #ifdef __BIG_ENDIAN
4005 		data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
4006 				((data_array[i] & 0x0000ff00) << 8) |
4007 				((data_array[i] & 0x00ff0000) >> 8) |
4008 				((data_array[i] & 0xff000000) >> 24);
4009 #endif
4010 	}
4011 	return rc;
4012 }
4013 
elink_cl45_read_or_write(struct bnx2x_softc * sc,struct elink_phy * phy,uint8_t devad,uint16_t reg,uint16_t or_val)4014 static void elink_cl45_read_or_write(struct bnx2x_softc *sc,
4015 				     struct elink_phy *phy,
4016 				     uint8_t devad, uint16_t reg,
4017 				     uint16_t or_val)
4018 {
4019 	uint16_t val;
4020 	elink_cl45_read(sc, phy, devad, reg, &val);
4021 	elink_cl45_write(sc, phy, devad, reg, val | or_val);
4022 }
4023 
elink_cl45_read_and_write(struct bnx2x_softc * sc,struct elink_phy * phy,uint8_t devad,uint16_t reg,uint16_t and_val)4024 static void elink_cl45_read_and_write(struct bnx2x_softc *sc,
4025 				      struct elink_phy *phy,
4026 				      uint8_t devad, uint16_t reg,
4027 				      uint16_t and_val)
4028 {
4029 	uint16_t val;
4030 	elink_cl45_read(sc, phy, devad, reg, &val);
4031 	elink_cl45_write(sc, phy, devad, reg, val & and_val);
4032 }
4033 
elink_phy_read(struct elink_params * params,uint8_t phy_addr,uint8_t devad,uint16_t reg,uint16_t * ret_val)4034 elink_status_t elink_phy_read(struct elink_params *params, uint8_t phy_addr,
4035 		   uint8_t devad, uint16_t reg, uint16_t *ret_val)
4036 {
4037 	uint8_t phy_index;
4038 	/* Probe for the phy according to the given phy_addr, and execute
4039 	 * the read request on it
4040 	 */
4041 	for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
4042 		if (params->phy[phy_index].addr == phy_addr) {
4043 			return elink_cl45_read(params->sc,
4044 					       &params->phy[phy_index], devad,
4045 					       reg, ret_val);
4046 		}
4047 	}
4048 	return ELINK_STATUS_ERROR;
4049 }
4050 
elink_phy_write(struct elink_params * params,uint8_t phy_addr,uint8_t devad,uint16_t reg,uint16_t val)4051 elink_status_t elink_phy_write(struct elink_params *params, uint8_t phy_addr,
4052 		    uint8_t devad, uint16_t reg, uint16_t val)
4053 {
4054 	uint8_t phy_index;
4055 	/* Probe for the phy according to the given phy_addr, and execute
4056 	 * the write request on it
4057 	 */
4058 	for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
4059 		if (params->phy[phy_index].addr == phy_addr) {
4060 			return elink_cl45_write(params->sc,
4061 						&params->phy[phy_index], devad,
4062 						reg, val);
4063 		}
4064 	}
4065 	return ELINK_STATUS_ERROR;
4066 }
4067 
elink_get_warpcore_lane(__rte_unused struct elink_phy * phy,struct elink_params * params)4068 static uint8_t elink_get_warpcore_lane(__rte_unused struct elink_phy *phy,
4069 				  struct elink_params *params)
4070 {
4071 	uint8_t lane = 0;
4072 	struct bnx2x_softc *sc = params->sc;
4073 	uint32_t path_swap, path_swap_ovr;
4074 	uint8_t path, port;
4075 
4076 	path = SC_PATH(sc);
4077 	port = params->port;
4078 
4079 	if (elink_is_4_port_mode(sc)) {
4080 		uint32_t port_swap, port_swap_ovr;
4081 
4082 		/* Figure out path swap value */
4083 		path_swap_ovr = REG_RD(sc, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
4084 		if (path_swap_ovr & 0x1)
4085 			path_swap = (path_swap_ovr & 0x2);
4086 		else
4087 			path_swap = REG_RD(sc, MISC_REG_FOUR_PORT_PATH_SWAP);
4088 
4089 		if (path_swap)
4090 			path = path ^ 1;
4091 
4092 		/* Figure out port swap value */
4093 		port_swap_ovr = REG_RD(sc, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
4094 		if (port_swap_ovr & 0x1)
4095 			port_swap = (port_swap_ovr & 0x2);
4096 		else
4097 			port_swap = REG_RD(sc, MISC_REG_FOUR_PORT_PORT_SWAP);
4098 
4099 		if (port_swap)
4100 			port = port ^ 1;
4101 
4102 		lane = (port << 1) + path;
4103 	} else { /* Two port mode - no port swap */
4104 
4105 		/* Figure out path swap value */
4106 		path_swap_ovr =
4107 			REG_RD(sc, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
4108 		if (path_swap_ovr & 0x1) {
4109 			path_swap = (path_swap_ovr & 0x2);
4110 		} else {
4111 			path_swap =
4112 				REG_RD(sc, MISC_REG_TWO_PORT_PATH_SWAP);
4113 		}
4114 		if (path_swap)
4115 			path = path ^ 1;
4116 
4117 		lane = path << 1;
4118 	}
4119 	return lane;
4120 }
4121 
4122 
elink_set_aer_mmd(struct elink_params * params,struct elink_phy * phy)4123 static void elink_set_aer_mmd(struct elink_params *params,
4124 			      struct elink_phy *phy)
4125 {
4126 	uint32_t ser_lane;
4127 	uint16_t offset, aer_val;
4128 	struct bnx2x_softc *sc = params->sc;
4129 	ser_lane = ((params->lane_config &
4130 		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4131 		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4132 
4133 	offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
4134 		(phy->addr + ser_lane) : 0;
4135 
4136 	if (USES_WARPCORE(sc)) {
4137 		aer_val = elink_get_warpcore_lane(phy, params);
4138 		/* In Dual-lane mode, two lanes are joined together,
4139 		 * so in order to configure them, the AER broadcast method is
4140 		 * used here.
4141 		 * 0x200 is the broadcast address for lanes 0,1
4142 		 * 0x201 is the broadcast address for lanes 2,3
4143 		 */
4144 		if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
4145 			aer_val = (aer_val >> 1) | 0x200;
4146 	} else if (CHIP_IS_E2(sc))
4147 		aer_val = 0x3800 + offset - 1;
4148 	else
4149 		aer_val = 0x3800 + offset;
4150 
4151 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4152 			  MDIO_AER_BLOCK_AER_REG, aer_val);
4153 
4154 }
4155 
4156 /******************************************************************/
4157 /*			Internal phy section			  */
4158 /******************************************************************/
4159 
elink_set_serdes_access(struct bnx2x_softc * sc,uint8_t port)4160 static void elink_set_serdes_access(struct bnx2x_softc *sc, uint8_t port)
4161 {
4162 	uint32_t emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4163 
4164 	/* Set Clause 22 */
4165 	REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_ST + port * 0x10, 1);
4166 	REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
4167 	DELAY(500);
4168 	REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
4169 	DELAY(500);
4170 	 /* Set Clause 45 */
4171 	REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_ST + port * 0x10, 0);
4172 }
4173 
elink_serdes_deassert(struct bnx2x_softc * sc,uint8_t port)4174 static void elink_serdes_deassert(struct bnx2x_softc *sc, uint8_t port)
4175 {
4176 	uint32_t val;
4177 
4178 	ELINK_DEBUG_P0(sc, "elink_serdes_deassert");
4179 
4180 	val = ELINK_SERDES_RESET_BITS << (port * 16);
4181 
4182 	/* Reset and unreset the SerDes/XGXS */
4183 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
4184 	DELAY(500);
4185 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
4186 
4187 	elink_set_serdes_access(sc, port);
4188 
4189 	REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_DEVAD + port * 0x10,
4190 	       ELINK_DEFAULT_PHY_DEV_ADDR);
4191 }
4192 
elink_xgxs_specific_func(struct elink_phy * phy,struct elink_params * params,uint32_t action)4193 static void elink_xgxs_specific_func(struct elink_phy *phy,
4194 				     struct elink_params *params,
4195 				     uint32_t action)
4196 {
4197 	struct bnx2x_softc *sc = params->sc;
4198 	switch (action) {
4199 	case ELINK_PHY_INIT:
4200 		/* Set correct devad */
4201 		REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_ST + params->port * 0x18, 0);
4202 		REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port * 0x18,
4203 		       phy->def_md_devad);
4204 		break;
4205 	}
4206 }
4207 
elink_xgxs_deassert(struct elink_params * params)4208 static void elink_xgxs_deassert(struct elink_params *params)
4209 {
4210 	struct bnx2x_softc *sc = params->sc;
4211 	uint8_t port;
4212 	uint32_t val;
4213 	ELINK_DEBUG_P0(sc, "elink_xgxs_deassert");
4214 	port = params->port;
4215 
4216 	val = ELINK_XGXS_RESET_BITS << (port * 16);
4217 
4218 	/* Reset and unreset the SerDes/XGXS */
4219 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
4220 	DELAY(500);
4221 	REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
4222 	elink_xgxs_specific_func(&params->phy[ELINK_INT_PHY], params,
4223 				 ELINK_PHY_INIT);
4224 }
4225 
elink_calc_ieee_aneg_adv(struct elink_phy * phy,struct elink_params * params,uint16_t * ieee_fc)4226 static void elink_calc_ieee_aneg_adv(struct elink_phy *phy,
4227 				     struct elink_params *params,
4228 				     uint16_t *ieee_fc)
4229 {
4230 	struct bnx2x_softc *sc = params->sc;
4231 	*ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
4232 	/* Resolve pause mode and advertisement Please refer to Table
4233 	 * 28B-3 of the 802.3ab-1999 spec
4234 	 */
4235 
4236 	switch (phy->req_flow_ctrl) {
4237 	case ELINK_FLOW_CTRL_AUTO:
4238 		switch (params->req_fc_auto_adv) {
4239 		case ELINK_FLOW_CTRL_BOTH:
4240 		case ELINK_FLOW_CTRL_RX:
4241 			*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4242 			break;
4243 		case ELINK_FLOW_CTRL_TX:
4244 			*ieee_fc |=
4245 				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
4246 			break;
4247 		default:
4248 			break;
4249 		}
4250 		break;
4251 	case ELINK_FLOW_CTRL_TX:
4252 		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
4253 		break;
4254 
4255 	case ELINK_FLOW_CTRL_RX:
4256 	case ELINK_FLOW_CTRL_BOTH:
4257 		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4258 		break;
4259 
4260 	case ELINK_FLOW_CTRL_NONE:
4261 	default:
4262 		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
4263 		break;
4264 	}
4265 	ELINK_DEBUG_P1(sc, "ieee_fc = 0x%x", *ieee_fc);
4266 }
4267 
set_phy_vars(struct elink_params * params,struct elink_vars * vars)4268 static void set_phy_vars(struct elink_params *params,
4269 			 struct elink_vars *vars)
4270 {
4271 	struct bnx2x_softc *sc = params->sc;
4272 	uint8_t actual_phy_idx, phy_index, link_cfg_idx;
4273 	uint8_t phy_config_swapped = params->multi_phy_config &
4274 			PORT_HW_CFG_PHY_SWAPPED_ENABLED;
4275 	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
4276 	      phy_index++) {
4277 		link_cfg_idx = ELINK_LINK_CONFIG_IDX(phy_index);
4278 		actual_phy_idx = phy_index;
4279 		if (phy_config_swapped) {
4280 			if (phy_index == ELINK_EXT_PHY1)
4281 				actual_phy_idx = ELINK_EXT_PHY2;
4282 			else if (phy_index == ELINK_EXT_PHY2)
4283 				actual_phy_idx = ELINK_EXT_PHY1;
4284 		}
4285 		params->phy[actual_phy_idx].req_flow_ctrl =
4286 			params->req_flow_ctrl[link_cfg_idx];
4287 
4288 		params->phy[actual_phy_idx].req_line_speed =
4289 			params->req_line_speed[link_cfg_idx];
4290 
4291 		params->phy[actual_phy_idx].speed_cap_mask =
4292 			params->speed_cap_mask[link_cfg_idx];
4293 
4294 		params->phy[actual_phy_idx].req_duplex =
4295 			params->req_duplex[link_cfg_idx];
4296 
4297 		if (params->req_line_speed[link_cfg_idx] ==
4298 		    ELINK_SPEED_AUTO_NEG)
4299 			vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
4300 
4301 		ELINK_DEBUG_P3(sc, "req_flow_ctrl %x, req_line_speed %x,"
4302 			   " speed_cap_mask %x",
4303 			   params->phy[actual_phy_idx].req_flow_ctrl,
4304 			   params->phy[actual_phy_idx].req_line_speed,
4305 			   params->phy[actual_phy_idx].speed_cap_mask);
4306 	}
4307 }
4308 
elink_ext_phy_set_pause(struct elink_params * params,struct elink_phy * phy,struct elink_vars * vars)4309 static void elink_ext_phy_set_pause(struct elink_params *params,
4310 				    struct elink_phy *phy,
4311 				    struct elink_vars *vars)
4312 {
4313 	uint16_t val;
4314 	struct bnx2x_softc *sc = params->sc;
4315 	/* Read modify write pause advertizing */
4316 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
4317 
4318 	val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
4319 
4320 	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
4321 	elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
4322 	if ((vars->ieee_fc &
4323 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
4324 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
4325 		val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
4326 	}
4327 	if ((vars->ieee_fc &
4328 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
4329 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
4330 		val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
4331 	}
4332 	ELINK_DEBUG_P1(sc, "Ext phy AN advertize 0x%x", val);
4333 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
4334 }
4335 
elink_pause_resolve(__rte_unused struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars,uint32_t pause_result)4336 static void elink_pause_resolve(__rte_unused struct elink_phy *phy,
4337 				struct elink_params *params,
4338 				struct elink_vars *vars,
4339 				uint32_t pause_result)
4340 {
4341 	struct bnx2x_softc *sc = params->sc;
4342 						/*  LD	    LP	 */
4343 	switch (pause_result) {			/* ASYM P ASYM P */
4344 	case 0xb:				/*   1  0   1  1 */
4345 		ELINK_DEBUG_P0(sc, "Flow Control: TX only");
4346 		vars->flow_ctrl = ELINK_FLOW_CTRL_TX;
4347 		break;
4348 
4349 	case 0xe:				/*   1  1   1  0 */
4350 		ELINK_DEBUG_P0(sc, "Flow Control: RX only");
4351 		vars->flow_ctrl = ELINK_FLOW_CTRL_RX;
4352 		break;
4353 
4354 	case 0x5:				/*   0  1   0  1 */
4355 	case 0x7:				/*   0  1   1  1 */
4356 	case 0xd:				/*   1  1   0  1 */
4357 	case 0xf:				/*   1  1   1  1 */
4358 		/* If the user selected to advertise RX ONLY,
4359 		 * although we advertised both, need to enable
4360 		 * RX only.
4361 		 */
4362 
4363 		if (params->req_fc_auto_adv == ELINK_FLOW_CTRL_BOTH) {
4364 			ELINK_DEBUG_P0(sc, "Flow Control: RX & TX");
4365 		vars->flow_ctrl = ELINK_FLOW_CTRL_BOTH;
4366 		} else {
4367 			ELINK_DEBUG_P0(sc, "Flow Control: RX only");
4368 			vars->flow_ctrl = ELINK_FLOW_CTRL_RX;
4369 		}
4370 		break;
4371 	default:
4372 		ELINK_DEBUG_P0(sc, "Flow Control: None");
4373 		vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
4374 		break;
4375 	}
4376 	if (pause_result & (1 << 0))
4377 		vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
4378 	if (pause_result & (1 << 1))
4379 		vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
4380 
4381 }
4382 
elink_ext_phy_update_adv_fc(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)4383 static void elink_ext_phy_update_adv_fc(struct elink_phy *phy,
4384 					struct elink_params *params,
4385 					struct elink_vars *vars)
4386 {
4387 	uint16_t ld_pause;		/* local */
4388 	uint16_t lp_pause;		/* link partner */
4389 	uint16_t pause_result;
4390 	struct bnx2x_softc *sc = params->sc;
4391 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE) {
4392 		elink_cl22_read(sc, phy, 0x4, &ld_pause);
4393 		elink_cl22_read(sc, phy, 0x5, &lp_pause);
4394 	} else if (CHIP_IS_E3(sc) &&
4395 		ELINK_SINGLE_MEDIA_DIRECT(params)) {
4396 		uint8_t lane = elink_get_warpcore_lane(phy, params);
4397 		uint16_t gp_status, gp_mask;
4398 		elink_cl45_read(sc, phy,
4399 				MDIO_AN_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_4,
4400 				&gp_status);
4401 		gp_mask = (MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL |
4402 			   MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP) <<
4403 			lane;
4404 		if ((gp_status & gp_mask) == gp_mask) {
4405 			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4406 					MDIO_AN_REG_ADV_PAUSE, &ld_pause);
4407 			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4408 					MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
4409 		} else {
4410 			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4411 					MDIO_AN_REG_CL37_FC_LD, &ld_pause);
4412 			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4413 					MDIO_AN_REG_CL37_FC_LP, &lp_pause);
4414 			ld_pause = ((ld_pause &
4415 				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
4416 				    << 3);
4417 			lp_pause = ((lp_pause &
4418 				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
4419 				    << 3);
4420 		}
4421 	} else {
4422 		elink_cl45_read(sc, phy,
4423 				MDIO_AN_DEVAD,
4424 				MDIO_AN_REG_ADV_PAUSE, &ld_pause);
4425 		elink_cl45_read(sc, phy,
4426 				MDIO_AN_DEVAD,
4427 				MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
4428 	}
4429 	pause_result = (ld_pause &
4430 			MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
4431 	pause_result |= (lp_pause &
4432 			 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
4433 	ELINK_DEBUG_P1(sc, "Ext PHY pause result 0x%x", pause_result);
4434 	elink_pause_resolve(phy, params, vars, pause_result);
4435 
4436 }
4437 
elink_ext_phy_resolve_fc(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)4438 static uint8_t elink_ext_phy_resolve_fc(struct elink_phy *phy,
4439 				   struct elink_params *params,
4440 				   struct elink_vars *vars)
4441 {
4442 	uint8_t ret = 0;
4443 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
4444 	if (phy->req_flow_ctrl != ELINK_FLOW_CTRL_AUTO) {
4445 		/* Update the advertised flow-controled of LD/LP in AN */
4446 		if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
4447 			elink_ext_phy_update_adv_fc(phy, params, vars);
4448 		/* But set the flow-control result as the requested one */
4449 		vars->flow_ctrl = phy->req_flow_ctrl;
4450 	} else if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
4451 		vars->flow_ctrl = params->req_fc_auto_adv;
4452 	else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
4453 		ret = 1;
4454 		elink_ext_phy_update_adv_fc(phy, params, vars);
4455 	}
4456 	return ret;
4457 }
4458 /******************************************************************/
4459 /*			Warpcore section			  */
4460 /******************************************************************/
4461 /* The init_internal_warpcore should mirror the xgxs,
4462  * i.e. reset the lane (if needed), set aer for the
4463  * init configuration, and set/clear SGMII flag. Internal
4464  * phy init is done purely in phy_init stage.
4465  */
4466 #define WC_TX_DRIVER(post2, idriver, ipre, ifir) \
4467 	((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \
4468 	 (idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \
4469 	 (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET) | \
4470 	 (ifir << MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET))
4471 
4472 #define WC_TX_FIR(post, main, pre) \
4473 	((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \
4474 	 (main << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | \
4475 	 (pre << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET))
4476 
elink_update_link_attr(struct elink_params * params,uint32_t link_attr)4477 static void elink_update_link_attr(struct elink_params *params,
4478 				   uint32_t link_attr)
4479 {
4480 	struct bnx2x_softc *sc = params->sc;
4481 
4482 	if (SHMEM2_HAS(sc, link_attr_sync))
4483 		REG_WR(sc, params->shmem2_base +
4484 		       offsetof(struct shmem2_region,
4485 				link_attr_sync[params->port]), link_attr);
4486 }
4487 
elink_warpcore_enable_AN_KR2(struct elink_phy * phy,struct elink_params * params,__rte_unused struct elink_vars * vars)4488 static void elink_warpcore_enable_AN_KR2(struct elink_phy *phy,
4489 					 struct elink_params *params,
4490 					 __rte_unused struct elink_vars *vars)
4491 {
4492 	struct bnx2x_softc *sc = params->sc;
4493 	uint16_t i;
4494 	static struct elink_reg_set reg_set[] = {
4495 		/* Step 1 - Program the TX/RX alignment markers */
4496 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0xa157},
4497 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xcbe2},
4498 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0x7537},
4499 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0xa157},
4500 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xcbe2},
4501 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0x7537},
4502 		/* Step 2 - Configure the NP registers */
4503 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000a},
4504 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6400},
4505 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0620},
4506 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0157},
4507 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x6464},
4508 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x3150},
4509 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x3150},
4510 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0157},
4511 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0620}
4512 	};
4513 	ELINK_DEBUG_P0(sc, "Enabling 20G-KR2");
4514 
4515 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4516 				 MDIO_WC_REG_CL49_USERB0_CTRL, (3 << 6));
4517 
4518 	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4519 		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4520 				 reg_set[i].val);
4521 
4522 	/* Start KR2 work-around timer which handles BNX2X8073 link-partner */
4523 	params->link_attr_sync |= LINK_ATTR_SYNC_KR2_ENABLE;
4524 	elink_update_link_attr(params, params->link_attr_sync);
4525 }
4526 
elink_disable_kr2(struct elink_params * params,struct elink_vars * vars,struct elink_phy * phy)4527 static void elink_disable_kr2(struct elink_params *params,
4528 			      struct elink_vars *vars,
4529 			      struct elink_phy *phy)
4530 {
4531 	struct bnx2x_softc *sc = params->sc;
4532 	int i;
4533 	static struct elink_reg_set reg_set[] = {
4534 		/* Step 1 - Program the TX/RX alignment markers */
4535 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0x7690},
4536 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xe647},
4537 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0xc4f0},
4538 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0x7690},
4539 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xe647},
4540 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0xc4f0},
4541 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000c},
4542 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6000},
4543 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0000},
4544 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0002},
4545 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x0000},
4546 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x0af7},
4547 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x0af7},
4548 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0002},
4549 		{MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0000}
4550 	};
4551 	ELINK_DEBUG_P0(sc, "Disabling 20G-KR2");
4552 
4553 	for (i = 0; i < (int)ARRAY_SIZE(reg_set); i++)
4554 		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4555 				 reg_set[i].val);
4556 	params->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE;
4557 	elink_update_link_attr(params, params->link_attr_sync);
4558 
4559 	vars->check_kr2_recovery_cnt = ELINK_CHECK_KR2_RECOVERY_CNT;
4560 }
4561 
elink_warpcore_set_lpi_passthrough(struct elink_phy * phy,struct elink_params * params)4562 static void elink_warpcore_set_lpi_passthrough(struct elink_phy *phy,
4563 					       struct elink_params *params)
4564 {
4565 	struct bnx2x_softc *sc = params->sc;
4566 
4567 	ELINK_DEBUG_P0(sc, "Configure WC for LPI pass through");
4568 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4569 			 MDIO_WC_REG_EEE_COMBO_CONTROL0, 0x7c);
4570 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4571 				 MDIO_WC_REG_DIGITAL4_MISC5, 0xc000);
4572 }
4573 
elink_warpcore_restart_AN_KR(struct elink_phy * phy,struct elink_params * params)4574 static void elink_warpcore_restart_AN_KR(struct elink_phy *phy,
4575 					 struct elink_params *params)
4576 {
4577 	/* Restart autoneg on the leading lane only */
4578 	struct bnx2x_softc *sc = params->sc;
4579 	uint16_t lane = elink_get_warpcore_lane(phy, params);
4580 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4581 			  MDIO_AER_BLOCK_AER_REG, lane);
4582 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4583 			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
4584 
4585 	/* Restore AER */
4586 	elink_set_aer_mmd(params, phy);
4587 }
4588 
elink_warpcore_enable_AN_KR(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)4589 static void elink_warpcore_enable_AN_KR(struct elink_phy *phy,
4590 					struct elink_params *params,
4591 					struct elink_vars *vars) {
4592 	uint16_t lane, i, cl72_ctrl, an_adv = 0, val;
4593 	uint32_t wc_lane_config;
4594 	struct bnx2x_softc *sc = params->sc;
4595 	static struct elink_reg_set reg_set[] = {
4596 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
4597 		{MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0},
4598 		{MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415},
4599 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190},
4600 		/* Disable Autoneg: re-enable it after adv is done. */
4601 		{MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0},
4602 		{MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2},
4603 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0},
4604 	};
4605 	ELINK_DEBUG_P0(sc,  "Enable Auto Negotiation for KR");
4606 	/* Set to default registers that may be overridden by 10G force */
4607 	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4608 		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4609 				 reg_set[i].val);
4610 
4611 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4612 			MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl);
4613 	cl72_ctrl &= 0x08ff;
4614 	cl72_ctrl |= 0x3800;
4615 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4616 			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl);
4617 
4618 	/* Check adding advertisement for 1G KX */
4619 	if (((vars->line_speed == ELINK_SPEED_AUTO_NEG) &&
4620 	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
4621 	    (vars->line_speed == ELINK_SPEED_1000)) {
4622 		uint16_t addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2;
4623 		an_adv |= (1 << 5);
4624 
4625 		/* Enable CL37 1G Parallel Detect */
4626 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD, addr, 0x1);
4627 		ELINK_DEBUG_P0(sc, "Advertize 1G");
4628 	}
4629 	if (((vars->line_speed == ELINK_SPEED_AUTO_NEG) &&
4630 	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
4631 	    (vars->line_speed ==  ELINK_SPEED_10000)) {
4632 		/* Check adding advertisement for 10G KR */
4633 		an_adv |= (1 << 7);
4634 		/* Enable 10G Parallel Detect */
4635 		CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4636 				  MDIO_AER_BLOCK_AER_REG, 0);
4637 
4638 		elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4639 				 MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
4640 		elink_set_aer_mmd(params, phy);
4641 		ELINK_DEBUG_P0(sc, "Advertize 10G");
4642 	}
4643 
4644 	/* Set Transmit PMD settings */
4645 	lane = elink_get_warpcore_lane(phy, params);
4646 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4647 			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * lane,
4648 			 WC_TX_DRIVER(0x02, 0x06, 0x09, 0));
4649 	/* Configure the next lane if dual mode */
4650 	if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
4651 		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4652 				 MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * (lane + 1),
4653 				 WC_TX_DRIVER(0x02, 0x06, 0x09, 0));
4654 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4655 			 MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
4656 			 0x03f0);
4657 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4658 			 MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
4659 			 0x03f0);
4660 
4661 	/* Advertised speeds */
4662 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4663 			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, an_adv);
4664 
4665 	/* Advertised and set FEC (Forward Error Correction) */
4666 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4667 			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2,
4668 			 (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY |
4669 			  MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ));
4670 
4671 	/* Enable CL37 BAM */
4672 	if (REG_RD(sc, params->shmem_base +
4673 		   offsetof(struct shmem_region, dev_info.
4674 			    port_hw_config[params->port].default_cfg)) &
4675 	    PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
4676 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4677 					 MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL,
4678 					 1);
4679 		ELINK_DEBUG_P0(sc, "Enable CL37 BAM on KR");
4680 	}
4681 
4682 	/* Advertise pause */
4683 	elink_ext_phy_set_pause(params, phy, vars);
4684 	vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
4685 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4686 				 MDIO_WC_REG_DIGITAL5_MISC7, 0x100);
4687 
4688 	/* Over 1G - AN local device user page 1 */
4689 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4690 			MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
4691 
4692 	if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
4693 	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) ||
4694 	    (phy->req_line_speed == ELINK_SPEED_20000)) {
4695 
4696 		CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4697 				  MDIO_AER_BLOCK_AER_REG, lane);
4698 
4699 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4700 					 MDIO_WC_REG_RX1_PCI_CTRL +
4701 					 (0x10 * lane),
4702 					 (1 << 11));
4703 
4704 		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4705 				 MDIO_WC_REG_XGXS_X2_CONTROL3, 0x7);
4706 		elink_set_aer_mmd(params, phy);
4707 
4708 		elink_warpcore_enable_AN_KR2(phy, params, vars);
4709 	} else {
4710 		/* Enable Auto-Detect to support 1G over CL37 as well */
4711 		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4712 				 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x10);
4713 		wc_lane_config = REG_RD(sc, params->shmem_base +
4714 					offsetof(struct shmem_region, dev_info.
4715 					shared_hw_config.wc_lane_config));
4716 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4717 				MDIO_WC_REG_RX0_PCI_CTRL + (lane << 4), &val);
4718 		/* Force cl48 sync_status LOW to avoid getting stuck in CL73
4719 		 * parallel-detect loop when CL73 and CL37 are enabled.
4720 		 */
4721 		val |= 1 << 11;
4722 
4723 		/* Restore Polarity settings in case it was run over by
4724 		 * previous link owner
4725 		 */
4726 		if (wc_lane_config &
4727 		    (SHARED_HW_CFG_RX_LANE0_POL_FLIP_ENABLED << lane))
4728 			val |= 3 << 2;
4729 		else
4730 			val &= ~(3 << 2);
4731 		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4732 				 MDIO_WC_REG_RX0_PCI_CTRL + (lane << 4),
4733 				 val);
4734 
4735 		elink_disable_kr2(params, vars, phy);
4736 	}
4737 
4738 	/* Enable Autoneg: only on the main lane */
4739 	elink_warpcore_restart_AN_KR(phy, params);
4740 }
4741 
elink_warpcore_set_10G_KR(struct elink_phy * phy,struct elink_params * params,__rte_unused struct elink_vars * vars)4742 static void elink_warpcore_set_10G_KR(struct elink_phy *phy,
4743 				      struct elink_params *params,
4744 				      __rte_unused struct elink_vars *vars)
4745 {
4746 	struct bnx2x_softc *sc = params->sc;
4747 	uint16_t val16, i, lane;
4748 	static struct elink_reg_set reg_set[] = {
4749 		/* Disable Autoneg */
4750 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
4751 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
4752 			0x3f00},
4753 		{MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0},
4754 		{MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0},
4755 		{MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1},
4756 		{MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa},
4757 		/* Leave cl72 training enable, needed for KR */
4758 		{MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2}
4759 	};
4760 
4761 	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4762 		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4763 				 reg_set[i].val);
4764 
4765 	lane = elink_get_warpcore_lane(phy, params);
4766 	/* Global registers */
4767 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4768 			  MDIO_AER_BLOCK_AER_REG, 0);
4769 	/* Disable CL36 PCS Tx */
4770 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4771 			MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
4772 	val16 &= ~(0x0011 << lane);
4773 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4774 			 MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
4775 
4776 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4777 			MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
4778 	val16 |= (0x0303 << (lane << 1));
4779 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4780 			 MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
4781 	/* Restore AER */
4782 	elink_set_aer_mmd(params, phy);
4783 	/* Set speed via PMA/PMD register */
4784 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD,
4785 			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
4786 
4787 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD,
4788 			 MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
4789 
4790 	/* Enable encoded forced speed */
4791 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4792 			 MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
4793 
4794 	/* Turn TX scramble payload only the 64/66 scrambler */
4795 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4796 			 MDIO_WC_REG_TX66_CONTROL, 0x9);
4797 
4798 	/* Turn RX scramble payload only the 64/66 scrambler */
4799 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4800 				 MDIO_WC_REG_RX66_CONTROL, 0xF9);
4801 
4802 	/* Set and clear loopback to cause a reset to 64/66 decoder */
4803 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4804 			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
4805 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4806 			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
4807 
4808 }
4809 
elink_warpcore_set_10G_XFI(struct elink_phy * phy,struct elink_params * params,uint8_t is_xfi)4810 static void elink_warpcore_set_10G_XFI(struct elink_phy *phy,
4811 				       struct elink_params *params,
4812 				       uint8_t is_xfi)
4813 {
4814 	struct bnx2x_softc *sc = params->sc;
4815 	uint16_t misc1_val, tap_val, tx_driver_val, lane, val;
4816 	uint32_t cfg_tap_val, tx_drv_brdct, tx_equal;
4817 	uint32_t ifir_val, ipost2_val, ipre_driver_val;
4818 	/* Hold rxSeqStart */
4819 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4820 				 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x8000);
4821 
4822 	/* Hold tx_fifo_reset */
4823 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4824 				 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x1);
4825 
4826 	/* Disable CL73 AN */
4827 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
4828 
4829 	/* Disable 100FX Enable and Auto-Detect */
4830 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4831 				  MDIO_WC_REG_FX100_CTRL1, 0xFFFA);
4832 
4833 	/* Disable 100FX Idle detect */
4834 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4835 				 MDIO_WC_REG_FX100_CTRL3, 0x0080);
4836 
4837 	/* Set Block address to Remote PHY & Clear forced_speed[5] */
4838 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4839 				  MDIO_WC_REG_DIGITAL4_MISC3, 0xFF7F);
4840 
4841 	/* Turn off auto-detect & fiber mode */
4842 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4843 				  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4844 				  0xFFEE);
4845 
4846 	/* Set filter_force_link, disable_false_link and parallel_detect */
4847 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4848 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
4849 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4850 			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4851 			 ((val | 0x0006) & 0xFFFE));
4852 
4853 	/* Set XFI / SFI */
4854 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4855 			MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
4856 
4857 	misc1_val &= ~(0x1f);
4858 
4859 	if (is_xfi) {
4860 		misc1_val |= 0x5;
4861 		tap_val = WC_TX_FIR(0x08, 0x37, 0x00);
4862 		tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03, 0);
4863 	} else {
4864 		cfg_tap_val = REG_RD(sc, params->shmem_base +
4865 				     offsetof(struct shmem_region, dev_info.
4866 					      port_hw_config[params->port].
4867 					      sfi_tap_values));
4868 
4869 		tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK;
4870 
4871 		misc1_val |= 0x9;
4872 
4873 		/* TAP values are controlled by nvram, if value there isn't 0 */
4874 		if (tx_equal)
4875 			tap_val = (uint16_t)tx_equal;
4876 		else
4877 			tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02);
4878 
4879 		ifir_val = DEFAULT_TX_DRV_IFIR;
4880 		ipost2_val = DEFAULT_TX_DRV_POST2;
4881 		ipre_driver_val = DEFAULT_TX_DRV_IPRE_DRIVER;
4882 		tx_drv_brdct = DEFAULT_TX_DRV_BRDCT;
4883 
4884 		/* If any of the IFIR/IPRE_DRIVER/POST@ is set, apply all
4885 		 * configuration.
4886 		 */
4887 		if (cfg_tap_val & (PORT_HW_CFG_TX_DRV_IFIR_MASK |
4888 				   PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK |
4889 				   PORT_HW_CFG_TX_DRV_POST2_MASK)) {
4890 			ifir_val = (cfg_tap_val &
4891 				    PORT_HW_CFG_TX_DRV_IFIR_MASK) >>
4892 				PORT_HW_CFG_TX_DRV_IFIR_SHIFT;
4893 			ipre_driver_val = (cfg_tap_val &
4894 					   PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK)
4895 			>> PORT_HW_CFG_TX_DRV_IPREDRIVER_SHIFT;
4896 			ipost2_val = (cfg_tap_val &
4897 				      PORT_HW_CFG_TX_DRV_POST2_MASK) >>
4898 				PORT_HW_CFG_TX_DRV_POST2_SHIFT;
4899 		}
4900 
4901 		if (cfg_tap_val & PORT_HW_CFG_TX_DRV_BROADCAST_MASK) {
4902 			tx_drv_brdct = (cfg_tap_val &
4903 					PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >>
4904 				PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT;
4905 		}
4906 
4907 		tx_driver_val = WC_TX_DRIVER(ipost2_val, tx_drv_brdct,
4908 					     ipre_driver_val, ifir_val);
4909 	}
4910 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4911 			 MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
4912 
4913 	/* Set Transmit PMD settings */
4914 	lane = elink_get_warpcore_lane(phy, params);
4915 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4916 			 MDIO_WC_REG_TX_FIR_TAP,
4917 			 tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
4918 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4919 			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * lane,
4920 			 tx_driver_val);
4921 
4922 	/* Enable fiber mode, enable and invert sig_det */
4923 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4924 				 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0xd);
4925 
4926 	/* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
4927 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4928 				 MDIO_WC_REG_DIGITAL4_MISC3, 0x8080);
4929 
4930 	elink_warpcore_set_lpi_passthrough(phy, params);
4931 
4932 	/* 10G XFI Full Duplex */
4933 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4934 			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
4935 
4936 	/* Release tx_fifo_reset */
4937 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4938 				  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3,
4939 				  0xFFFE);
4940 	/* Release rxSeqStart */
4941 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4942 				  MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x7FFF);
4943 }
4944 
elink_warpcore_set_20G_force_KR2(struct elink_phy * phy,struct elink_params * params)4945 static void elink_warpcore_set_20G_force_KR2(struct elink_phy *phy,
4946 					     struct elink_params *params)
4947 {
4948 	uint16_t val;
4949 	struct bnx2x_softc *sc = params->sc;
4950 	/* Set global registers, so set AER lane to 0 */
4951 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4952 			  MDIO_AER_BLOCK_AER_REG, 0);
4953 
4954 	/* Disable sequencer */
4955 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4956 				  MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, ~(1 << 13));
4957 
4958 	elink_set_aer_mmd(params, phy);
4959 
4960 	elink_cl45_read_and_write(sc, phy, MDIO_PMA_DEVAD,
4961 				  MDIO_WC_REG_PMD_KR_CONTROL, ~(1 << 1));
4962 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4963 			 MDIO_AN_REG_CTRL, 0);
4964 	/* Turn off CL73 */
4965 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4966 			MDIO_WC_REG_CL73_USERB0_CTRL, &val);
4967 	val &= ~(1 << 5);
4968 	val |= (1 << 6);
4969 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4970 			 MDIO_WC_REG_CL73_USERB0_CTRL, val);
4971 
4972 	/* Set 20G KR2 force speed */
4973 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4974 				 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x1f);
4975 
4976 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4977 				 MDIO_WC_REG_DIGITAL4_MISC3, (1 << 7));
4978 
4979 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4980 			MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &val);
4981 	val &= ~(3 << 14);
4982 	val |= (1 << 15);
4983 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4984 			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, val);
4985 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4986 			 MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0x835A);
4987 
4988 	/* Enable sequencer (over lane 0) */
4989 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4990 			  MDIO_AER_BLOCK_AER_REG, 0);
4991 
4992 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4993 				 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, (1 << 13));
4994 
4995 	elink_set_aer_mmd(params, phy);
4996 }
4997 
elink_warpcore_set_20G_DXGXS(struct bnx2x_softc * sc,struct elink_phy * phy,uint16_t lane)4998 static void elink_warpcore_set_20G_DXGXS(struct bnx2x_softc *sc,
4999 					 struct elink_phy *phy,
5000 					 uint16_t lane)
5001 {
5002 	/* Rx0 anaRxControl1G */
5003 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5004 			 MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
5005 
5006 	/* Rx2 anaRxControl1G */
5007 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5008 			 MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
5009 
5010 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5011 			 MDIO_WC_REG_RX66_SCW0, 0xE070);
5012 
5013 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5014 			 MDIO_WC_REG_RX66_SCW1, 0xC0D0);
5015 
5016 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5017 			 MDIO_WC_REG_RX66_SCW2, 0xA0B0);
5018 
5019 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5020 			 MDIO_WC_REG_RX66_SCW3, 0x8090);
5021 
5022 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5023 			 MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
5024 
5025 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5026 			 MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
5027 
5028 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5029 			 MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
5030 
5031 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5032 			 MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
5033 
5034 	/* Serdes Digital Misc1 */
5035 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5036 			 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
5037 
5038 	/* Serdes Digital4 Misc3 */
5039 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5040 			 MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
5041 
5042 	/* Set Transmit PMD settings */
5043 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5044 			 MDIO_WC_REG_TX_FIR_TAP,
5045 			 (WC_TX_FIR(0x12, 0x2d, 0x00) |
5046 			  MDIO_WC_REG_TX_FIR_TAP_ENABLE));
5047 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5048 			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * lane,
5049 			 WC_TX_DRIVER(0x02, 0x02, 0x02, 0));
5050 }
5051 
elink_warpcore_set_sgmii_speed(struct elink_phy * phy,struct elink_params * params,uint8_t fiber_mode,uint8_t always_autoneg)5052 static void elink_warpcore_set_sgmii_speed(struct elink_phy *phy,
5053 					   struct elink_params *params,
5054 					   uint8_t fiber_mode,
5055 					   uint8_t always_autoneg)
5056 {
5057 	struct bnx2x_softc *sc = params->sc;
5058 	uint16_t val16, digctrl_kx1, digctrl_kx2;
5059 
5060 	/* Clear XFI clock comp in non-10G single lane mode. */
5061 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5062 				  MDIO_WC_REG_RX66_CONTROL, ~(3 << 13));
5063 
5064 	elink_warpcore_set_lpi_passthrough(phy, params);
5065 
5066 	if (always_autoneg || phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
5067 		/* SGMII Autoneg */
5068 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5069 					 MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
5070 					 0x1000);
5071 		ELINK_DEBUG_P0(sc, "set SGMII AUTONEG");
5072 	} else {
5073 	/* Note that 2.5G works only when used with 1G advertisement */
5074 		if (fiber_mode && phy->req_line_speed == SPEED_2500 &&
5075 		   (phy->speed_cap_mask &
5076 		   (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
5077 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))) {
5078 			elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5079 			MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6010);
5080 		}
5081 
5082 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5083 				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
5084 		val16 &= 0xcebf;
5085 		switch (phy->req_line_speed) {
5086 		case ELINK_SPEED_10:
5087 			break;
5088 		case ELINK_SPEED_100:
5089 			val16 |= 0x2000;
5090 			break;
5091 		case ELINK_SPEED_1000:
5092 		case ELINK_SPEED_2500:
5093 			val16 |= 0x0040;
5094 			break;
5095 		default:
5096 			ELINK_DEBUG_P1(sc,
5097 			   "Speed not supported: 0x%x", phy->req_line_speed);
5098 			return;
5099 		}
5100 
5101 		if (phy->req_duplex == DUPLEX_FULL)
5102 			val16 |= 0x0100;
5103 
5104 		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5105 				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
5106 
5107 		ELINK_DEBUG_P1(sc, "set SGMII force speed %d",
5108 			       phy->req_line_speed);
5109 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5110 				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
5111 		ELINK_DEBUG_P1(sc, "  (readback) %x", val16);
5112 	}
5113 
5114 	/* SGMII Slave mode and disable signal detect */
5115 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5116 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
5117 	if (fiber_mode)
5118 		digctrl_kx1 = 1;
5119 	else
5120 		digctrl_kx1 &= 0xff4a;
5121 
5122 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5123 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
5124 			digctrl_kx1);
5125 
5126 	/* Turn off parallel detect */
5127 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5128 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
5129 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5130 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
5131 			(digctrl_kx2 & ~(1 << 2)));
5132 
5133 	/* Re-enable parallel detect */
5134 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5135 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
5136 			(digctrl_kx2 | (1 << 2)));
5137 
5138 	/* Enable autodet */
5139 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5140 			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
5141 			(digctrl_kx1 | 0x10));
5142 }
5143 
5144 
elink_warpcore_reset_lane(struct bnx2x_softc * sc,struct elink_phy * phy,uint8_t reset)5145 static void elink_warpcore_reset_lane(struct bnx2x_softc *sc,
5146 				      struct elink_phy *phy,
5147 				      uint8_t reset)
5148 {
5149 	uint16_t val;
5150 	/* Take lane out of reset after configuration is finished */
5151 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5152 			MDIO_WC_REG_DIGITAL5_MISC6, &val);
5153 	if (reset)
5154 		val |= 0xC000;
5155 	else
5156 		val &= 0x3FFF;
5157 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5158 			 MDIO_WC_REG_DIGITAL5_MISC6, val);
5159 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5160 			 MDIO_WC_REG_DIGITAL5_MISC6, &val);
5161 }
5162 
5163 /* Clear SFI/XFI link settings registers */
elink_warpcore_clear_regs(struct elink_phy * phy,struct elink_params * params,uint16_t lane)5164 static void elink_warpcore_clear_regs(struct elink_phy *phy,
5165 				      struct elink_params *params,
5166 				      uint16_t lane)
5167 {
5168 	struct bnx2x_softc *sc = params->sc;
5169 	uint16_t i;
5170 	static struct elink_reg_set wc_regs[] = {
5171 		{MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0},
5172 		{MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL1, 0x014a},
5173 		{MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL3, 0x0800},
5174 		{MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL4_MISC3, 0x8008},
5175 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
5176 			0x0195},
5177 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
5178 			0x0007},
5179 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3,
5180 			0x0002},
5181 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000},
5182 		{MDIO_WC_DEVAD, MDIO_WC_REG_TX_FIR_TAP, 0x0000},
5183 		{MDIO_WC_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040},
5184 		{MDIO_WC_DEVAD, MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140}
5185 	};
5186 	/* Set XFI clock comp as default. */
5187 	elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5188 				 MDIO_WC_REG_RX66_CONTROL, (3 << 13));
5189 
5190 	for (i = 0; i < ARRAY_SIZE(wc_regs); i++)
5191 		elink_cl45_write(sc, phy, wc_regs[i].devad, wc_regs[i].reg,
5192 				 wc_regs[i].val);
5193 
5194 	lane = elink_get_warpcore_lane(phy, params);
5195 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5196 			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * lane, 0x0990);
5197 
5198 }
5199 
elink_get_mod_abs_int_cfg(struct bnx2x_softc * sc,__rte_unused uint32_t chip_id,uint32_t shmem_base,uint8_t port,uint8_t * gpio_num,uint8_t * gpio_port)5200 static elink_status_t elink_get_mod_abs_int_cfg(struct bnx2x_softc *sc,
5201 						__rte_unused uint32_t chip_id,
5202 						uint32_t shmem_base,
5203 						uint8_t port,
5204 						uint8_t *gpio_num,
5205 						uint8_t *gpio_port)
5206 {
5207 	uint32_t cfg_pin;
5208 	*gpio_num = 0;
5209 	*gpio_port = 0;
5210 	if (CHIP_IS_E3(sc)) {
5211 		cfg_pin = (REG_RD(sc, shmem_base +
5212 				offsetof(struct shmem_region,
5213 				dev_info.port_hw_config[port].e3_sfp_ctrl)) &
5214 				PORT_HW_CFG_E3_MOD_ABS_MASK) >>
5215 				PORT_HW_CFG_E3_MOD_ABS_SHIFT;
5216 
5217 		/*
5218 		 * This should not happen since this function is called
5219 		 * from interrupt triggered by GPIO (since EPIO can only
5220 		 * generate interrupts to MCP).
5221 		 * So if this function was called and none of the GPIOs was set,
5222 		 * it means something disastrous has already happened.
5223 		 */
5224 		if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
5225 		    (cfg_pin > PIN_CFG_GPIO3_P1)) {
5226 			ELINK_DEBUG_P1(sc,
5227 			   "No cfg pin %x for module detect indication",
5228 			   cfg_pin);
5229 			return ELINK_STATUS_ERROR;
5230 		}
5231 
5232 		*gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
5233 		*gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
5234 	} else {
5235 		*gpio_num = MISC_REGISTERS_GPIO_3;
5236 		*gpio_port = port;
5237 	}
5238 
5239 	return ELINK_STATUS_OK;
5240 }
5241 
elink_is_sfp_module_plugged(__rte_unused struct elink_phy * phy,struct elink_params * params)5242 static int elink_is_sfp_module_plugged(__rte_unused struct elink_phy *phy,
5243 				       struct elink_params *params)
5244 {
5245 	struct bnx2x_softc *sc = params->sc;
5246 	uint8_t gpio_num, gpio_port;
5247 	uint32_t gpio_val;
5248 	if (elink_get_mod_abs_int_cfg(sc, params->chip_id,
5249 				      params->shmem_base, params->port,
5250 				      &gpio_num, &gpio_port) != ELINK_STATUS_OK)
5251 		return 0;
5252 	gpio_val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
5253 
5254 	/* Call the handling function in case module is detected */
5255 	if (gpio_val == 0)
5256 		return 1;
5257 	else
5258 		return 0;
5259 }
elink_warpcore_get_sigdet(struct elink_phy * phy,struct elink_params * params)5260 static int elink_warpcore_get_sigdet(struct elink_phy *phy,
5261 				     struct elink_params *params)
5262 {
5263 	uint16_t gp2_status_reg0, lane;
5264 	struct bnx2x_softc *sc = params->sc;
5265 
5266 	lane = elink_get_warpcore_lane(phy, params);
5267 
5268 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
5269 				 &gp2_status_reg0);
5270 
5271 	return (gp2_status_reg0 >> (8 + lane)) & 0x1;
5272 }
5273 
elink_warpcore_config_runtime(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)5274 static void elink_warpcore_config_runtime(struct elink_phy *phy,
5275 					  struct elink_params *params,
5276 					  struct elink_vars *vars)
5277 {
5278 	struct bnx2x_softc *sc = params->sc;
5279 	uint32_t serdes_net_if;
5280 	uint16_t gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
5281 
5282 	vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
5283 
5284 	if (!vars->turn_to_run_wc_rt)
5285 		return;
5286 
5287 	if (vars->rx_tx_asic_rst) {
5288 		uint16_t lane = elink_get_warpcore_lane(phy, params);
5289 		serdes_net_if = (REG_RD(sc, params->shmem_base +
5290 				offsetof(struct shmem_region, dev_info.
5291 				port_hw_config[params->port].default_cfg)) &
5292 				PORT_HW_CFG_NET_SERDES_IF_MASK);
5293 
5294 		switch (serdes_net_if) {
5295 		case PORT_HW_CFG_NET_SERDES_IF_KR:
5296 			/* Do we get link yet? */
5297 			elink_cl45_read(sc, phy, MDIO_WC_DEVAD, 0x81d1,
5298 					&gp_status1);
5299 			lnkup = (gp_status1 >> (8 + lane)) & 0x1;/* 1G */
5300 				/*10G KR*/
5301 			lnkup_kr = (gp_status1 >> (12 + lane)) & 0x1;
5302 
5303 			if (lnkup_kr || lnkup) {
5304 				vars->rx_tx_asic_rst = 0;
5305 			} else {
5306 				/* Reset the lane to see if link comes up.*/
5307 				elink_warpcore_reset_lane(sc, phy, 1);
5308 				elink_warpcore_reset_lane(sc, phy, 0);
5309 
5310 				/* Restart Autoneg */
5311 				elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
5312 					MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
5313 
5314 				vars->rx_tx_asic_rst--;
5315 				ELINK_DEBUG_P1(sc, "0x%x retry left",
5316 				vars->rx_tx_asic_rst);
5317 			}
5318 			break;
5319 
5320 		default:
5321 			break;
5322 		}
5323 
5324 	} /*params->rx_tx_asic_rst*/
5325 }
5326 
elink_warpcore_config_sfi(struct elink_phy * phy,struct elink_params * params)5327 static void elink_warpcore_config_sfi(struct elink_phy *phy,
5328 				      struct elink_params *params)
5329 {
5330 	uint16_t lane = elink_get_warpcore_lane(phy, params);
5331 	struct bnx2x_softc *sc = params->sc;
5332 	elink_warpcore_clear_regs(phy, params, lane);
5333 	if ((params->req_line_speed[ELINK_LINK_CONFIG_IDX(ELINK_INT_PHY)] ==
5334 	     ELINK_SPEED_10000) &&
5335 	    (phy->media_type != ELINK_ETH_PHY_SFP_1G_FIBER)) {
5336 		ELINK_DEBUG_P0(sc, "Setting 10G SFI");
5337 		elink_warpcore_set_10G_XFI(phy, params, 0);
5338 	} else {
5339 		ELINK_DEBUG_P0(sc, "Setting 1G Fiber");
5340 		elink_warpcore_set_sgmii_speed(phy, params, 1, 0);
5341 	}
5342 }
5343 
elink_sfp_e3_set_transmitter(struct elink_params * params,struct elink_phy * phy,uint8_t tx_en)5344 static void elink_sfp_e3_set_transmitter(struct elink_params *params,
5345 					 struct elink_phy *phy,
5346 					 uint8_t tx_en)
5347 {
5348 	struct bnx2x_softc *sc = params->sc;
5349 	uint32_t cfg_pin;
5350 	uint8_t port = params->port;
5351 
5352 	cfg_pin = REG_RD(sc, params->shmem_base +
5353 			 offsetof(struct shmem_region,
5354 				  dev_info.port_hw_config[port].e3_sfp_ctrl)) &
5355 		PORT_HW_CFG_E3_TX_LASER_MASK;
5356 	/* Set the !tx_en since this pin is DISABLE_TX_LASER */
5357 	ELINK_DEBUG_P1(sc, "Setting WC TX to %d", tx_en);
5358 
5359 	/* For 20G, the expected pin to be used is 3 pins after the current */
5360 	elink_set_cfg_pin(sc, cfg_pin, tx_en ^ 1);
5361 	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
5362 		elink_set_cfg_pin(sc, cfg_pin + 3, tx_en ^ 1);
5363 }
5364 
elink_warpcore_config_init(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)5365 static uint8_t elink_warpcore_config_init(struct elink_phy *phy,
5366 				       struct elink_params *params,
5367 				       struct elink_vars *vars)
5368 {
5369 	struct bnx2x_softc *sc = params->sc;
5370 	uint32_t serdes_net_if;
5371 	uint8_t fiber_mode;
5372 	uint16_t lane = elink_get_warpcore_lane(phy, params);
5373 	serdes_net_if = (REG_RD(sc, params->shmem_base +
5374 			 offsetof(struct shmem_region, dev_info.
5375 				  port_hw_config[params->port].default_cfg)) &
5376 			 PORT_HW_CFG_NET_SERDES_IF_MASK);
5377 	ELINK_DEBUG_P2(sc, "Begin Warpcore init, link_speed %d, "
5378 			   "serdes_net_if = 0x%x",
5379 		       vars->line_speed, serdes_net_if);
5380 	elink_set_aer_mmd(params, phy);
5381 	elink_warpcore_reset_lane(sc, phy, 1);
5382 	vars->phy_flags |= PHY_XGXS_FLAG;
5383 	if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
5384 	    (phy->req_line_speed &&
5385 	     ((phy->req_line_speed == ELINK_SPEED_100) ||
5386 	      (phy->req_line_speed == ELINK_SPEED_10)))) {
5387 		vars->phy_flags |= PHY_SGMII_FLAG;
5388 		ELINK_DEBUG_P0(sc, "Setting SGMII mode");
5389 		elink_warpcore_clear_regs(phy, params, lane);
5390 		elink_warpcore_set_sgmii_speed(phy, params, 0, 1);
5391 	} else {
5392 		switch (serdes_net_if) {
5393 		case PORT_HW_CFG_NET_SERDES_IF_KR:
5394 			/* Enable KR Auto Neg */
5395 			if (params->loopback_mode != ELINK_LOOPBACK_EXT)
5396 				elink_warpcore_enable_AN_KR(phy, params, vars);
5397 			else {
5398 				ELINK_DEBUG_P0(sc, "Setting KR 10G-Force");
5399 				elink_warpcore_set_10G_KR(phy, params, vars);
5400 			}
5401 			break;
5402 
5403 		case PORT_HW_CFG_NET_SERDES_IF_XFI:
5404 			elink_warpcore_clear_regs(phy, params, lane);
5405 			if (vars->line_speed == ELINK_SPEED_10000) {
5406 				ELINK_DEBUG_P0(sc, "Setting 10G XFI");
5407 				elink_warpcore_set_10G_XFI(phy, params, 1);
5408 			} else {
5409 				if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
5410 					ELINK_DEBUG_P0(sc, "1G Fiber");
5411 					fiber_mode = 1;
5412 				} else {
5413 					ELINK_DEBUG_P0(sc, "10/100/1G SGMII");
5414 					fiber_mode = 0;
5415 				}
5416 				elink_warpcore_set_sgmii_speed(phy,
5417 								params,
5418 								fiber_mode,
5419 								0);
5420 			}
5421 
5422 			break;
5423 
5424 		case PORT_HW_CFG_NET_SERDES_IF_SFI:
5425 			/* Issue Module detection if module is plugged, or
5426 			 * enabled transmitter to avoid current leakage in case
5427 			 * no module is connected
5428 			 */
5429 			if ((params->loopback_mode == ELINK_LOOPBACK_NONE) ||
5430 			    (params->loopback_mode == ELINK_LOOPBACK_EXT)) {
5431 				if (elink_is_sfp_module_plugged(phy, params))
5432 					elink_sfp_module_detection(phy, params);
5433 				else
5434 					elink_sfp_e3_set_transmitter(params,
5435 								     phy, 1);
5436 			}
5437 
5438 			elink_warpcore_config_sfi(phy, params);
5439 			break;
5440 
5441 		case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
5442 			if (vars->line_speed != ELINK_SPEED_20000) {
5443 				ELINK_DEBUG_P0(sc, "Speed not supported yet");
5444 				return 0;
5445 			}
5446 			ELINK_DEBUG_P0(sc, "Setting 20G DXGXS");
5447 			elink_warpcore_set_20G_DXGXS(sc, phy, lane);
5448 			/* Issue Module detection */
5449 
5450 			elink_sfp_module_detection(phy, params);
5451 			break;
5452 		case PORT_HW_CFG_NET_SERDES_IF_KR2:
5453 			if (!params->loopback_mode) {
5454 				elink_warpcore_enable_AN_KR(phy, params, vars);
5455 			} else {
5456 				ELINK_DEBUG_P0(sc, "Setting KR 20G-Force");
5457 				elink_warpcore_set_20G_force_KR2(phy, params);
5458 			}
5459 			break;
5460 		default:
5461 			ELINK_DEBUG_P1(sc,
5462 			   "Unsupported Serdes Net Interface 0x%x",
5463 			   serdes_net_if);
5464 			return 0;
5465 		}
5466 	}
5467 
5468 	/* Take lane out of reset after configuration is finished */
5469 	elink_warpcore_reset_lane(sc, phy, 0);
5470 	ELINK_DEBUG_P0(sc, "Exit config init");
5471 
5472 	return 0;
5473 }
5474 
elink_warpcore_link_reset(struct elink_phy * phy,struct elink_params * params)5475 static void elink_warpcore_link_reset(struct elink_phy *phy,
5476 				      struct elink_params *params)
5477 {
5478 	struct bnx2x_softc *sc = params->sc;
5479 	uint16_t val16, lane;
5480 	elink_sfp_e3_set_transmitter(params, phy, 0);
5481 	elink_set_mdio_emac_per_phy(sc, params);
5482 	elink_set_aer_mmd(params, phy);
5483 	/* Global register */
5484 	elink_warpcore_reset_lane(sc, phy, 1);
5485 
5486 	/* Clear loopback settings (if any) */
5487 	/* 10G & 20G */
5488 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5489 				  MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0xBFFF);
5490 
5491 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5492 				  MDIO_WC_REG_IEEE0BLK_MIICNTL, 0xfffe);
5493 
5494 	/* Update those 1-copy registers */
5495 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
5496 			  MDIO_AER_BLOCK_AER_REG, 0);
5497 	/* Enable 1G MDIO (1-copy) */
5498 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5499 				  MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
5500 				  ~0x10);
5501 
5502 	elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5503 				  MDIO_WC_REG_XGXSBLK1_LANECTRL2, 0xff00);
5504 	lane = elink_get_warpcore_lane(phy, params);
5505 	/* Disable CL36 PCS Tx */
5506 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5507 			MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
5508 	val16 |= (0x11 << lane);
5509 	if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
5510 		val16 |= (0x22 << lane);
5511 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5512 			 MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
5513 
5514 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5515 			MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
5516 	val16 &= ~(0x0303 << (lane << 1));
5517 	val16 |= (0x0101 << (lane << 1));
5518 	if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE) {
5519 		val16 &= ~(0x0c0c << (lane << 1));
5520 		val16 |= (0x0404 << (lane << 1));
5521 	}
5522 
5523 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5524 			 MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
5525 	/* Restore AER */
5526 	elink_set_aer_mmd(params, phy);
5527 
5528 }
5529 
elink_set_warpcore_loopback(struct elink_phy * phy,struct elink_params * params)5530 static void elink_set_warpcore_loopback(struct elink_phy *phy,
5531 					struct elink_params *params)
5532 {
5533 	struct bnx2x_softc *sc = params->sc;
5534 	uint16_t val16;
5535 	uint32_t lane;
5536 	ELINK_DEBUG_P2(sc, "Setting Warpcore loopback type %x, speed %d",
5537 		       params->loopback_mode, phy->req_line_speed);
5538 
5539 	if (phy->req_line_speed < ELINK_SPEED_10000 ||
5540 	    phy->supported & ELINK_SUPPORTED_20000baseKR2_Full) {
5541 		/* 10/100/1000/20G-KR2 */
5542 
5543 		/* Update those 1-copy registers */
5544 		CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
5545 				  MDIO_AER_BLOCK_AER_REG, 0);
5546 		/* Enable 1G MDIO (1-copy) */
5547 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5548 					 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
5549 					 0x10);
5550 		/* Set 1G loopback based on lane (1-copy) */
5551 		lane = elink_get_warpcore_lane(phy, params);
5552 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5553 				MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
5554 		val16 |= (1 << lane);
5555 		if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
5556 			val16 |= (2 << lane);
5557 		elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5558 				 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
5559 				 val16);
5560 
5561 		/* Switch back to 4-copy registers */
5562 		elink_set_aer_mmd(params, phy);
5563 	} else {
5564 		/* 10G / 20G-DXGXS */
5565 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5566 					 MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
5567 					 0x4000);
5568 		elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5569 					 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1);
5570 	}
5571 }
5572 
5573 
5574 
elink_sync_link(struct elink_params * params,struct elink_vars * vars)5575 static void elink_sync_link(struct elink_params *params,
5576 			     struct elink_vars *vars)
5577 {
5578 	struct bnx2x_softc *sc = params->sc;
5579 	uint8_t link_10g_plus;
5580 	if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
5581 		vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
5582 	vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
5583 	if (vars->link_up) {
5584 		ELINK_DEBUG_P0(sc, "phy link up");
5585 		ELINK_DEBUG_P1(sc, "link status = %x", vars->link_status);
5586 
5587 		vars->phy_link_up = 1;
5588 		vars->duplex = DUPLEX_FULL;
5589 		switch (vars->link_status &
5590 			LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
5591 		case ELINK_LINK_10THD:
5592 			vars->duplex = DUPLEX_HALF;
5593 			/* Fall thru */
5594 		case ELINK_LINK_10TFD:
5595 			vars->line_speed = ELINK_SPEED_10;
5596 			break;
5597 
5598 		case ELINK_LINK_100TXHD:
5599 			vars->duplex = DUPLEX_HALF;
5600 			/* Fall thru */
5601 		case ELINK_LINK_100T4:
5602 		case ELINK_LINK_100TXFD:
5603 			vars->line_speed = ELINK_SPEED_100;
5604 			break;
5605 
5606 		case ELINK_LINK_1000THD:
5607 			vars->duplex = DUPLEX_HALF;
5608 			/* Fall thru */
5609 		case ELINK_LINK_1000TFD:
5610 			vars->line_speed = ELINK_SPEED_1000;
5611 			break;
5612 
5613 		case ELINK_LINK_2500THD:
5614 			vars->duplex = DUPLEX_HALF;
5615 			/* Fall thru */
5616 		case ELINK_LINK_2500TFD:
5617 			vars->line_speed = ELINK_SPEED_2500;
5618 			break;
5619 
5620 		case ELINK_LINK_10GTFD:
5621 			vars->line_speed = ELINK_SPEED_10000;
5622 			break;
5623 		case ELINK_LINK_20GTFD:
5624 			vars->line_speed = ELINK_SPEED_20000;
5625 			break;
5626 		default:
5627 			break;
5628 		}
5629 		vars->flow_ctrl = 0;
5630 		if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
5631 			vars->flow_ctrl |= ELINK_FLOW_CTRL_TX;
5632 
5633 		if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
5634 			vars->flow_ctrl |= ELINK_FLOW_CTRL_RX;
5635 
5636 		if (!vars->flow_ctrl)
5637 			vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
5638 
5639 		if (vars->line_speed &&
5640 		    ((vars->line_speed == ELINK_SPEED_10) ||
5641 		     (vars->line_speed == ELINK_SPEED_100))) {
5642 			vars->phy_flags |= PHY_SGMII_FLAG;
5643 		} else {
5644 			vars->phy_flags &= ~PHY_SGMII_FLAG;
5645 		}
5646 		if (vars->line_speed &&
5647 		    USES_WARPCORE(sc) &&
5648 		    (vars->line_speed == ELINK_SPEED_1000))
5649 			vars->phy_flags |= PHY_SGMII_FLAG;
5650 		/* Anything 10 and over uses the bmac */
5651 		link_10g_plus = (vars->line_speed >= ELINK_SPEED_10000);
5652 
5653 		if (link_10g_plus) {
5654 			if (USES_WARPCORE(sc))
5655 				vars->mac_type = ELINK_MAC_TYPE_XMAC;
5656 			else
5657 				vars->mac_type = ELINK_MAC_TYPE_BMAC;
5658 		} else {
5659 			if (USES_WARPCORE(sc))
5660 				vars->mac_type = ELINK_MAC_TYPE_UMAC;
5661 			else
5662 				vars->mac_type = ELINK_MAC_TYPE_EMAC;
5663 		}
5664 	} else { /* Link down */
5665 		ELINK_DEBUG_P0(sc, "phy link down");
5666 
5667 		vars->phy_link_up = 0;
5668 
5669 		vars->line_speed = 0;
5670 		vars->duplex = DUPLEX_FULL;
5671 		vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
5672 
5673 		/* Indicate no mac active */
5674 		vars->mac_type = ELINK_MAC_TYPE_NONE;
5675 		if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
5676 			vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
5677 		if (vars->link_status & LINK_STATUS_SFP_TX_FAULT)
5678 			vars->phy_flags |= PHY_SFP_TX_FAULT_FLAG;
5679 	}
5680 }
5681 
elink_link_status_update(struct elink_params * params,struct elink_vars * vars)5682 void elink_link_status_update(struct elink_params *params,
5683 			      struct elink_vars *vars)
5684 {
5685 	struct bnx2x_softc *sc = params->sc;
5686 	uint8_t port = params->port;
5687 	uint32_t sync_offset, media_types;
5688 	/* Update PHY configuration */
5689 	set_phy_vars(params, vars);
5690 
5691 	vars->link_status = REG_RD(sc, params->shmem_base +
5692 				   offsetof(struct shmem_region,
5693 					    port_mb[port].link_status));
5694 
5695 	/* Force link UP in non LOOPBACK_EXT loopback mode(s) */
5696 	if (params->loopback_mode != ELINK_LOOPBACK_NONE &&
5697 	    params->loopback_mode != ELINK_LOOPBACK_EXT)
5698 		vars->link_status |= LINK_STATUS_LINK_UP;
5699 
5700 	if (elink_eee_has_cap(params))
5701 		vars->eee_status = REG_RD(sc, params->shmem2_base +
5702 					  offsetof(struct shmem2_region,
5703 						   eee_status[params->port]));
5704 
5705 	vars->phy_flags = PHY_XGXS_FLAG;
5706 	elink_sync_link(params, vars);
5707 	/* Sync media type */
5708 	sync_offset = params->shmem_base +
5709 			offsetof(struct shmem_region,
5710 				 dev_info.port_hw_config[port].media_type);
5711 	media_types = REG_RD(sc, sync_offset);
5712 
5713 	params->phy[ELINK_INT_PHY].media_type =
5714 		(media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
5715 		PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
5716 	params->phy[ELINK_EXT_PHY1].media_type =
5717 		(media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
5718 		PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
5719 	params->phy[ELINK_EXT_PHY2].media_type =
5720 		(media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
5721 		PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
5722 	ELINK_DEBUG_P1(sc, "media_types = 0x%x", media_types);
5723 
5724 	/* Sync AEU offset */
5725 	sync_offset = params->shmem_base +
5726 			offsetof(struct shmem_region,
5727 				 dev_info.port_hw_config[port].aeu_int_mask);
5728 
5729 	vars->aeu_int_mask = REG_RD(sc, sync_offset);
5730 
5731 	/* Sync PFC status */
5732 	if (vars->link_status & LINK_STATUS_PFC_ENABLED)
5733 		params->feature_config_flags |=
5734 					ELINK_FEATURE_CONFIG_PFC_ENABLED;
5735 	else
5736 		params->feature_config_flags &=
5737 					~ELINK_FEATURE_CONFIG_PFC_ENABLED;
5738 
5739 	if (SHMEM2_HAS(sc, link_attr_sync))
5740 		params->link_attr_sync = SHMEM2_RD(sc,
5741 						 link_attr_sync[params->port]);
5742 
5743 	ELINK_DEBUG_P3(sc, "link_status 0x%x  phy_link_up %x int_mask 0x%x",
5744 		 vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
5745 	ELINK_DEBUG_P3(sc, "line_speed %x  duplex %x  flow_ctrl 0x%x",
5746 		 vars->line_speed, vars->duplex, vars->flow_ctrl);
5747 }
5748 
elink_set_master_ln(struct elink_params * params,struct elink_phy * phy)5749 static void elink_set_master_ln(struct elink_params *params,
5750 				struct elink_phy *phy)
5751 {
5752 	struct bnx2x_softc *sc = params->sc;
5753 	uint16_t new_master_ln, ser_lane;
5754 	ser_lane = ((params->lane_config &
5755 		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5756 		    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5757 
5758 	/* Set the master_ln for AN */
5759 	CL22_RD_OVER_CL45(sc, phy,
5760 			  MDIO_REG_BANK_XGXS_BLOCK2,
5761 			  MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
5762 			  &new_master_ln);
5763 
5764 	CL22_WR_OVER_CL45(sc, phy,
5765 			  MDIO_REG_BANK_XGXS_BLOCK2,
5766 			  MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
5767 			  (new_master_ln | ser_lane));
5768 }
5769 
elink_reset_unicore(struct elink_params * params,struct elink_phy * phy,uint8_t set_serdes)5770 static elink_status_t elink_reset_unicore(struct elink_params *params,
5771 			       struct elink_phy *phy,
5772 			       uint8_t set_serdes)
5773 {
5774 	struct bnx2x_softc *sc = params->sc;
5775 	uint16_t mii_control;
5776 	uint16_t i;
5777 	CL22_RD_OVER_CL45(sc, phy,
5778 			  MDIO_REG_BANK_COMBO_IEEE0,
5779 			  MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
5780 
5781 	/* Reset the unicore */
5782 	CL22_WR_OVER_CL45(sc, phy,
5783 			  MDIO_REG_BANK_COMBO_IEEE0,
5784 			  MDIO_COMBO_IEEE0_MII_CONTROL,
5785 			  (mii_control |
5786 			   MDIO_COMBO_IEEO_MII_CONTROL_RESET));
5787 	if (set_serdes)
5788 		elink_set_serdes_access(sc, params->port);
5789 
5790 	/* Wait for the reset to self clear */
5791 	for (i = 0; i < ELINK_MDIO_ACCESS_TIMEOUT; i++) {
5792 		DELAY(5);
5793 
5794 		/* The reset erased the previous bank value */
5795 		CL22_RD_OVER_CL45(sc, phy,
5796 				  MDIO_REG_BANK_COMBO_IEEE0,
5797 				  MDIO_COMBO_IEEE0_MII_CONTROL,
5798 				  &mii_control);
5799 
5800 		if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
5801 			DELAY(5);
5802 			return ELINK_STATUS_OK;
5803 		}
5804 	}
5805 
5806 	elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED, params->port);
5807 			     /* "Warning: PHY was not initialized,"
5808 			      * " Port %d",
5809 			      */
5810 
5811 	ELINK_DEBUG_P0(sc, "BUG! XGXS is still in reset!");
5812 	return ELINK_STATUS_ERROR;
5813 
5814 }
5815 
elink_set_swap_lanes(struct elink_params * params,struct elink_phy * phy)5816 static void elink_set_swap_lanes(struct elink_params *params,
5817 				 struct elink_phy *phy)
5818 {
5819 	struct bnx2x_softc *sc = params->sc;
5820 	/* Each two bits represents a lane number:
5821 	 * No swap is 0123 => 0x1b no need to enable the swap
5822 	 */
5823 	uint16_t rx_lane_swap, tx_lane_swap;
5824 
5825 	rx_lane_swap = ((params->lane_config &
5826 			 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
5827 			PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
5828 	tx_lane_swap = ((params->lane_config &
5829 			 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
5830 			PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
5831 
5832 	if (rx_lane_swap != 0x1b) {
5833 		CL22_WR_OVER_CL45(sc, phy,
5834 				  MDIO_REG_BANK_XGXS_BLOCK2,
5835 				  MDIO_XGXS_BLOCK2_RX_LN_SWAP,
5836 				  (rx_lane_swap |
5837 				   MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
5838 				   MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
5839 	} else {
5840 		CL22_WR_OVER_CL45(sc, phy,
5841 				  MDIO_REG_BANK_XGXS_BLOCK2,
5842 				  MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
5843 	}
5844 
5845 	if (tx_lane_swap != 0x1b) {
5846 		CL22_WR_OVER_CL45(sc, phy,
5847 				  MDIO_REG_BANK_XGXS_BLOCK2,
5848 				  MDIO_XGXS_BLOCK2_TX_LN_SWAP,
5849 				  (tx_lane_swap |
5850 				   MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
5851 	} else {
5852 		CL22_WR_OVER_CL45(sc, phy,
5853 				  MDIO_REG_BANK_XGXS_BLOCK2,
5854 				  MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
5855 	}
5856 }
5857 
elink_set_parallel_detection(struct elink_phy * phy,struct elink_params * params)5858 static void elink_set_parallel_detection(struct elink_phy *phy,
5859 					 struct elink_params *params)
5860 {
5861 	struct bnx2x_softc *sc = params->sc;
5862 	uint16_t control2;
5863 	CL22_RD_OVER_CL45(sc, phy,
5864 			  MDIO_REG_BANK_SERDES_DIGITAL,
5865 			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
5866 			  &control2);
5867 	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5868 		control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
5869 	else
5870 		control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
5871 	ELINK_DEBUG_P2(sc, "phy->speed_cap_mask = 0x%x, control2 = 0x%x",
5872 		phy->speed_cap_mask, control2);
5873 	CL22_WR_OVER_CL45(sc, phy,
5874 			  MDIO_REG_BANK_SERDES_DIGITAL,
5875 			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
5876 			  control2);
5877 
5878 	if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
5879 	     (phy->speed_cap_mask &
5880 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
5881 		ELINK_DEBUG_P0(sc, "XGXS");
5882 
5883 		CL22_WR_OVER_CL45(sc, phy,
5884 				 MDIO_REG_BANK_10G_PARALLEL_DETECT,
5885 				 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
5886 				 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
5887 
5888 		CL22_RD_OVER_CL45(sc, phy,
5889 				  MDIO_REG_BANK_10G_PARALLEL_DETECT,
5890 				  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
5891 				  &control2);
5892 
5893 
5894 		control2 |=
5895 		    MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
5896 
5897 		CL22_WR_OVER_CL45(sc, phy,
5898 				  MDIO_REG_BANK_10G_PARALLEL_DETECT,
5899 				  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
5900 				  control2);
5901 
5902 		/* Disable parallel detection of HiG */
5903 		CL22_WR_OVER_CL45(sc, phy,
5904 				  MDIO_REG_BANK_XGXS_BLOCK2,
5905 				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
5906 				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
5907 				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
5908 	}
5909 }
5910 
elink_set_autoneg(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars,uint8_t enable_cl73)5911 static void elink_set_autoneg(struct elink_phy *phy,
5912 			      struct elink_params *params,
5913 			      struct elink_vars *vars,
5914 			      uint8_t enable_cl73)
5915 {
5916 	struct bnx2x_softc *sc = params->sc;
5917 	uint16_t reg_val;
5918 
5919 	/* CL37 Autoneg */
5920 	CL22_RD_OVER_CL45(sc, phy,
5921 			  MDIO_REG_BANK_COMBO_IEEE0,
5922 			  MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
5923 
5924 	/* CL37 Autoneg Enabled */
5925 	if (vars->line_speed == ELINK_SPEED_AUTO_NEG)
5926 		reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
5927 	else /* CL37 Autoneg Disabled */
5928 		reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5929 			     MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
5930 
5931 	CL22_WR_OVER_CL45(sc, phy,
5932 			  MDIO_REG_BANK_COMBO_IEEE0,
5933 			  MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
5934 
5935 	/* Enable/Disable Autodetection */
5936 
5937 	CL22_RD_OVER_CL45(sc, phy,
5938 			  MDIO_REG_BANK_SERDES_DIGITAL,
5939 			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
5940 	reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
5941 		    MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
5942 	reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
5943 	if (vars->line_speed == ELINK_SPEED_AUTO_NEG)
5944 		reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
5945 	else
5946 		reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
5947 
5948 	CL22_WR_OVER_CL45(sc, phy,
5949 			  MDIO_REG_BANK_SERDES_DIGITAL,
5950 			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
5951 
5952 	/* Enable TetonII and BAM autoneg */
5953 	CL22_RD_OVER_CL45(sc, phy,
5954 			  MDIO_REG_BANK_BAM_NEXT_PAGE,
5955 			  MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
5956 			  &reg_val);
5957 	if (vars->line_speed == ELINK_SPEED_AUTO_NEG) {
5958 		/* Enable BAM aneg Mode and TetonII aneg Mode */
5959 		reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
5960 			    MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
5961 	} else {
5962 		/* TetonII and BAM Autoneg Disabled */
5963 		reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
5964 			     MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
5965 	}
5966 	CL22_WR_OVER_CL45(sc, phy,
5967 			  MDIO_REG_BANK_BAM_NEXT_PAGE,
5968 			  MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
5969 			  reg_val);
5970 
5971 	if (enable_cl73) {
5972 		/* Enable Cl73 FSM status bits */
5973 		CL22_WR_OVER_CL45(sc, phy,
5974 				  MDIO_REG_BANK_CL73_USERB0,
5975 				  MDIO_CL73_USERB0_CL73_UCTRL,
5976 				  0xe);
5977 
5978 		/* Enable BAM Station Manager*/
5979 		CL22_WR_OVER_CL45(sc, phy,
5980 			MDIO_REG_BANK_CL73_USERB0,
5981 			MDIO_CL73_USERB0_CL73_BAM_CTRL1,
5982 			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
5983 			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
5984 			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
5985 
5986 		/* Advertise CL73 link speeds */
5987 		CL22_RD_OVER_CL45(sc, phy,
5988 				  MDIO_REG_BANK_CL73_IEEEB1,
5989 				  MDIO_CL73_IEEEB1_AN_ADV2,
5990 				  &reg_val);
5991 		if (phy->speed_cap_mask &
5992 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
5993 			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
5994 		if (phy->speed_cap_mask &
5995 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5996 			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
5997 
5998 		CL22_WR_OVER_CL45(sc, phy,
5999 				  MDIO_REG_BANK_CL73_IEEEB1,
6000 				  MDIO_CL73_IEEEB1_AN_ADV2,
6001 				  reg_val);
6002 
6003 		/* CL73 Autoneg Enabled */
6004 		reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
6005 
6006 	} else /* CL73 Autoneg Disabled */
6007 		reg_val = 0;
6008 
6009 	CL22_WR_OVER_CL45(sc, phy,
6010 			  MDIO_REG_BANK_CL73_IEEEB0,
6011 			  MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
6012 }
6013 
6014 /* Program SerDes, forced speed */
elink_program_serdes(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)6015 static void elink_program_serdes(struct elink_phy *phy,
6016 				 struct elink_params *params,
6017 				 struct elink_vars *vars)
6018 {
6019 	struct bnx2x_softc *sc = params->sc;
6020 	uint16_t reg_val;
6021 
6022 	/* Program duplex, disable autoneg and sgmii*/
6023 	CL22_RD_OVER_CL45(sc, phy,
6024 			  MDIO_REG_BANK_COMBO_IEEE0,
6025 			  MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
6026 	reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
6027 		     MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
6028 		     MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
6029 	if (phy->req_duplex == DUPLEX_FULL)
6030 		reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
6031 	CL22_WR_OVER_CL45(sc, phy,
6032 			  MDIO_REG_BANK_COMBO_IEEE0,
6033 			  MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
6034 
6035 	/* Program speed
6036 	 *  - needed only if the speed is greater than 1G (2.5G or 10G)
6037 	 */
6038 	CL22_RD_OVER_CL45(sc, phy,
6039 			  MDIO_REG_BANK_SERDES_DIGITAL,
6040 			  MDIO_SERDES_DIGITAL_MISC1, &reg_val);
6041 	/* Clearing the speed value before setting the right speed */
6042 	ELINK_DEBUG_P1(sc, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x", reg_val);
6043 
6044 	reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
6045 		     MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
6046 
6047 	if (!((vars->line_speed == ELINK_SPEED_1000) ||
6048 	      (vars->line_speed == ELINK_SPEED_100) ||
6049 	      (vars->line_speed == ELINK_SPEED_10))) {
6050 
6051 		reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
6052 			    MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
6053 		if (vars->line_speed == ELINK_SPEED_10000)
6054 			reg_val |=
6055 				MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
6056 	}
6057 
6058 	CL22_WR_OVER_CL45(sc, phy,
6059 			  MDIO_REG_BANK_SERDES_DIGITAL,
6060 			  MDIO_SERDES_DIGITAL_MISC1, reg_val);
6061 
6062 }
6063 
elink_set_brcm_cl37_advertisement(struct elink_phy * phy,struct elink_params * params)6064 static void elink_set_brcm_cl37_advertisement(struct elink_phy *phy,
6065 					      struct elink_params *params)
6066 {
6067 	struct bnx2x_softc *sc = params->sc;
6068 	uint16_t val = 0;
6069 
6070 	/* Set extended capabilities */
6071 	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
6072 		val |= MDIO_OVER_1G_UP1_2_5G;
6073 	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
6074 		val |= MDIO_OVER_1G_UP1_10G;
6075 	CL22_WR_OVER_CL45(sc, phy,
6076 			  MDIO_REG_BANK_OVER_1G,
6077 			  MDIO_OVER_1G_UP1, val);
6078 
6079 	CL22_WR_OVER_CL45(sc, phy,
6080 			  MDIO_REG_BANK_OVER_1G,
6081 			  MDIO_OVER_1G_UP3, 0x400);
6082 }
6083 
elink_set_ieee_aneg_advertisement(struct elink_phy * phy,struct elink_params * params,uint16_t ieee_fc)6084 static void elink_set_ieee_aneg_advertisement(struct elink_phy *phy,
6085 					      struct elink_params *params,
6086 					      uint16_t ieee_fc)
6087 {
6088 	struct bnx2x_softc *sc = params->sc;
6089 	uint16_t val;
6090 	/* For AN, we are always publishing full duplex */
6091 
6092 	CL22_WR_OVER_CL45(sc, phy,
6093 			  MDIO_REG_BANK_COMBO_IEEE0,
6094 			  MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
6095 	CL22_RD_OVER_CL45(sc, phy,
6096 			  MDIO_REG_BANK_CL73_IEEEB1,
6097 			  MDIO_CL73_IEEEB1_AN_ADV1, &val);
6098 	val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
6099 	val |= ((ieee_fc << 3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
6100 	CL22_WR_OVER_CL45(sc, phy,
6101 			  MDIO_REG_BANK_CL73_IEEEB1,
6102 			  MDIO_CL73_IEEEB1_AN_ADV1, val);
6103 }
6104 
elink_restart_autoneg(struct elink_phy * phy,struct elink_params * params,uint8_t enable_cl73)6105 static void elink_restart_autoneg(struct elink_phy *phy,
6106 				  struct elink_params *params,
6107 				  uint8_t enable_cl73)
6108 {
6109 	struct bnx2x_softc *sc = params->sc;
6110 	uint16_t mii_control;
6111 
6112 	ELINK_DEBUG_P0(sc, "elink_restart_autoneg");
6113 	/* Enable and restart BAM/CL37 aneg */
6114 
6115 	if (enable_cl73) {
6116 		CL22_RD_OVER_CL45(sc, phy,
6117 				  MDIO_REG_BANK_CL73_IEEEB0,
6118 				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6119 				  &mii_control);
6120 
6121 		CL22_WR_OVER_CL45(sc, phy,
6122 				  MDIO_REG_BANK_CL73_IEEEB0,
6123 				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6124 				  (mii_control |
6125 				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
6126 				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
6127 	} else {
6128 
6129 		CL22_RD_OVER_CL45(sc, phy,
6130 				  MDIO_REG_BANK_COMBO_IEEE0,
6131 				  MDIO_COMBO_IEEE0_MII_CONTROL,
6132 				  &mii_control);
6133 		ELINK_DEBUG_P1(sc,
6134 			 "elink_restart_autoneg mii_control before = 0x%x",
6135 			 mii_control);
6136 		CL22_WR_OVER_CL45(sc, phy,
6137 				  MDIO_REG_BANK_COMBO_IEEE0,
6138 				  MDIO_COMBO_IEEE0_MII_CONTROL,
6139 				  (mii_control |
6140 				   MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
6141 				   MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
6142 	}
6143 }
6144 
elink_initialize_sgmii_process(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)6145 static void elink_initialize_sgmii_process(struct elink_phy *phy,
6146 					   struct elink_params *params,
6147 					   struct elink_vars *vars)
6148 {
6149 	struct bnx2x_softc *sc = params->sc;
6150 	uint16_t control1;
6151 
6152 	/* In SGMII mode, the unicore is always slave */
6153 
6154 	CL22_RD_OVER_CL45(sc, phy,
6155 			  MDIO_REG_BANK_SERDES_DIGITAL,
6156 			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
6157 			  &control1);
6158 	control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
6159 	/* Set sgmii mode (and not fiber) */
6160 	control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
6161 		      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
6162 		      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
6163 	CL22_WR_OVER_CL45(sc, phy,
6164 			  MDIO_REG_BANK_SERDES_DIGITAL,
6165 			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
6166 			  control1);
6167 
6168 	/* If forced speed */
6169 	if (!(vars->line_speed == ELINK_SPEED_AUTO_NEG)) {
6170 		/* Set speed, disable autoneg */
6171 		uint16_t mii_control;
6172 
6173 		CL22_RD_OVER_CL45(sc, phy,
6174 				  MDIO_REG_BANK_COMBO_IEEE0,
6175 				  MDIO_COMBO_IEEE0_MII_CONTROL,
6176 				  &mii_control);
6177 		mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
6178 				 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK |
6179 				 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
6180 
6181 		switch (vars->line_speed) {
6182 		case ELINK_SPEED_100:
6183 			mii_control |=
6184 				MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
6185 			break;
6186 		case ELINK_SPEED_1000:
6187 			mii_control |=
6188 				MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
6189 			break;
6190 		case ELINK_SPEED_10:
6191 			/* There is nothing to set for 10M */
6192 			break;
6193 		default:
6194 			/* Invalid speed for SGMII */
6195 			ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x",
6196 				  vars->line_speed);
6197 			break;
6198 		}
6199 
6200 		/* Setting the full duplex */
6201 		if (phy->req_duplex == DUPLEX_FULL)
6202 			mii_control |=
6203 				MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
6204 		CL22_WR_OVER_CL45(sc, phy,
6205 				  MDIO_REG_BANK_COMBO_IEEE0,
6206 				  MDIO_COMBO_IEEE0_MII_CONTROL,
6207 				  mii_control);
6208 
6209 	} else { /* AN mode */
6210 		/* Enable and restart AN */
6211 		elink_restart_autoneg(phy, params, 0);
6212 	}
6213 }
6214 
6215 /* Link management
6216  */
elink_direct_parallel_detect_used(struct elink_phy * phy,struct elink_params * params)6217 static elink_status_t elink_direct_parallel_detect_used(struct elink_phy *phy,
6218 					     struct elink_params *params)
6219 {
6220 	struct bnx2x_softc *sc = params->sc;
6221 	uint16_t pd_10g, status2_1000x;
6222 	if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
6223 		return ELINK_STATUS_OK;
6224 	CL22_RD_OVER_CL45(sc, phy,
6225 			  MDIO_REG_BANK_SERDES_DIGITAL,
6226 			  MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
6227 			  &status2_1000x);
6228 	CL22_RD_OVER_CL45(sc, phy,
6229 			  MDIO_REG_BANK_SERDES_DIGITAL,
6230 			  MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
6231 			  &status2_1000x);
6232 	if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
6233 		ELINK_DEBUG_P1(sc, "1G parallel detect link on port %d",
6234 			 params->port);
6235 		return 1;
6236 	}
6237 
6238 	CL22_RD_OVER_CL45(sc, phy,
6239 			  MDIO_REG_BANK_10G_PARALLEL_DETECT,
6240 			  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
6241 			  &pd_10g);
6242 
6243 	if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
6244 		ELINK_DEBUG_P1(sc, "10G parallel detect link on port %d",
6245 			 params->port);
6246 		return 1;
6247 	}
6248 	return ELINK_STATUS_OK;
6249 }
6250 
elink_update_adv_fc(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars,uint32_t gp_status)6251 static void elink_update_adv_fc(struct elink_phy *phy,
6252 				struct elink_params *params,
6253 				struct elink_vars *vars,
6254 				uint32_t gp_status)
6255 {
6256 	uint16_t ld_pause;   /* local driver */
6257 	uint16_t lp_pause;   /* link partner */
6258 	uint16_t pause_result;
6259 	struct bnx2x_softc *sc = params->sc;
6260 	if ((gp_status &
6261 	     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
6262 	      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
6263 	    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
6264 	     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
6265 
6266 		CL22_RD_OVER_CL45(sc, phy,
6267 				  MDIO_REG_BANK_CL73_IEEEB1,
6268 				  MDIO_CL73_IEEEB1_AN_ADV1,
6269 				  &ld_pause);
6270 		CL22_RD_OVER_CL45(sc, phy,
6271 				  MDIO_REG_BANK_CL73_IEEEB1,
6272 				  MDIO_CL73_IEEEB1_AN_LP_ADV1,
6273 				  &lp_pause);
6274 		pause_result = (ld_pause &
6275 				MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) >> 8;
6276 		pause_result |= (lp_pause &
6277 				 MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK) >> 10;
6278 		ELINK_DEBUG_P1(sc, "pause_result CL73 0x%x", pause_result);
6279 	} else {
6280 		CL22_RD_OVER_CL45(sc, phy,
6281 				  MDIO_REG_BANK_COMBO_IEEE0,
6282 				  MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
6283 				  &ld_pause);
6284 		CL22_RD_OVER_CL45(sc, phy,
6285 			MDIO_REG_BANK_COMBO_IEEE0,
6286 			MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
6287 			&lp_pause);
6288 		pause_result = (ld_pause &
6289 				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) >> 5;
6290 		pause_result |= (lp_pause &
6291 				 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) >> 7;
6292 		ELINK_DEBUG_P1(sc, "pause_result CL37 0x%x", pause_result);
6293 	}
6294 	elink_pause_resolve(phy, params, vars, pause_result);
6295 
6296 }
6297 
elink_flow_ctrl_resolve(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars,uint32_t gp_status)6298 static void elink_flow_ctrl_resolve(struct elink_phy *phy,
6299 				    struct elink_params *params,
6300 				    struct elink_vars *vars,
6301 				    uint32_t gp_status)
6302 {
6303 	struct bnx2x_softc *sc = params->sc;
6304 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
6305 
6306 	/* Resolve from gp_status in case of AN complete and not sgmii */
6307 	if (phy->req_flow_ctrl != ELINK_FLOW_CTRL_AUTO) {
6308 		/* Update the advertised flow-controled of LD/LP in AN */
6309 		if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6310 			elink_update_adv_fc(phy, params, vars, gp_status);
6311 		/* But set the flow-control result as the requested one */
6312 		vars->flow_ctrl = phy->req_flow_ctrl;
6313 	} else if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
6314 		vars->flow_ctrl = params->req_fc_auto_adv;
6315 	else if ((gp_status & ELINK_MDIO_AN_CL73_OR_37_COMPLETE) &&
6316 		 (!(vars->phy_flags & PHY_SGMII_FLAG))) {
6317 		if (elink_direct_parallel_detect_used(phy, params)) {
6318 			vars->flow_ctrl = params->req_fc_auto_adv;
6319 			return;
6320 		}
6321 		elink_update_adv_fc(phy, params, vars, gp_status);
6322 	}
6323 	ELINK_DEBUG_P1(sc, "flow_ctrl 0x%x", vars->flow_ctrl);
6324 }
6325 
elink_check_fallback_to_cl37(struct elink_phy * phy,struct elink_params * params)6326 static void elink_check_fallback_to_cl37(struct elink_phy *phy,
6327 					 struct elink_params *params)
6328 {
6329 	struct bnx2x_softc *sc = params->sc;
6330 	uint16_t rx_status, ustat_val, cl37_fsm_received;
6331 	ELINK_DEBUG_P0(sc, "elink_check_fallback_to_cl37");
6332 	/* Step 1: Make sure signal is detected */
6333 	CL22_RD_OVER_CL45(sc, phy,
6334 			  MDIO_REG_BANK_RX0,
6335 			  MDIO_RX0_RX_STATUS,
6336 			  &rx_status);
6337 	if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
6338 	    (MDIO_RX0_RX_STATUS_SIGDET)) {
6339 		ELINK_DEBUG_P1(sc, "Signal is not detected. Restoring CL73."
6340 			     "rx_status(0x80b0) = 0x%x", rx_status);
6341 		CL22_WR_OVER_CL45(sc, phy,
6342 				  MDIO_REG_BANK_CL73_IEEEB0,
6343 				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6344 				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
6345 		return;
6346 	}
6347 	/* Step 2: Check CL73 state machine */
6348 	CL22_RD_OVER_CL45(sc, phy,
6349 			  MDIO_REG_BANK_CL73_USERB0,
6350 			  MDIO_CL73_USERB0_CL73_USTAT1,
6351 			  &ustat_val);
6352 	if ((ustat_val &
6353 	     (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
6354 	      MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
6355 	    (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
6356 	      MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
6357 		ELINK_DEBUG_P1(sc, "CL73 state-machine is not stable. "
6358 			     "ustat_val(0x8371) = 0x%x", ustat_val);
6359 		return;
6360 	}
6361 	/* Step 3: Check CL37 Message Pages received to indicate LP
6362 	 * supports only CL37
6363 	 */
6364 	CL22_RD_OVER_CL45(sc, phy,
6365 			  MDIO_REG_BANK_REMOTE_PHY,
6366 			  MDIO_REMOTE_PHY_MISC_RX_STATUS,
6367 			  &cl37_fsm_received);
6368 	if ((cl37_fsm_received &
6369 	     (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
6370 	     MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
6371 	    (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
6372 	      MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
6373 		ELINK_DEBUG_P1(sc, "No CL37 FSM were received. "
6374 			     "misc_rx_status(0x8330) = 0x%x",
6375 			 cl37_fsm_received);
6376 		return;
6377 	}
6378 	/* The combined cl37/cl73 fsm state information indicating that
6379 	 * we are connected to a device which does not support cl73, but
6380 	 * does support cl37 BAM. In this case we disable cl73 and
6381 	 * restart cl37 auto-neg
6382 	 */
6383 
6384 	/* Disable CL73 */
6385 	CL22_WR_OVER_CL45(sc, phy,
6386 			  MDIO_REG_BANK_CL73_IEEEB0,
6387 			  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6388 			  0);
6389 	/* Restart CL37 autoneg */
6390 	elink_restart_autoneg(phy, params, 0);
6391 	ELINK_DEBUG_P0(sc, "Disabling CL73, and restarting CL37 autoneg");
6392 }
6393 
elink_xgxs_an_resolve(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars,uint32_t gp_status)6394 static void elink_xgxs_an_resolve(struct elink_phy *phy,
6395 				  struct elink_params *params,
6396 				  struct elink_vars *vars,
6397 				  uint32_t gp_status)
6398 {
6399 	if (gp_status & ELINK_MDIO_AN_CL73_OR_37_COMPLETE)
6400 		vars->link_status |=
6401 			LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6402 
6403 	if (elink_direct_parallel_detect_used(phy, params))
6404 		vars->link_status |=
6405 			LINK_STATUS_PARALLEL_DETECTION_USED;
6406 }
elink_get_link_speed_duplex(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars,uint16_t is_link_up,uint16_t speed_mask,uint16_t is_duplex)6407 static elink_status_t elink_get_link_speed_duplex(struct elink_phy *phy,
6408 				     struct elink_params *params,
6409 				      struct elink_vars *vars,
6410 				      uint16_t is_link_up,
6411 				      uint16_t speed_mask,
6412 				      uint16_t is_duplex)
6413 {
6414 	struct bnx2x_softc *sc = params->sc;
6415 	if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6416 		vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
6417 	if (is_link_up) {
6418 		ELINK_DEBUG_P0(sc, "phy link up");
6419 
6420 		vars->phy_link_up = 1;
6421 		vars->link_status |= LINK_STATUS_LINK_UP;
6422 
6423 		switch (speed_mask) {
6424 		case ELINK_GP_STATUS_10M:
6425 			vars->line_speed = ELINK_SPEED_10;
6426 			if (is_duplex == DUPLEX_FULL)
6427 				vars->link_status |= ELINK_LINK_10TFD;
6428 			else
6429 				vars->link_status |= ELINK_LINK_10THD;
6430 			break;
6431 
6432 		case ELINK_GP_STATUS_100M:
6433 			vars->line_speed = ELINK_SPEED_100;
6434 			if (is_duplex == DUPLEX_FULL)
6435 				vars->link_status |= ELINK_LINK_100TXFD;
6436 			else
6437 				vars->link_status |= ELINK_LINK_100TXHD;
6438 			break;
6439 
6440 		case ELINK_GP_STATUS_1G:
6441 		case ELINK_GP_STATUS_1G_KX:
6442 			vars->line_speed = ELINK_SPEED_1000;
6443 			if (is_duplex == DUPLEX_FULL)
6444 				vars->link_status |= ELINK_LINK_1000TFD;
6445 			else
6446 				vars->link_status |= ELINK_LINK_1000THD;
6447 			break;
6448 
6449 		case ELINK_GP_STATUS_2_5G:
6450 			vars->line_speed = ELINK_SPEED_2500;
6451 			if (is_duplex == DUPLEX_FULL)
6452 				vars->link_status |= ELINK_LINK_2500TFD;
6453 			else
6454 				vars->link_status |= ELINK_LINK_2500THD;
6455 			break;
6456 
6457 		case ELINK_GP_STATUS_5G:
6458 		case ELINK_GP_STATUS_6G:
6459 			ELINK_DEBUG_P1(sc,
6460 				 "link speed unsupported  gp_status 0x%x",
6461 				  speed_mask);
6462 			return ELINK_STATUS_ERROR;
6463 
6464 		case ELINK_GP_STATUS_10G_KX4:
6465 		case ELINK_GP_STATUS_10G_HIG:
6466 		case ELINK_GP_STATUS_10G_CX4:
6467 		case ELINK_GP_STATUS_10G_KR:
6468 		case ELINK_GP_STATUS_10G_SFI:
6469 		case ELINK_GP_STATUS_10G_XFI:
6470 			vars->line_speed = ELINK_SPEED_10000;
6471 			vars->link_status |= ELINK_LINK_10GTFD;
6472 			break;
6473 		case ELINK_GP_STATUS_20G_DXGXS:
6474 		case ELINK_GP_STATUS_20G_KR2:
6475 			vars->line_speed = ELINK_SPEED_20000;
6476 			vars->link_status |= ELINK_LINK_20GTFD;
6477 			break;
6478 		default:
6479 			ELINK_DEBUG_P1(sc,
6480 				  "link speed unsupported gp_status 0x%x",
6481 				  speed_mask);
6482 			return ELINK_STATUS_ERROR;
6483 		}
6484 	} else { /* link_down */
6485 		ELINK_DEBUG_P0(sc, "phy link down");
6486 
6487 		vars->phy_link_up = 0;
6488 
6489 		vars->duplex = DUPLEX_FULL;
6490 		vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
6491 		vars->mac_type = ELINK_MAC_TYPE_NONE;
6492 	}
6493 	ELINK_DEBUG_P2(sc, " in elink_get_link_speed_duplex vars->link_status = %x, vars->duplex = %x",
6494 			vars->link_status, vars->duplex);
6495 	ELINK_DEBUG_P2(sc, " phy_link_up %x line_speed %d",
6496 		    vars->phy_link_up, vars->line_speed);
6497 	return ELINK_STATUS_OK;
6498 }
6499 
elink_link_settings_status(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)6500 static uint8_t elink_link_settings_status(struct elink_phy *phy,
6501 				      struct elink_params *params,
6502 				      struct elink_vars *vars)
6503 {
6504 	struct bnx2x_softc *sc = params->sc;
6505 
6506 	uint16_t gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
6507 	elink_status_t rc = ELINK_STATUS_OK;
6508 
6509 	/* Read gp_status */
6510 	CL22_RD_OVER_CL45(sc, phy,
6511 			  MDIO_REG_BANK_GP_STATUS,
6512 			  MDIO_GP_STATUS_TOP_AN_STATUS1,
6513 			  &gp_status);
6514 	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS) {
6515 		duplex = DUPLEX_FULL;
6516 		ELINK_DEBUG_P1(sc, "duplex status read from phy is = %x",
6517 				duplex);
6518 	} else {
6519 		ELINK_DEBUG_P1(sc, "phy status does not allow interface to be FULL_DUPLEX : %x",
6520 			gp_status);
6521 	}
6522 
6523 
6524 	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
6525 		link_up = 1;
6526 	speed_mask = gp_status & ELINK_GP_STATUS_SPEED_MASK;
6527 	ELINK_DEBUG_P3(sc, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x",
6528 		       gp_status, link_up, speed_mask);
6529 	rc = elink_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
6530 					 duplex);
6531 	if (rc == ELINK_STATUS_ERROR)
6532 		return rc;
6533 
6534 	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
6535 		if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
6536 			vars->duplex = duplex;
6537 			elink_flow_ctrl_resolve(phy, params, vars, gp_status);
6538 			if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6539 				elink_xgxs_an_resolve(phy, params, vars,
6540 						      gp_status);
6541 		}
6542 	} else { /* Link_down */
6543 		if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
6544 		    ELINK_SINGLE_MEDIA_DIRECT(params)) {
6545 			/* Check signal is detected */
6546 			elink_check_fallback_to_cl37(phy, params);
6547 		}
6548 	}
6549 
6550 	/* Read LP advertised speeds*/
6551 	if (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6552 	    (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)) {
6553 		uint16_t val;
6554 
6555 		CL22_RD_OVER_CL45(sc, phy, MDIO_REG_BANK_CL73_IEEEB1,
6556 				  MDIO_CL73_IEEEB1_AN_LP_ADV2, &val);
6557 
6558 		if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
6559 			vars->link_status |=
6560 				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
6561 		if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
6562 			   MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
6563 			vars->link_status |=
6564 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6565 
6566 		CL22_RD_OVER_CL45(sc, phy, MDIO_REG_BANK_OVER_1G,
6567 				  MDIO_OVER_1G_LP_UP1, &val);
6568 
6569 		if (val & MDIO_OVER_1G_UP1_2_5G)
6570 			vars->link_status |=
6571 				LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
6572 		if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
6573 			vars->link_status |=
6574 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6575 	}
6576 
6577 	ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x",
6578 		   vars->duplex, vars->flow_ctrl, vars->link_status);
6579 	return rc;
6580 }
6581 
elink_warpcore_read_status(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)6582 static uint8_t elink_warpcore_read_status(struct elink_phy *phy,
6583 				     struct elink_params *params,
6584 				     struct elink_vars *vars)
6585 {
6586 	struct bnx2x_softc *sc = params->sc;
6587 	uint8_t lane;
6588 	uint16_t gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
6589 	elink_status_t rc = ELINK_STATUS_OK;
6590 	lane = elink_get_warpcore_lane(phy, params);
6591 	/* Read gp_status */
6592 	if ((params->loopback_mode) &&
6593 	    (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)) {
6594 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6595 				MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up);
6596 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6597 				MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up);
6598 		link_up &= 0x1;
6599 		ELINK_DEBUG_P1(sc, "params->loopback_mode link_up read = %x",
6600 				link_up);
6601 	} else if ((phy->req_line_speed > ELINK_SPEED_10000) &&
6602 		(phy->supported & ELINK_SUPPORTED_20000baseMLD2_Full)) {
6603 		uint16_t temp_link_up;
6604 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6605 				1, &temp_link_up);
6606 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6607 				1, &link_up);
6608 		ELINK_DEBUG_P2(sc, "PCS RX link status = 0x%x-->0x%x",
6609 			       temp_link_up, link_up);
6610 		link_up &= (1 << 2);
6611 		if (link_up)
6612 			elink_ext_phy_resolve_fc(phy, params, vars);
6613 	} else {
6614 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6615 				MDIO_WC_REG_GP2_STATUS_GP_2_1,
6616 				&gp_status1);
6617 		ELINK_DEBUG_P1(sc, "0x81d1 = 0x%x", gp_status1);
6618 		/* Check for either KR, 1G, or AN up. */
6619 		link_up = ((gp_status1 >> 8) |
6620 			   (gp_status1 >> 12) |
6621 			   (gp_status1)) &
6622 			(1 << lane);
6623 		if (phy->supported & ELINK_SUPPORTED_20000baseKR2_Full) {
6624 			uint16_t an_link;
6625 			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6626 					MDIO_AN_REG_STATUS, &an_link);
6627 			elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6628 					MDIO_AN_REG_STATUS, &an_link);
6629 			link_up |= (an_link & (1 << 2));
6630 			ELINK_DEBUG_P2(sc, "an_link = %x, link_up = %x",
6631 					an_link, link_up);
6632 		}
6633 		if (link_up && ELINK_SINGLE_MEDIA_DIRECT(params)) {
6634 			uint16_t pd, gp_status4;
6635 			if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
6636 				/* Check Autoneg complete */
6637 				elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6638 						MDIO_WC_REG_GP2_STATUS_GP_2_4,
6639 						&gp_status4);
6640 				if (gp_status4 & ((1 << 12) << lane))
6641 					vars->link_status |=
6642 					LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6643 
6644 				/* Check parallel detect used */
6645 				elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6646 						MDIO_WC_REG_PAR_DET_10G_STATUS,
6647 						&pd);
6648 				if (pd & (1 << 15))
6649 					vars->link_status |=
6650 					LINK_STATUS_PARALLEL_DETECTION_USED;
6651 				ELINK_DEBUG_P2(sc, "pd = %x, link_status = %x",
6652 						pd, vars->link_status);
6653 			}
6654 			elink_ext_phy_resolve_fc(phy, params, vars);
6655 			vars->duplex = duplex;
6656 			ELINK_DEBUG_P3(sc, " ELINK_SINGLE_MEDIA_DIRECT duplex %x  flow_ctrl 0x%x link_status 0x%x",
6657 					vars->duplex, vars->flow_ctrl,
6658 					vars->link_status);
6659 		}
6660 	}
6661 	ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x",
6662 			vars->duplex, vars->flow_ctrl, vars->link_status);
6663 	if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) &&
6664 	    ELINK_SINGLE_MEDIA_DIRECT(params)) {
6665 		uint16_t val;
6666 
6667 		elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6668 				MDIO_AN_REG_LP_AUTO_NEG2, &val);
6669 
6670 		if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
6671 			vars->link_status |=
6672 				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
6673 		if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
6674 			   MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
6675 			vars->link_status |=
6676 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6677 		ELINK_DEBUG_P2(sc, "val = %x, link_status = %x",
6678 				val, vars->link_status);
6679 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6680 				MDIO_WC_REG_DIGITAL3_LP_UP1, &val);
6681 
6682 		if (val & MDIO_OVER_1G_UP1_2_5G)
6683 			vars->link_status |=
6684 				LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
6685 		if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
6686 			vars->link_status |=
6687 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6688 		ELINK_DEBUG_P2(sc, "val = %x, link_status = %x",
6689 				val, vars->link_status);
6690 
6691 	}
6692 
6693 
6694 	if (lane < 2) {
6695 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6696 				MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
6697 	} else {
6698 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6699 				MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
6700 	}
6701 	ELINK_DEBUG_P2(sc, "lane %d gp_speed 0x%x", lane, gp_speed);
6702 
6703 	if ((lane & 1) == 0)
6704 		gp_speed <<= 8;
6705 	gp_speed &= 0x3f00;
6706 	link_up = !!link_up;
6707 
6708 	/* Reset the TX FIFO to fix SGMII issue */
6709 	rc = elink_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
6710 					 duplex);
6711 
6712 	/* In case of KR link down, start up the recovering procedure */
6713 	if ((!link_up) && (phy->media_type == ELINK_ETH_PHY_KR) &&
6714 	    (!(phy->flags & ELINK_FLAGS_WC_DUAL_MODE)))
6715 		vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
6716 
6717 	ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x",
6718 		   vars->duplex, vars->flow_ctrl, vars->link_status);
6719 	return rc;
6720 }
elink_set_gmii_tx_driver(struct elink_params * params)6721 static void elink_set_gmii_tx_driver(struct elink_params *params)
6722 {
6723 	struct bnx2x_softc *sc = params->sc;
6724 	struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
6725 	uint16_t lp_up2;
6726 	uint16_t tx_driver;
6727 	uint16_t bank;
6728 
6729 	/* Read precomp */
6730 	CL22_RD_OVER_CL45(sc, phy,
6731 			  MDIO_REG_BANK_OVER_1G,
6732 			  MDIO_OVER_1G_LP_UP2, &lp_up2);
6733 
6734 	/* Bits [10:7] at lp_up2, positioned at [15:12] */
6735 	lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
6736 		   MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
6737 		  MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
6738 
6739 	if (lp_up2 == 0)
6740 		return;
6741 
6742 	for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
6743 	      bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
6744 		CL22_RD_OVER_CL45(sc, phy,
6745 				  bank,
6746 				  MDIO_TX0_TX_DRIVER, &tx_driver);
6747 
6748 		/* Replace tx_driver bits [15:12] */
6749 		if (lp_up2 !=
6750 		    (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
6751 			tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
6752 			tx_driver |= lp_up2;
6753 			CL22_WR_OVER_CL45(sc, phy,
6754 					  bank,
6755 					  MDIO_TX0_TX_DRIVER, tx_driver);
6756 		}
6757 	}
6758 }
6759 
elink_emac_program(struct elink_params * params,struct elink_vars * vars)6760 static elink_status_t elink_emac_program(struct elink_params *params,
6761 			      struct elink_vars *vars)
6762 {
6763 	struct bnx2x_softc *sc = params->sc;
6764 	uint8_t port = params->port;
6765 	uint16_t mode = 0;
6766 
6767 	ELINK_DEBUG_P0(sc, "setting link speed & duplex");
6768 	elink_bits_dis(sc, GRCBASE_EMAC0 + port * 0x400 +
6769 		       EMAC_REG_EMAC_MODE,
6770 		       (EMAC_MODE_25G_MODE |
6771 			EMAC_MODE_PORT_MII_10M |
6772 			EMAC_MODE_HALF_DUPLEX));
6773 	switch (vars->line_speed) {
6774 	case ELINK_SPEED_10:
6775 		mode |= EMAC_MODE_PORT_MII_10M;
6776 		break;
6777 
6778 	case ELINK_SPEED_100:
6779 		mode |= EMAC_MODE_PORT_MII;
6780 		break;
6781 
6782 	case ELINK_SPEED_1000:
6783 		mode |= EMAC_MODE_PORT_GMII;
6784 		break;
6785 
6786 	case ELINK_SPEED_2500:
6787 		mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
6788 		break;
6789 
6790 	default:
6791 		/* 10G not valid for EMAC */
6792 		ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x",
6793 			   vars->line_speed);
6794 		return ELINK_STATUS_ERROR;
6795 	}
6796 
6797 	if (vars->duplex == DUPLEX_HALF)
6798 		mode |= EMAC_MODE_HALF_DUPLEX;
6799 	elink_bits_en(sc,
6800 		      GRCBASE_EMAC0 + port * 0x400 + EMAC_REG_EMAC_MODE,
6801 		      mode);
6802 
6803 	elink_set_led(params, vars, ELINK_LED_MODE_OPER, vars->line_speed);
6804 	return ELINK_STATUS_OK;
6805 }
6806 
elink_set_preemphasis(struct elink_phy * phy,struct elink_params * params)6807 static void elink_set_preemphasis(struct elink_phy *phy,
6808 				  struct elink_params *params)
6809 {
6810 
6811 	uint16_t bank, i = 0;
6812 	struct bnx2x_softc *sc = params->sc;
6813 
6814 	for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
6815 	     bank += (MDIO_REG_BANK_RX1 - MDIO_REG_BANK_RX0), i++) {
6816 		CL22_WR_OVER_CL45(sc, phy,
6817 				  bank,
6818 				  MDIO_RX0_RX_EQ_BOOST,
6819 				  phy->rx_preemphasis[i]);
6820 	}
6821 
6822 	for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
6823 	     bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
6824 		CL22_WR_OVER_CL45(sc, phy,
6825 				  bank,
6826 				  MDIO_TX0_TX_DRIVER,
6827 				  phy->tx_preemphasis[i]);
6828 	}
6829 }
6830 
elink_xgxs_config_init(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)6831 static uint8_t elink_xgxs_config_init(struct elink_phy *phy,
6832 				   struct elink_params *params,
6833 				   struct elink_vars *vars)
6834 {
6835 	struct bnx2x_softc *sc = params->sc;
6836 	uint8_t enable_cl73 = (ELINK_SINGLE_MEDIA_DIRECT(params) ||
6837 			  (params->loopback_mode == ELINK_LOOPBACK_XGXS));
6838 	if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
6839 		if (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6840 		    (params->feature_config_flags &
6841 		     ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
6842 			elink_set_preemphasis(phy, params);
6843 
6844 		/* Forced speed requested? */
6845 		if (vars->line_speed != ELINK_SPEED_AUTO_NEG ||
6846 		    (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6847 		     params->loopback_mode == ELINK_LOOPBACK_EXT)) {
6848 			ELINK_DEBUG_P0(sc, "not SGMII, no AN");
6849 
6850 			/* Disable autoneg */
6851 			elink_set_autoneg(phy, params, vars, 0);
6852 
6853 			/* Program speed and duplex */
6854 			elink_program_serdes(phy, params, vars);
6855 
6856 		} else { /* AN_mode */
6857 			ELINK_DEBUG_P0(sc, "not SGMII, AN");
6858 
6859 			/* AN enabled */
6860 			elink_set_brcm_cl37_advertisement(phy, params);
6861 
6862 			/* Program duplex & pause advertisement (for aneg) */
6863 			elink_set_ieee_aneg_advertisement(phy, params,
6864 							  vars->ieee_fc);
6865 
6866 			/* Enable autoneg */
6867 			elink_set_autoneg(phy, params, vars, enable_cl73);
6868 
6869 			/* Enable and restart AN */
6870 			elink_restart_autoneg(phy, params, enable_cl73);
6871 		}
6872 
6873 	} else { /* SGMII mode */
6874 		ELINK_DEBUG_P0(sc, "SGMII");
6875 
6876 		elink_initialize_sgmii_process(phy, params, vars);
6877 	}
6878 
6879 	return 0;
6880 }
6881 
elink_prepare_xgxs(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)6882 static elink_status_t elink_prepare_xgxs(struct elink_phy *phy,
6883 			  struct elink_params *params,
6884 			  struct elink_vars *vars)
6885 {
6886 	elink_status_t rc;
6887 	vars->phy_flags |= PHY_XGXS_FLAG;
6888 	if ((phy->req_line_speed &&
6889 	     ((phy->req_line_speed == ELINK_SPEED_100) ||
6890 	      (phy->req_line_speed == ELINK_SPEED_10))) ||
6891 	    (!phy->req_line_speed &&
6892 	     (phy->speed_cap_mask >=
6893 	      PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
6894 	     (phy->speed_cap_mask <
6895 	      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
6896 	    (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD))
6897 		vars->phy_flags |= PHY_SGMII_FLAG;
6898 	else
6899 		vars->phy_flags &= ~PHY_SGMII_FLAG;
6900 
6901 	elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
6902 	elink_set_aer_mmd(params, phy);
6903 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
6904 		elink_set_master_ln(params, phy);
6905 
6906 	rc = elink_reset_unicore(params, phy, 0);
6907 	/* Reset the SerDes and wait for reset bit return low */
6908 	if (rc != ELINK_STATUS_OK)
6909 		return rc;
6910 
6911 	elink_set_aer_mmd(params, phy);
6912 	/* Setting the masterLn_def again after the reset */
6913 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
6914 		elink_set_master_ln(params, phy);
6915 		elink_set_swap_lanes(params, phy);
6916 	}
6917 
6918 	return rc;
6919 }
6920 
elink_wait_reset_complete(struct bnx2x_softc * sc,struct elink_phy * phy,struct elink_params * params)6921 static uint16_t elink_wait_reset_complete(struct bnx2x_softc *sc,
6922 				     struct elink_phy *phy,
6923 				     struct elink_params *params)
6924 {
6925 	uint16_t cnt, ctrl;
6926 	/* Wait for soft reset to get cleared up to 1 sec */
6927 	for (cnt = 0; cnt < 1000; cnt++) {
6928 		if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE)
6929 			elink_cl22_read(sc, phy,
6930 				MDIO_PMA_REG_CTRL, &ctrl);
6931 		else
6932 			elink_cl45_read(sc, phy,
6933 				MDIO_PMA_DEVAD,
6934 				MDIO_PMA_REG_CTRL, &ctrl);
6935 		if (!(ctrl & (1 << 15)))
6936 			break;
6937 		DELAY(1000 * 1);
6938 	}
6939 
6940 	if (cnt == 1000)
6941 		elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED,
6942 				   params->port);
6943 				     /* "Warning: PHY was not initialized,"
6944 				      * " Port %d",
6945 				      */
6946 
6947 	ELINK_DEBUG_P2(sc, "control reg 0x%x (after %d ms)", ctrl, cnt);
6948 	return cnt;
6949 }
6950 
elink_link_int_enable(struct elink_params * params)6951 static void elink_link_int_enable(struct elink_params *params)
6952 {
6953 	uint8_t port = params->port;
6954 	uint32_t mask;
6955 	struct bnx2x_softc *sc = params->sc;
6956 
6957 	/* Setting the status to report on link up for either XGXS or SerDes */
6958 	if (CHIP_IS_E3(sc)) {
6959 		mask = ELINK_NIG_MASK_XGXS0_LINK_STATUS;
6960 		if (!(ELINK_SINGLE_MEDIA_DIRECT(params)))
6961 			mask |= ELINK_NIG_MASK_MI_INT;
6962 	} else if (params->switch_cfg == ELINK_SWITCH_CFG_10G) {
6963 		mask = (ELINK_NIG_MASK_XGXS0_LINK10G |
6964 			ELINK_NIG_MASK_XGXS0_LINK_STATUS);
6965 		ELINK_DEBUG_P0(sc, "enabled XGXS interrupt");
6966 		if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) &&
6967 			params->phy[ELINK_INT_PHY].type !=
6968 				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
6969 			mask |= ELINK_NIG_MASK_MI_INT;
6970 			ELINK_DEBUG_P0(sc, "enabled external phy int");
6971 		}
6972 
6973 	} else { /* SerDes */
6974 		mask = ELINK_NIG_MASK_SERDES0_LINK_STATUS;
6975 		ELINK_DEBUG_P0(sc, "enabled SerDes interrupt");
6976 		if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) &&
6977 			params->phy[ELINK_INT_PHY].type !=
6978 				PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
6979 			mask |= ELINK_NIG_MASK_MI_INT;
6980 			ELINK_DEBUG_P0(sc, "enabled external phy int");
6981 		}
6982 	}
6983 	elink_bits_en(sc,
6984 		      NIG_REG_MASK_INTERRUPT_PORT0 + port * 4,
6985 		      mask);
6986 
6987 	ELINK_DEBUG_P3(sc, "port %x, is_xgxs %x, int_status 0x%x", port,
6988 		 (params->switch_cfg == ELINK_SWITCH_CFG_10G),
6989 		 REG_RD(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port * 4));
6990 	ELINK_DEBUG_P3(sc, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x",
6991 		 REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port * 4),
6992 		 REG_RD(sc, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port * 0x18),
6993 		 REG_RD(sc, NIG_REG_SERDES0_STATUS_LINK_STATUS + port * 0x3c));
6994 	ELINK_DEBUG_P2(sc, " 10G %x, XGXS_LINK %x",
6995 	   REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK10G + port * 0x68),
6996 	   REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK_STATUS + port * 0x68));
6997 }
6998 
elink_rearm_latch_signal(struct bnx2x_softc * sc,uint8_t port,uint8_t exp_mi_int)6999 static void elink_rearm_latch_signal(struct bnx2x_softc *sc, uint8_t port,
7000 				     uint8_t exp_mi_int)
7001 {
7002 	uint32_t latch_status = 0;
7003 
7004 	/* Disable the MI INT ( external phy int ) by writing 1 to the
7005 	 * status register. Link down indication is high-active-signal,
7006 	 * so in this case we need to write the status to clear the XOR
7007 	 */
7008 	/* Read Latched signals */
7009 	latch_status = REG_RD(sc,
7010 				    NIG_REG_LATCH_STATUS_0 + port * 8);
7011 	ELINK_DEBUG_P1(sc, "latch_status = 0x%x", latch_status);
7012 	/* Handle only those with latched-signal=up.*/
7013 	if (exp_mi_int)
7014 		elink_bits_en(sc,
7015 			      NIG_REG_STATUS_INTERRUPT_PORT0
7016 			      + port * 4,
7017 			      ELINK_NIG_STATUS_EMAC0_MI_INT);
7018 	else
7019 		elink_bits_dis(sc,
7020 			       NIG_REG_STATUS_INTERRUPT_PORT0
7021 			       + port * 4,
7022 			       ELINK_NIG_STATUS_EMAC0_MI_INT);
7023 
7024 	if (latch_status & 1) {
7025 
7026 		/* For all latched-signal=up : Re-Arm Latch signals */
7027 		REG_WR(sc, NIG_REG_LATCH_STATUS_0 + port * 8,
7028 		       (latch_status & 0xfffe) | (latch_status & 1));
7029 	}
7030 	/* For all latched-signal=up,Write original_signal to status */
7031 }
7032 
elink_link_int_ack(struct elink_params * params,struct elink_vars * vars,uint8_t is_10g_plus)7033 static void elink_link_int_ack(struct elink_params *params,
7034 			       struct elink_vars *vars, uint8_t is_10g_plus)
7035 {
7036 	struct bnx2x_softc *sc = params->sc;
7037 	uint8_t port = params->port;
7038 	uint32_t mask;
7039 	/* First reset all status we assume only one line will be
7040 	 * change at a time
7041 	 */
7042 	elink_bits_dis(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port * 4,
7043 		       (ELINK_NIG_STATUS_XGXS0_LINK10G |
7044 			ELINK_NIG_STATUS_XGXS0_LINK_STATUS |
7045 			ELINK_NIG_STATUS_SERDES0_LINK_STATUS));
7046 	if (vars->phy_link_up) {
7047 		if (USES_WARPCORE(sc))
7048 			mask = ELINK_NIG_STATUS_XGXS0_LINK_STATUS;
7049 		else {
7050 			if (is_10g_plus)
7051 				mask = ELINK_NIG_STATUS_XGXS0_LINK10G;
7052 			else if (params->switch_cfg == ELINK_SWITCH_CFG_10G) {
7053 				/* Disable the link interrupt by writing 1 to
7054 				 * the relevant lane in the status register
7055 				 */
7056 				uint32_t ser_lane =
7057 					((params->lane_config &
7058 				    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
7059 				    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
7060 				mask = ((1 << ser_lane) <<
7061 				       ELINK_NIG_STATUS_XGXS0_LINK_STATUS_SIZE);
7062 			} else
7063 				mask = ELINK_NIG_STATUS_SERDES0_LINK_STATUS;
7064 		}
7065 		ELINK_DEBUG_P1(sc, "Ack link up interrupt with mask 0x%x",
7066 			       mask);
7067 		elink_bits_en(sc,
7068 			      NIG_REG_STATUS_INTERRUPT_PORT0 + port * 4,
7069 			      mask);
7070 	}
7071 }
7072 
elink_format_ver(uint32_t num,uint8_t * str,uint16_t * len)7073 static elink_status_t elink_format_ver(uint32_t num, uint8_t *str,
7074 				       uint16_t *len)
7075 {
7076 	uint8_t *str_ptr = str;
7077 	uint32_t mask = 0xf0000000;
7078 	uint8_t shift = 8 * 4;
7079 	uint8_t digit;
7080 	uint8_t remove_leading_zeros = 1;
7081 	if (*len < 10) {
7082 		/* Need more than 10chars for this format */
7083 		*str_ptr = '\0';
7084 		(*len)--;
7085 		return ELINK_STATUS_ERROR;
7086 	}
7087 	while (shift > 0) {
7088 
7089 		shift -= 4;
7090 		digit = ((num & mask) >> shift);
7091 		if (digit == 0 && remove_leading_zeros) {
7092 			mask = mask >> 4;
7093 			continue;
7094 		} else if (digit < 0xa)
7095 			*str_ptr = digit + '0';
7096 		else
7097 			*str_ptr = digit - 0xa + 'a';
7098 		remove_leading_zeros = 0;
7099 		str_ptr++;
7100 		(*len)--;
7101 		mask = mask >> 4;
7102 		if (shift == 4 * 4) {
7103 			*str_ptr = '.';
7104 			str_ptr++;
7105 			(*len)--;
7106 			remove_leading_zeros = 1;
7107 		}
7108 	}
7109 	return ELINK_STATUS_OK;
7110 }
7111 
7112 
elink_null_format_ver(__rte_unused uint32_t spirom_ver,uint8_t * str,uint16_t * len)7113 static elink_status_t elink_null_format_ver(__rte_unused uint32_t spirom_ver,
7114 				 uint8_t *str,
7115 				 uint16_t *len)
7116 {
7117 	str[0] = '\0';
7118 	(*len)--;
7119 	return ELINK_STATUS_OK;
7120 }
7121 
elink_get_ext_phy_fw_version(struct elink_params * params,uint8_t * version,uint16_t len)7122 elink_status_t elink_get_ext_phy_fw_version(struct elink_params *params,
7123 				 uint8_t *version,
7124 				 uint16_t len)
7125 {
7126 	struct bnx2x_softc *sc;
7127 	uint32_t spirom_ver = 0;
7128 	elink_status_t status = ELINK_STATUS_OK;
7129 	uint8_t *ver_p = version;
7130 	uint16_t remain_len = len;
7131 	if (version == NULL || params == NULL)
7132 		return ELINK_STATUS_ERROR;
7133 	sc = params->sc;
7134 
7135 	/* Extract first external phy*/
7136 	version[0] = '\0';
7137 	spirom_ver = REG_RD(sc, params->phy[ELINK_EXT_PHY1].ver_addr);
7138 
7139 	if (params->phy[ELINK_EXT_PHY1].format_fw_ver) {
7140 		status |= params->phy[ELINK_EXT_PHY1].format_fw_ver(spirom_ver,
7141 							      ver_p,
7142 							      &remain_len);
7143 		ver_p += (len - remain_len);
7144 	}
7145 	if ((params->num_phys == ELINK_MAX_PHYS) &&
7146 	    (params->phy[ELINK_EXT_PHY2].ver_addr != 0)) {
7147 		spirom_ver = REG_RD(sc, params->phy[ELINK_EXT_PHY2].ver_addr);
7148 		if (params->phy[ELINK_EXT_PHY2].format_fw_ver) {
7149 			*ver_p = '/';
7150 			ver_p++;
7151 			remain_len--;
7152 			status |= params->phy[ELINK_EXT_PHY2].format_fw_ver(
7153 				spirom_ver,
7154 				ver_p,
7155 				&remain_len);
7156 			ver_p = version + (len - remain_len);
7157 		}
7158 	}
7159 	*ver_p = '\0';
7160 	return status;
7161 }
7162 
elink_set_xgxs_loopback(struct elink_phy * phy,struct elink_params * params)7163 static void elink_set_xgxs_loopback(struct elink_phy *phy,
7164 				    struct elink_params *params)
7165 {
7166 	uint8_t port = params->port;
7167 	struct bnx2x_softc *sc = params->sc;
7168 
7169 	if (phy->req_line_speed != ELINK_SPEED_1000) {
7170 		uint32_t md_devad = 0;
7171 
7172 		ELINK_DEBUG_P0(sc, "XGXS 10G loopback enable");
7173 
7174 		if (!CHIP_IS_E3(sc)) {
7175 			/* Change the uni_phy_addr in the nig */
7176 			md_devad = REG_RD(sc, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
7177 					       port * 0x18));
7178 
7179 			REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + port * 0x18,
7180 			       0x5);
7181 		}
7182 
7183 		elink_cl45_write(sc, phy,
7184 				 5,
7185 				 (MDIO_REG_BANK_AER_BLOCK +
7186 				  (MDIO_AER_BLOCK_AER_REG & 0xf)),
7187 				 0x2800);
7188 
7189 		elink_cl45_write(sc, phy,
7190 				 5,
7191 				 (MDIO_REG_BANK_CL73_IEEEB0 +
7192 				  (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
7193 				 0x6041);
7194 		DELAY(1000 * 200);
7195 		/* Set aer mmd back */
7196 		elink_set_aer_mmd(params, phy);
7197 
7198 		if (!CHIP_IS_E3(sc)) {
7199 			/* And md_devad */
7200 			REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + port * 0x18,
7201 			       md_devad);
7202 		}
7203 	} else {
7204 		uint16_t mii_ctrl;
7205 		ELINK_DEBUG_P0(sc, "XGXS 1G loopback enable");
7206 		elink_cl45_read(sc, phy, 5,
7207 				(MDIO_REG_BANK_COMBO_IEEE0 +
7208 				(MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
7209 				&mii_ctrl);
7210 		elink_cl45_write(sc, phy, 5,
7211 				 (MDIO_REG_BANK_COMBO_IEEE0 +
7212 				 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
7213 				 mii_ctrl |
7214 				 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
7215 	}
7216 }
7217 
elink_set_led(struct elink_params * params,struct elink_vars * vars,uint8_t mode,uint32_t speed)7218 elink_status_t elink_set_led(struct elink_params *params,
7219 		  struct elink_vars *vars, uint8_t mode, uint32_t speed)
7220 {
7221 	uint8_t port = params->port;
7222 	uint16_t hw_led_mode = params->hw_led_mode;
7223 	elink_status_t rc = ELINK_STATUS_OK;
7224 	uint8_t phy_idx;
7225 	uint32_t tmp;
7226 	uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
7227 	struct bnx2x_softc *sc = params->sc;
7228 	ELINK_DEBUG_P2(sc, "elink_set_led: port %x, mode %d", port, mode);
7229 	ELINK_DEBUG_P2(sc, "speed 0x%x, hw_led_mode 0x%x",
7230 		 speed, hw_led_mode);
7231 	/* In case */
7232 	for (phy_idx = ELINK_EXT_PHY1; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
7233 		if (params->phy[phy_idx].set_link_led) {
7234 			params->phy[phy_idx].set_link_led(
7235 				&params->phy[phy_idx], params, mode);
7236 		}
7237 	}
7238 #ifdef ELINK_INCLUDE_EMUL
7239 	if (params->feature_config_flags &
7240 	    ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC)
7241 		return rc;
7242 #endif
7243 
7244 	switch (mode) {
7245 	case ELINK_LED_MODE_FRONT_PANEL_OFF:
7246 	case ELINK_LED_MODE_OFF:
7247 		REG_WR(sc, NIG_REG_LED_10G_P0 + port * 4, 0);
7248 		REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4,
7249 		       SHARED_HW_CFG_LED_MAC1);
7250 
7251 		tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7252 		if (params->phy[ELINK_EXT_PHY1].type ==
7253 			PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE)
7254 			tmp &= ~(EMAC_LED_1000MB_OVERRIDE |
7255 				EMAC_LED_100MB_OVERRIDE |
7256 				EMAC_LED_10MB_OVERRIDE);
7257 		else
7258 			tmp |= EMAC_LED_OVERRIDE;
7259 
7260 		elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED, tmp);
7261 		break;
7262 
7263 	case ELINK_LED_MODE_OPER:
7264 		/* For all other phys, OPER mode is same as ON, so in case
7265 		 * link is down, do nothing
7266 		 */
7267 		if (!vars->link_up)
7268 			break;
7269 		/* fallthrough */
7270 	case ELINK_LED_MODE_ON:
7271 		if (((params->phy[ELINK_EXT_PHY1].type ==
7272 			  PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727) ||
7273 			 (params->phy[ELINK_EXT_PHY1].type ==
7274 			  PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722)) &&
7275 		    CHIP_IS_E2(sc) && params->num_phys == 2) {
7276 			/* This is a work-around for E2 + 8727 Configurations */
7277 			if (mode == ELINK_LED_MODE_ON ||
7278 				speed == ELINK_SPEED_10000){
7279 				REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4, 0);
7280 				REG_WR(sc, NIG_REG_LED_10G_P0 + port * 4, 1);
7281 
7282 				tmp = elink_cb_reg_read(sc, emac_base +
7283 							EMAC_REG_EMAC_LED);
7284 				elink_cb_reg_write(sc, emac_base +
7285 						   EMAC_REG_EMAC_LED,
7286 						   (tmp | EMAC_LED_OVERRIDE));
7287 				/* Return here without enabling traffic
7288 				 * LED blink and setting rate in ON mode.
7289 				 * In oper mode, enabling LED blink
7290 				 * and setting rate is needed.
7291 				 */
7292 				if (mode == ELINK_LED_MODE_ON)
7293 					return rc;
7294 			}
7295 		} else if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
7296 			/* This is a work-around for HW issue found when link
7297 			 * is up in CL73
7298 			 */
7299 			if ((!CHIP_IS_E3(sc)) ||
7300 			    (CHIP_IS_E3(sc) &&
7301 			     mode == ELINK_LED_MODE_ON))
7302 				REG_WR(sc, NIG_REG_LED_10G_P0 + port * 4, 1);
7303 
7304 			if (CHIP_IS_E1x(sc) ||
7305 			    CHIP_IS_E2(sc) ||
7306 			    (mode == ELINK_LED_MODE_ON))
7307 				REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4, 0);
7308 			else
7309 				REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4,
7310 				       hw_led_mode);
7311 		} else if ((params->phy[ELINK_EXT_PHY1].type ==
7312 			    PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE) &&
7313 			   (mode == ELINK_LED_MODE_ON)) {
7314 			REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4, 0);
7315 			tmp = elink_cb_reg_read(sc, emac_base +
7316 						EMAC_REG_EMAC_LED);
7317 			elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED,
7318 					   tmp | EMAC_LED_OVERRIDE |
7319 					   EMAC_LED_1000MB_OVERRIDE);
7320 			/* Break here; otherwise, it'll disable the
7321 			 * intended override.
7322 			 */
7323 			break;
7324 		} else {
7325 			uint32_t nig_led_mode = ((params->hw_led_mode <<
7326 					     SHARED_HW_CFG_LED_MODE_SHIFT) ==
7327 					    SHARED_HW_CFG_LED_EXTPHY2) ?
7328 				(SHARED_HW_CFG_LED_PHY1 >>
7329 				 SHARED_HW_CFG_LED_MODE_SHIFT) : hw_led_mode;
7330 			REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4,
7331 			       nig_led_mode);
7332 		}
7333 
7334 		REG_WR(sc, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port * 4,
7335 		       0);
7336 		/* Set blinking rate to ~15.9Hz */
7337 		if (CHIP_IS_E3(sc))
7338 			REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port * 4,
7339 			       LED_BLINK_RATE_VAL_E3);
7340 		else
7341 			REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port * 4,
7342 			       LED_BLINK_RATE_VAL_E1X_E2);
7343 		REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
7344 		       port * 4, 1);
7345 		tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7346 		elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED,
7347 			(tmp & (~EMAC_LED_OVERRIDE)));
7348 
7349 		if (CHIP_IS_E1(sc) &&
7350 		    ((speed == ELINK_SPEED_2500) ||
7351 		     (speed == ELINK_SPEED_1000) ||
7352 		     (speed == ELINK_SPEED_100) ||
7353 		     (speed == ELINK_SPEED_10))) {
7354 			/* For speeds less than 10G LED scheme is different */
7355 			REG_WR(sc, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
7356 			       + port * 4, 1);
7357 			REG_WR(sc, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
7358 			       port * 4, 0);
7359 			REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
7360 			       port * 4, 1);
7361 		}
7362 		break;
7363 
7364 	default:
7365 		rc = ELINK_STATUS_ERROR;
7366 		ELINK_DEBUG_P1(sc, "elink_set_led: Invalid led mode %d",
7367 			 mode);
7368 		break;
7369 	}
7370 	return rc;
7371 
7372 }
7373 
7374 /* This function comes to reflect the actual link state read DIRECTLY from the
7375  * HW
7376  */
elink_test_link(struct elink_params * params,__rte_unused struct elink_vars * vars,uint8_t is_serdes)7377 elink_status_t elink_test_link(struct elink_params *params,
7378 			       __rte_unused struct elink_vars *vars,
7379 		    uint8_t is_serdes)
7380 {
7381 	struct bnx2x_softc *sc = params->sc;
7382 	uint16_t gp_status = 0, phy_index = 0;
7383 	uint8_t ext_phy_link_up = 0, serdes_phy_type;
7384 	struct elink_vars temp_vars;
7385 	struct elink_phy *int_phy = &params->phy[ELINK_INT_PHY];
7386 #ifdef ELINK_INCLUDE_FPGA
7387 	if (CHIP_REV_IS_FPGA(sc))
7388 		return ELINK_STATUS_OK;
7389 #endif
7390 #ifdef ELINK_INCLUDE_EMUL
7391 	if (CHIP_REV_IS_EMUL(sc))
7392 		return ELINK_STATUS_OK;
7393 #endif
7394 
7395 	if (CHIP_IS_E3(sc)) {
7396 		uint16_t link_up;
7397 		if (params->req_line_speed[ELINK_LINK_CONFIG_IDX(ELINK_INT_PHY)]
7398 		    > ELINK_SPEED_10000) {
7399 			/* Check 20G link */
7400 			elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7401 					1, &link_up);
7402 			elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7403 					1, &link_up);
7404 			link_up &= (1 << 2);
7405 		} else {
7406 			/* Check 10G link and below*/
7407 			uint8_t lane = elink_get_warpcore_lane(int_phy, params);
7408 			elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7409 					MDIO_WC_REG_GP2_STATUS_GP_2_1,
7410 					&gp_status);
7411 			gp_status = ((gp_status >> 8) & 0xf) |
7412 				((gp_status >> 12) & 0xf);
7413 			link_up = gp_status & (1 << lane);
7414 		}
7415 		if (!link_up)
7416 			return ELINK_STATUS_NO_LINK;
7417 	} else {
7418 		CL22_RD_OVER_CL45(sc, int_phy,
7419 			  MDIO_REG_BANK_GP_STATUS,
7420 			  MDIO_GP_STATUS_TOP_AN_STATUS1,
7421 			  &gp_status);
7422 	/* Link is up only if both local phy and external phy are up */
7423 	if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
7424 		return ELINK_STATUS_NO_LINK;
7425 	}
7426 	/* In XGXS loopback mode, do not check external PHY */
7427 	if (params->loopback_mode == ELINK_LOOPBACK_XGXS)
7428 		return ELINK_STATUS_OK;
7429 
7430 	switch (params->num_phys) {
7431 	case 1:
7432 		/* No external PHY */
7433 		return ELINK_STATUS_OK;
7434 	case 2:
7435 		ext_phy_link_up = params->phy[ELINK_EXT_PHY1].read_status(
7436 			&params->phy[ELINK_EXT_PHY1],
7437 			params, &temp_vars);
7438 		break;
7439 	case 3: /* Dual Media */
7440 		for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7441 		      phy_index++) {
7442 			serdes_phy_type = ((params->phy[phy_index].media_type ==
7443 					    ELINK_ETH_PHY_SFPP_10G_FIBER) ||
7444 					   (params->phy[phy_index].media_type ==
7445 					    ELINK_ETH_PHY_SFP_1G_FIBER) ||
7446 					   (params->phy[phy_index].media_type ==
7447 					    ELINK_ETH_PHY_XFP_FIBER) ||
7448 					   (params->phy[phy_index].media_type ==
7449 					    ELINK_ETH_PHY_DA_TWINAX));
7450 
7451 			if (is_serdes != serdes_phy_type)
7452 				continue;
7453 			if (params->phy[phy_index].read_status) {
7454 				ext_phy_link_up |=
7455 					params->phy[phy_index].read_status(
7456 						&params->phy[phy_index],
7457 						params, &temp_vars);
7458 			}
7459 		}
7460 		break;
7461 	}
7462 	if (ext_phy_link_up)
7463 		return ELINK_STATUS_OK;
7464 	return ELINK_STATUS_NO_LINK;
7465 }
7466 
elink_link_initialize(struct elink_params * params,struct elink_vars * vars)7467 static elink_status_t elink_link_initialize(struct elink_params *params,
7468 				 struct elink_vars *vars)
7469 {
7470 	uint8_t phy_index, non_ext_phy;
7471 	struct bnx2x_softc *sc = params->sc;
7472 	/* In case of external phy existence, the line speed would be the
7473 	 * line speed linked up by the external phy. In case it is direct
7474 	 * only, then the line_speed during initialization will be
7475 	 * equal to the req_line_speed
7476 	 */
7477 	vars->line_speed = params->phy[ELINK_INT_PHY].req_line_speed;
7478 
7479 	/* Initialize the internal phy in case this is a direct board
7480 	 * (no external phys), or this board has external phy which requires
7481 	 * to first.
7482 	 */
7483 	if (!USES_WARPCORE(sc))
7484 		elink_prepare_xgxs(&params->phy[ELINK_INT_PHY], params, vars);
7485 	/* init ext phy and enable link state int */
7486 	non_ext_phy = (ELINK_SINGLE_MEDIA_DIRECT(params) ||
7487 		       (params->loopback_mode == ELINK_LOOPBACK_XGXS));
7488 
7489 	if (non_ext_phy ||
7490 	    (params->phy[ELINK_EXT_PHY1].flags & ELINK_FLAGS_INIT_XGXS_FIRST) ||
7491 	    (params->loopback_mode == ELINK_LOOPBACK_EXT_PHY)) {
7492 		struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
7493 		if (vars->line_speed == ELINK_SPEED_AUTO_NEG &&
7494 		    (CHIP_IS_E1x(sc) ||
7495 		     CHIP_IS_E2(sc)))
7496 			elink_set_parallel_detection(phy, params);
7497 		if (params->phy[ELINK_INT_PHY].config_init)
7498 			params->phy[ELINK_INT_PHY].config_init(phy, params,
7499 							       vars);
7500 	}
7501 
7502 	/* Re-read this value in case it was changed inside config_init due to
7503 	 * limitations of optic module
7504 	 */
7505 	vars->line_speed = params->phy[ELINK_INT_PHY].req_line_speed;
7506 
7507 	/* Init external phy*/
7508 	if (non_ext_phy) {
7509 		if (params->phy[ELINK_INT_PHY].supported &
7510 		    ELINK_SUPPORTED_FIBRE)
7511 			vars->link_status |= LINK_STATUS_SERDES_LINK;
7512 	} else {
7513 		for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7514 		      phy_index++) {
7515 			/* No need to initialize second phy in case of first
7516 			 * phy only selection. In case of second phy, we do
7517 			 * need to initialize the first phy, since they are
7518 			 * connected.
7519 			 */
7520 			if (params->phy[phy_index].supported &
7521 			    ELINK_SUPPORTED_FIBRE)
7522 				vars->link_status |= LINK_STATUS_SERDES_LINK;
7523 
7524 			if (phy_index == ELINK_EXT_PHY2 &&
7525 			    (elink_phy_selection(params) ==
7526 			     PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
7527 				ELINK_DEBUG_P0(sc,
7528 				   "Not initializing second phy");
7529 				continue;
7530 			}
7531 			params->phy[phy_index].config_init(
7532 				&params->phy[phy_index],
7533 				params, vars);
7534 		}
7535 	}
7536 	/* Reset the interrupt indication after phy was initialized */
7537 	elink_bits_dis(sc, NIG_REG_STATUS_INTERRUPT_PORT0 +
7538 		       params->port * 4,
7539 		       (ELINK_NIG_STATUS_XGXS0_LINK10G |
7540 			ELINK_NIG_STATUS_XGXS0_LINK_STATUS |
7541 			ELINK_NIG_STATUS_SERDES0_LINK_STATUS |
7542 			ELINK_NIG_MASK_MI_INT));
7543 	return ELINK_STATUS_OK;
7544 }
7545 
elink_int_link_reset(__rte_unused struct elink_phy * phy,struct elink_params * params)7546 static void elink_int_link_reset(__rte_unused struct elink_phy *phy,
7547 				 struct elink_params *params)
7548 {
7549 	/* Reset the SerDes/XGXS */
7550 	REG_WR(params->sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
7551 	       (0x1ff << (params->port * 16)));
7552 }
7553 
elink_common_ext_link_reset(__rte_unused struct elink_phy * phy,struct elink_params * params)7554 static void elink_common_ext_link_reset(__rte_unused struct elink_phy *phy,
7555 					struct elink_params *params)
7556 {
7557 	struct bnx2x_softc *sc = params->sc;
7558 	uint8_t gpio_port;
7559 	/* HW reset */
7560 	if (CHIP_IS_E2(sc))
7561 		gpio_port = SC_PATH(sc);
7562 	else
7563 		gpio_port = params->port;
7564 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
7565 		       MISC_REGISTERS_GPIO_OUTPUT_LOW,
7566 		       gpio_port);
7567 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
7568 		       MISC_REGISTERS_GPIO_OUTPUT_LOW,
7569 		       gpio_port);
7570 	ELINK_DEBUG_P0(sc, "reset external PHY");
7571 }
7572 
elink_update_link_down(struct elink_params * params,struct elink_vars * vars)7573 static elink_status_t elink_update_link_down(struct elink_params *params,
7574 				  struct elink_vars *vars)
7575 {
7576 	struct bnx2x_softc *sc = params->sc;
7577 	uint8_t port = params->port;
7578 
7579 	ELINK_DEBUG_P1(sc, "Port %x: Link is down", port);
7580 	elink_set_led(params, vars, ELINK_LED_MODE_OFF, 0);
7581 	vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG;
7582 	/* Indicate no mac active */
7583 	vars->mac_type = ELINK_MAC_TYPE_NONE;
7584 
7585 	/* Update shared memory */
7586 	vars->link_status &= ~ELINK_LINK_UPDATE_MASK;
7587 	vars->line_speed = 0;
7588 	elink_update_mng(params, vars->link_status);
7589 
7590 	/* Activate nig drain */
7591 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port * 4, 1);
7592 
7593 	/* Disable emac */
7594 	if (!CHIP_IS_E3(sc))
7595 		REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port * 4, 0);
7596 
7597 	DELAY(1000 * 10);
7598 	/* Reset BigMac/Xmac */
7599 	if (CHIP_IS_E1x(sc) ||
7600 	    CHIP_IS_E2(sc))
7601 		elink_set_bmac_rx(sc, params->chip_id, params->port, 0);
7602 
7603 	if (CHIP_IS_E3(sc)) {
7604 		/* Prevent LPI Generation by chip */
7605 		REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2),
7606 		       0);
7607 		REG_WR(sc, MISC_REG_CPMU_LP_MASK_ENT_P0 + (params->port << 2),
7608 		       0);
7609 		vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
7610 				      SHMEM_EEE_ACTIVE_BIT);
7611 
7612 		elink_update_mng_eee(params, vars->eee_status);
7613 		elink_set_xmac_rxtx(params, 0);
7614 		elink_set_umac_rxtx(params, 0);
7615 	}
7616 
7617 	return ELINK_STATUS_OK;
7618 }
7619 
elink_update_link_up(struct elink_params * params,struct elink_vars * vars,uint8_t link_10g)7620 static elink_status_t elink_update_link_up(struct elink_params *params,
7621 				struct elink_vars *vars,
7622 				uint8_t link_10g)
7623 {
7624 	struct bnx2x_softc *sc = params->sc;
7625 	uint8_t phy_idx, port = params->port;
7626 	elink_status_t rc = ELINK_STATUS_OK;
7627 
7628 	vars->link_status |= (LINK_STATUS_LINK_UP |
7629 			      LINK_STATUS_PHYSICAL_LINK_FLAG);
7630 	vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
7631 
7632 	if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
7633 		vars->link_status |=
7634 			LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
7635 
7636 	if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
7637 		vars->link_status |=
7638 			LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
7639 	if (USES_WARPCORE(sc)) {
7640 		if (link_10g) {
7641 			if (elink_xmac_enable(params, vars, 0) ==
7642 			    ELINK_STATUS_NO_LINK) {
7643 				ELINK_DEBUG_P0(sc, "Found errors on XMAC");
7644 				vars->link_up = 0;
7645 				vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
7646 				vars->link_status &= ~LINK_STATUS_LINK_UP;
7647 			}
7648 		} else
7649 			elink_umac_enable(params, vars, 0);
7650 		elink_set_led(params, vars,
7651 			      ELINK_LED_MODE_OPER, vars->line_speed);
7652 
7653 		if ((vars->eee_status & SHMEM_EEE_ACTIVE_BIT) &&
7654 		    (vars->eee_status & SHMEM_EEE_LPI_REQUESTED_BIT)) {
7655 			ELINK_DEBUG_P0(sc, "Enabling LPI assertion");
7656 			REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 +
7657 			       (params->port << 2), 1);
7658 			REG_WR(sc, MISC_REG_CPMU_LP_DR_ENABLE, 1);
7659 			REG_WR(sc, MISC_REG_CPMU_LP_MASK_ENT_P0 +
7660 			       (params->port << 2), 0xfc20);
7661 		}
7662 	}
7663 	if ((CHIP_IS_E1x(sc) ||
7664 	     CHIP_IS_E2(sc))) {
7665 		if (link_10g) {
7666 			if (elink_bmac_enable(params, vars, 0, 1) ==
7667 			    ELINK_STATUS_NO_LINK) {
7668 				ELINK_DEBUG_P0(sc, "Found errors on BMAC");
7669 				vars->link_up = 0;
7670 				vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
7671 				vars->link_status &= ~LINK_STATUS_LINK_UP;
7672 			}
7673 
7674 			elink_set_led(params, vars,
7675 				      ELINK_LED_MODE_OPER, ELINK_SPEED_10000);
7676 		} else {
7677 			rc = elink_emac_program(params, vars);
7678 			elink_emac_enable(params, vars, 0);
7679 
7680 			/* AN complete? */
7681 			if ((vars->link_status &
7682 			     LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
7683 			    && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
7684 			    ELINK_SINGLE_MEDIA_DIRECT(params))
7685 				elink_set_gmii_tx_driver(params);
7686 		}
7687 	}
7688 
7689 	/* PBF - link up */
7690 	if (CHIP_IS_E1x(sc))
7691 		rc |= elink_pbf_update(params, vars->flow_ctrl,
7692 				       vars->line_speed);
7693 
7694 	/* Disable drain */
7695 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port * 4, 0);
7696 
7697 	/* Update shared memory */
7698 	elink_update_mng(params, vars->link_status);
7699 	elink_update_mng_eee(params, vars->eee_status);
7700 	/* Check remote fault */
7701 	for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
7702 		if (params->phy[phy_idx].flags & ELINK_FLAGS_TX_ERROR_CHECK) {
7703 			elink_check_half_open_conn(params, vars, 0);
7704 			break;
7705 		}
7706 	}
7707 	DELAY(1000 * 20);
7708 	return rc;
7709 }
7710 
elink_chng_link_count(struct elink_params * params,uint8_t clear)7711 static void elink_chng_link_count(struct elink_params *params, uint8_t clear)
7712 {
7713 	struct bnx2x_softc *sc = params->sc;
7714 	uint32_t addr, val;
7715 
7716 	/* Verify the link_change_count is supported by the MFW */
7717 	if (!(SHMEM2_HAS(sc, link_change_count)))
7718 		return;
7719 
7720 	addr = params->shmem2_base +
7721 		offsetof(struct shmem2_region, link_change_count[params->port]);
7722 	if (clear)
7723 		val = 0;
7724 	else
7725 		val = REG_RD(sc, addr) + 1;
7726 	REG_WR(sc, addr, val);
7727 }
7728 
7729 /* The elink_link_update function should be called upon link
7730  * interrupt.
7731  * Link is considered up as follows:
7732  * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
7733  *   to be up
7734  * - SINGLE_MEDIA - The link between the 577xx and the external
7735  *   phy (XGXS) need to up as well as the external link of the
7736  *   phy (PHY_EXT1)
7737  * - DUAL_MEDIA - The link between the 577xx and the first
7738  *   external phy needs to be up, and at least one of the 2
7739  *   external phy link must be up.
7740  */
elink_link_update(struct elink_params * params,struct elink_vars * vars)7741 elink_status_t elink_link_update(struct elink_params *params,
7742 				 struct elink_vars *vars)
7743 {
7744 	struct bnx2x_softc *sc = params->sc;
7745 	struct elink_vars phy_vars[ELINK_MAX_PHYS];
7746 	uint8_t port = params->port;
7747 	uint8_t link_10g_plus, phy_index;
7748 	uint32_t prev_link_status = vars->link_status;
7749 	uint8_t ext_phy_link_up = 0, cur_link_up;
7750 	elink_status_t rc = ELINK_STATUS_OK;
7751 	uint16_t ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
7752 	uint8_t active_external_phy = ELINK_INT_PHY;
7753 	vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
7754 	vars->link_status &= ~ELINK_LINK_UPDATE_MASK;
7755 	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
7756 	      phy_index++) {
7757 		phy_vars[phy_index].flow_ctrl = 0;
7758 		phy_vars[phy_index].link_status = 0;
7759 		phy_vars[phy_index].line_speed = 0;
7760 		phy_vars[phy_index].duplex = DUPLEX_FULL;
7761 		phy_vars[phy_index].phy_link_up = 0;
7762 		phy_vars[phy_index].link_up = 0;
7763 		phy_vars[phy_index].fault_detected = 0;
7764 		/* different consideration, since vars holds inner state */
7765 		phy_vars[phy_index].eee_status = vars->eee_status;
7766 	}
7767 
7768 	if (USES_WARPCORE(sc))
7769 		elink_set_aer_mmd(params, &params->phy[ELINK_INT_PHY]);
7770 
7771 	ELINK_DEBUG_P3(sc, "port %x, XGXS?%x, int_status 0x%x",
7772 		 port, (vars->phy_flags & PHY_XGXS_FLAG),
7773 		 REG_RD(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port * 4));
7774 
7775 	ELINK_DEBUG_P3(sc, "int_mask 0x%x MI_INT %x, SERDES_LINK %x",
7776 		 REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port * 4),
7777 		 REG_RD(sc, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port * 0x18) > 0,
7778 		 REG_RD(sc, NIG_REG_SERDES0_STATUS_LINK_STATUS + port * 0x3c));
7779 
7780 	ELINK_DEBUG_P2(sc, " 10G %x, XGXS_LINK %x",
7781 	  REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK10G + port * 0x68),
7782 	  REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK_STATUS + port * 0x68));
7783 
7784 	/* Disable emac */
7785 	if (!CHIP_IS_E3(sc))
7786 		REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port * 4, 0);
7787 
7788 	/* Step 1:
7789 	 * Check external link change only for external phys, and apply
7790 	 * priority selection between them in case the link on both phys
7791 	 * is up. Note that instead of the common vars, a temporary
7792 	 * vars argument is used since each phy may have different link/
7793 	 * speed/duplex result
7794 	 */
7795 	for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7796 	      phy_index++) {
7797 		struct elink_phy *phy = &params->phy[phy_index];
7798 		if (!phy->read_status)
7799 			continue;
7800 		/* Read link status and params of this ext phy */
7801 		cur_link_up = phy->read_status(phy, params,
7802 					       &phy_vars[phy_index]);
7803 		if (cur_link_up) {
7804 			ELINK_DEBUG_P1(sc, "phy in index %d link is up",
7805 				   phy_index);
7806 		} else {
7807 			ELINK_DEBUG_P1(sc, "phy in index %d link is down",
7808 				   phy_index);
7809 			continue;
7810 		}
7811 
7812 		if (!ext_phy_link_up) {
7813 			ext_phy_link_up = 1;
7814 			active_external_phy = phy_index;
7815 		} else {
7816 			switch (elink_phy_selection(params)) {
7817 			case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
7818 			case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
7819 			/* In this option, the first PHY makes sure to pass the
7820 			 * traffic through itself only.
7821 			 * Its not clear how to reset the link on the second phy
7822 			 */
7823 				active_external_phy = ELINK_EXT_PHY1;
7824 				break;
7825 			case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
7826 			/* In this option, the first PHY makes sure to pass the
7827 			 * traffic through the second PHY.
7828 			 */
7829 				active_external_phy = ELINK_EXT_PHY2;
7830 				break;
7831 			default:
7832 			/* Link indication on both PHYs with the following cases
7833 			 * is invalid:
7834 			 * - FIRST_PHY means that second phy wasn't initialized,
7835 			 * hence its link is expected to be down
7836 			 * - SECOND_PHY means that first phy should not be able
7837 			 * to link up by itself (using configuration)
7838 			 * - DEFAULT should be overridden during initialization
7839 			 */
7840 				ELINK_DEBUG_P1(sc, "Invalid link indication"
7841 					       " mpc=0x%x. DISABLING LINK !!!",
7842 					   params->multi_phy_config);
7843 				ext_phy_link_up = 0;
7844 				break;
7845 			}
7846 		}
7847 	}
7848 	prev_line_speed = vars->line_speed;
7849 	/* Step 2:
7850 	 * Read the status of the internal phy. In case of
7851 	 * DIRECT_SINGLE_MEDIA board, this link is the external link,
7852 	 * otherwise this is the link between the 577xx and the first
7853 	 * external phy
7854 	 */
7855 	if (params->phy[ELINK_INT_PHY].read_status)
7856 		params->phy[ELINK_INT_PHY].read_status(
7857 			&params->phy[ELINK_INT_PHY],
7858 			params, vars);
7859 	/* The INT_PHY flow control reside in the vars. This include the
7860 	 * case where the speed or flow control are not set to AUTO.
7861 	 * Otherwise, the active external phy flow control result is set
7862 	 * to the vars. The ext_phy_line_speed is needed to check if the
7863 	 * speed is different between the internal phy and external phy.
7864 	 * This case may be result of intermediate link speed change.
7865 	 */
7866 	if (active_external_phy > ELINK_INT_PHY) {
7867 		vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
7868 		/* Link speed is taken from the XGXS. AN and FC result from
7869 		 * the external phy.
7870 		 */
7871 		vars->link_status |= phy_vars[active_external_phy].link_status;
7872 
7873 		/* if active_external_phy is first PHY and link is up - disable
7874 		 * disable TX on second external PHY
7875 		 */
7876 		if (active_external_phy == ELINK_EXT_PHY1) {
7877 			if (params->phy[ELINK_EXT_PHY2].phy_specific_func) {
7878 				ELINK_DEBUG_P0(sc,
7879 				   "Disabling TX on EXT_PHY2");
7880 				params->phy[ELINK_EXT_PHY2].phy_specific_func(
7881 					&params->phy[ELINK_EXT_PHY2],
7882 					params, ELINK_DISABLE_TX);
7883 			}
7884 		}
7885 
7886 		ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
7887 		vars->duplex = phy_vars[active_external_phy].duplex;
7888 		if (params->phy[active_external_phy].supported &
7889 		    ELINK_SUPPORTED_FIBRE)
7890 			vars->link_status |= LINK_STATUS_SERDES_LINK;
7891 		else
7892 			vars->link_status &= ~LINK_STATUS_SERDES_LINK;
7893 
7894 		vars->eee_status = phy_vars[active_external_phy].eee_status;
7895 
7896 		ELINK_DEBUG_P1(sc, "Active external phy selected: %x",
7897 			   active_external_phy);
7898 	}
7899 
7900 	ELINK_DEBUG_P3(sc, "vars : phy_flags = %x, mac_type = %x, phy_link_up = %x",
7901 		       vars->phy_flags, vars->mac_type, vars->phy_link_up);
7902 	ELINK_DEBUG_P3(sc, "vars : link_up = %x, line_speed = %x, duplex = %x",
7903 		       vars->link_up, vars->line_speed, vars->duplex);
7904 	ELINK_DEBUG_P3(sc, "vars : flow_ctrl = %x, ieee_fc = %x, link_status = %x",
7905 		       vars->flow_ctrl, vars->ieee_fc, vars->link_status);
7906 	ELINK_DEBUG_P3(sc, "vars : eee_status = %x, fault_detected = %x, check_kr2_recovery_cnt = %x",
7907 		       vars->eee_status, vars->fault_detected,
7908 		       vars->check_kr2_recovery_cnt);
7909 	ELINK_DEBUG_P3(sc, "vars : periodic_flags = %x, aeu_int_mask = %x, rx_tx_asic_rst = %x",
7910 		       vars->periodic_flags, vars->aeu_int_mask,
7911 		       vars->rx_tx_asic_rst);
7912 	ELINK_DEBUG_P2(sc, "vars : turn_to_run_wc_rt = %x, rsrv2 = %x",
7913 		       vars->turn_to_run_wc_rt, vars->rsrv2);
7914 
7915 	for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7916 	      phy_index++) {
7917 		if (params->phy[phy_index].flags &
7918 		    ELINK_FLAGS_REARM_LATCH_SIGNAL) {
7919 			elink_rearm_latch_signal(sc, port,
7920 						 phy_index ==
7921 						 active_external_phy);
7922 			break;
7923 		}
7924 	}
7925 	ELINK_DEBUG_P3(sc, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
7926 		   " ext_phy_line_speed = %d", vars->flow_ctrl,
7927 		   vars->link_status, ext_phy_line_speed);
7928 	/* Upon link speed change set the NIG into drain mode. Comes to
7929 	 * deals with possible FIFO glitch due to clk change when speed
7930 	 * is decreased without link down indicator
7931 	 */
7932 
7933 	if (vars->phy_link_up) {
7934 		if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
7935 		    (ext_phy_line_speed != vars->line_speed)) {
7936 			ELINK_DEBUG_P2(sc, "Internal link speed %d is"
7937 				   " different than the external"
7938 				   " link speed %d", vars->line_speed,
7939 				   ext_phy_line_speed);
7940 			vars->phy_link_up = 0;
7941 			ELINK_DEBUG_P0(sc, "phy_link_up set to 0");
7942 		} else if (prev_line_speed != vars->line_speed) {
7943 			REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE +
7944 			       params->port * 4, 0);
7945 			DELAY(1000 * 1);
7946 		}
7947 	}
7948 
7949 	/* Anything 10 and over uses the bmac */
7950 	link_10g_plus = (vars->line_speed >= ELINK_SPEED_10000);
7951 
7952 	elink_link_int_ack(params, vars, link_10g_plus);
7953 
7954 	/* In case external phy link is up, and internal link is down
7955 	 * (not initialized yet probably after link initialization, it
7956 	 * needs to be initialized.
7957 	 * Note that after link down-up as result of cable plug, the xgxs
7958 	 * link would probably become up again without the need
7959 	 * initialize it
7960 	 */
7961 	if (!(ELINK_SINGLE_MEDIA_DIRECT(params))) {
7962 		ELINK_DEBUG_P3(sc, "ext_phy_link_up = %d, int_link_up = %d,"
7963 			   " init_preceding = %d", ext_phy_link_up,
7964 			   vars->phy_link_up,
7965 			   params->phy[ELINK_EXT_PHY1].flags &
7966 			   ELINK_FLAGS_INIT_XGXS_FIRST);
7967 		if (!(params->phy[ELINK_EXT_PHY1].flags &
7968 		      ELINK_FLAGS_INIT_XGXS_FIRST)
7969 		    && ext_phy_link_up && !vars->phy_link_up) {
7970 			vars->line_speed = ext_phy_line_speed;
7971 			if (vars->line_speed < ELINK_SPEED_1000)
7972 				vars->phy_flags |= PHY_SGMII_FLAG;
7973 			else
7974 				vars->phy_flags &= ~PHY_SGMII_FLAG;
7975 
7976 			if (params->phy[ELINK_INT_PHY].config_init)
7977 				params->phy[ELINK_INT_PHY].config_init(
7978 					&params->phy[ELINK_INT_PHY], params,
7979 						vars);
7980 		}
7981 	}
7982 	/* Link is up only if both local phy and external phy (in case of
7983 	 * non-direct board) are up and no fault detected on active PHY.
7984 	 */
7985 	vars->link_up = (vars->phy_link_up &&
7986 			 (ext_phy_link_up ||
7987 			  ELINK_SINGLE_MEDIA_DIRECT(params)) &&
7988 			 (phy_vars[active_external_phy].fault_detected == 0));
7989 
7990 	if (vars->link_up)
7991 		ELINK_DEBUG_P0(sc, "local phy and external phy are up");
7992 	else
7993 		ELINK_DEBUG_P0(sc, "either local phy or external phy or both are down");
7994 
7995 	/* Update the PFC configuration in case it was changed */
7996 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
7997 		vars->link_status |= LINK_STATUS_PFC_ENABLED;
7998 	else
7999 		vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
8000 
8001 	if (vars->link_up)
8002 		rc = elink_update_link_up(params, vars, link_10g_plus);
8003 	else
8004 		rc = elink_update_link_down(params, vars);
8005 
8006 	if ((prev_link_status ^ vars->link_status) & LINK_STATUS_LINK_UP)
8007 		elink_chng_link_count(params, 0);
8008 
8009 	/* Update MCP link status was changed */
8010 	if (params->feature_config_flags &
8011 	    ELINK_FEATURE_CONFIG_BC_SUPPORTS_AFEX)
8012 		elink_cb_fw_command(sc, DRV_MSG_CODE_LINK_STATUS_CHANGED, 0);
8013 
8014 	return rc;
8015 }
8016 
8017 /*****************************************************************************/
8018 /*			    External Phy section			     */
8019 /*****************************************************************************/
elink_ext_phy_hw_reset(struct bnx2x_softc * sc,uint8_t port)8020 void elink_ext_phy_hw_reset(struct bnx2x_softc *sc, uint8_t port)
8021 {
8022 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
8023 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
8024 	DELAY(1000 * 1);
8025 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
8026 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
8027 }
8028 
elink_save_spirom_version(struct bnx2x_softc * sc,uint8_t port,uint32_t spirom_ver,uint32_t ver_addr)8029 static void elink_save_spirom_version(struct bnx2x_softc *sc, uint8_t port,
8030 				      uint32_t spirom_ver, uint32_t ver_addr)
8031 {
8032 	ELINK_DEBUG_P3(sc, "FW version 0x%x:0x%x for port %d",
8033 		 (uint16_t)(spirom_ver >> 16), (uint16_t)spirom_ver, port);
8034 
8035 	if (ver_addr)
8036 		REG_WR(sc, ver_addr, spirom_ver);
8037 }
8038 
elink_save_bnx2x_spirom_ver(struct bnx2x_softc * sc,struct elink_phy * phy,uint8_t port)8039 static void elink_save_bnx2x_spirom_ver(struct bnx2x_softc *sc,
8040 				      struct elink_phy *phy,
8041 				      uint8_t port)
8042 {
8043 	uint16_t fw_ver1, fw_ver2;
8044 
8045 	elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
8046 			MDIO_PMA_REG_ROM_VER1, &fw_ver1);
8047 	elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
8048 			MDIO_PMA_REG_ROM_VER2, &fw_ver2);
8049 	elink_save_spirom_version(sc, port, (uint32_t)(fw_ver1 << 16 | fw_ver2),
8050 				  phy->ver_addr);
8051 }
8052 
elink_ext_phy_10G_an_resolve(struct bnx2x_softc * sc,struct elink_phy * phy,struct elink_vars * vars)8053 static void elink_ext_phy_10G_an_resolve(struct bnx2x_softc *sc,
8054 				       struct elink_phy *phy,
8055 				       struct elink_vars *vars)
8056 {
8057 	uint16_t val;
8058 	elink_cl45_read(sc, phy,
8059 			MDIO_AN_DEVAD,
8060 			MDIO_AN_REG_STATUS, &val);
8061 	elink_cl45_read(sc, phy,
8062 			MDIO_AN_DEVAD,
8063 			MDIO_AN_REG_STATUS, &val);
8064 	if (val & (1 << 5))
8065 		vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
8066 	if ((val & (1 << 0)) == 0)
8067 		vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
8068 }
8069 
8070 /******************************************************************/
8071 /*		common BNX2X8073/BNX2X8727 PHY SECTION		  */
8072 /******************************************************************/
elink_8073_resolve_fc(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)8073 static void elink_8073_resolve_fc(struct elink_phy *phy,
8074 				  struct elink_params *params,
8075 				  struct elink_vars *vars)
8076 {
8077 	struct bnx2x_softc *sc = params->sc;
8078 	if (phy->req_line_speed == ELINK_SPEED_10 ||
8079 	    phy->req_line_speed == ELINK_SPEED_100) {
8080 		vars->flow_ctrl = phy->req_flow_ctrl;
8081 		return;
8082 	}
8083 
8084 	if (elink_ext_phy_resolve_fc(phy, params, vars) &&
8085 	    (vars->flow_ctrl == ELINK_FLOW_CTRL_NONE)) {
8086 		uint16_t pause_result;
8087 		uint16_t ld_pause;		/* local */
8088 		uint16_t lp_pause;		/* link partner */
8089 		elink_cl45_read(sc, phy,
8090 				MDIO_AN_DEVAD,
8091 				MDIO_AN_REG_CL37_FC_LD, &ld_pause);
8092 
8093 		elink_cl45_read(sc, phy,
8094 				MDIO_AN_DEVAD,
8095 				MDIO_AN_REG_CL37_FC_LP, &lp_pause);
8096 		pause_result = (ld_pause &
8097 				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
8098 		pause_result |= (lp_pause &
8099 				 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
8100 
8101 		elink_pause_resolve(phy, params, vars, pause_result);
8102 		ELINK_DEBUG_P1(sc, "Ext PHY CL37 pause result 0x%x",
8103 			   pause_result);
8104 	}
8105 }
elink_8073_8727_external_rom_boot(struct bnx2x_softc * sc,struct elink_phy * phy,uint8_t port)8106 static elink_status_t elink_8073_8727_external_rom_boot(struct bnx2x_softc *sc,
8107 					     struct elink_phy *phy,
8108 					     uint8_t port)
8109 {
8110 	uint32_t count = 0;
8111 	uint16_t fw_ver1 = 0, fw_msgout;
8112 	elink_status_t rc = ELINK_STATUS_OK;
8113 
8114 	/* Boot port from external ROM  */
8115 	/* EDC grst */
8116 	elink_cl45_write(sc, phy,
8117 			 MDIO_PMA_DEVAD,
8118 			 MDIO_PMA_REG_GEN_CTRL,
8119 			 0x0001);
8120 
8121 	/* Ucode reboot and rst */
8122 	elink_cl45_write(sc, phy,
8123 			 MDIO_PMA_DEVAD,
8124 			 MDIO_PMA_REG_GEN_CTRL,
8125 			 0x008c);
8126 
8127 	elink_cl45_write(sc, phy,
8128 			 MDIO_PMA_DEVAD,
8129 			 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
8130 
8131 	/* Reset internal microprocessor */
8132 	elink_cl45_write(sc, phy,
8133 			 MDIO_PMA_DEVAD,
8134 			 MDIO_PMA_REG_GEN_CTRL,
8135 			 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
8136 
8137 	/* Release srst bit */
8138 	elink_cl45_write(sc, phy,
8139 			 MDIO_PMA_DEVAD,
8140 			 MDIO_PMA_REG_GEN_CTRL,
8141 			 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
8142 
8143 	/* Delay 100ms per the PHY specifications */
8144 	DELAY(1000 * 100);
8145 
8146 	/* 8073 sometimes taking longer to download */
8147 	do {
8148 		count++;
8149 		if (count > 300) {
8150 			ELINK_DEBUG_P2(sc,
8151 				 "elink_8073_8727_external_rom_boot port %x:"
8152 				 "Download failed. fw version = 0x%x",
8153 				 port, fw_ver1);
8154 			rc = ELINK_STATUS_ERROR;
8155 			break;
8156 		}
8157 
8158 		elink_cl45_read(sc, phy,
8159 				MDIO_PMA_DEVAD,
8160 				MDIO_PMA_REG_ROM_VER1, &fw_ver1);
8161 		elink_cl45_read(sc, phy,
8162 				MDIO_PMA_DEVAD,
8163 				MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
8164 
8165 		DELAY(1000 * 1);
8166 	} while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
8167 			((fw_msgout & 0xff) != 0x03 && (phy->type ==
8168 			PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8073)));
8169 
8170 	/* Clear ser_boot_ctl bit */
8171 	elink_cl45_write(sc, phy,
8172 			 MDIO_PMA_DEVAD,
8173 			 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
8174 	elink_save_bnx2x_spirom_ver(sc, phy, port);
8175 
8176 	ELINK_DEBUG_P2(sc,
8177 		 "elink_8073_8727_external_rom_boot port %x:"
8178 		 "Download complete. fw version = 0x%x",
8179 		 port, fw_ver1);
8180 
8181 	return rc;
8182 }
8183 
8184 /******************************************************************/
8185 /*			BNX2X8073 PHY SECTION			  */
8186 /******************************************************************/
elink_8073_is_snr_needed(struct bnx2x_softc * sc,struct elink_phy * phy)8187 static elink_status_t elink_8073_is_snr_needed(struct bnx2x_softc *sc,
8188 					       struct elink_phy *phy)
8189 {
8190 	/* This is only required for 8073A1, version 102 only */
8191 	uint16_t val;
8192 
8193 	/* Read 8073 HW revision*/
8194 	elink_cl45_read(sc, phy,
8195 			MDIO_PMA_DEVAD,
8196 			MDIO_PMA_REG_8073_CHIP_REV, &val);
8197 
8198 	if (val != 1) {
8199 		/* No need to workaround in 8073 A1 */
8200 		return ELINK_STATUS_OK;
8201 	}
8202 
8203 	elink_cl45_read(sc, phy,
8204 			MDIO_PMA_DEVAD,
8205 			MDIO_PMA_REG_ROM_VER2, &val);
8206 
8207 	/* SNR should be applied only for version 0x102 */
8208 	if (val != 0x102)
8209 		return ELINK_STATUS_OK;
8210 
8211 	return 1;
8212 }
8213 
elink_8073_xaui_wa(struct bnx2x_softc * sc,struct elink_phy * phy)8214 static elink_status_t elink_8073_xaui_wa(struct bnx2x_softc *sc,
8215 					 struct elink_phy *phy)
8216 {
8217 	uint16_t val, cnt, cnt1;
8218 
8219 	elink_cl45_read(sc, phy,
8220 			MDIO_PMA_DEVAD,
8221 			MDIO_PMA_REG_8073_CHIP_REV, &val);
8222 
8223 	if (val > 0) {
8224 		/* No need to workaround in 8073 A1 */
8225 		return ELINK_STATUS_OK;
8226 	}
8227 	/* XAUI workaround in 8073 A0: */
8228 
8229 	/* After loading the boot ROM and restarting Autoneg, poll
8230 	 * Dev1, Reg $C820:
8231 	 */
8232 
8233 	for (cnt = 0; cnt < 1000; cnt++) {
8234 		elink_cl45_read(sc, phy,
8235 				MDIO_PMA_DEVAD,
8236 				MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
8237 				&val);
8238 		  /* If bit [14] = 0 or bit [13] = 0, continue on with
8239 		   * system initialization (XAUI work-around not required, as
8240 		   * these bits indicate 2.5G or 1G link up).
8241 		   */
8242 		if (!(val & (1 << 14)) || !(val & (1 << 13))) {
8243 			ELINK_DEBUG_P0(sc, "XAUI work-around not required");
8244 			return ELINK_STATUS_OK;
8245 		} else if (!(val & (1 << 15))) {
8246 			ELINK_DEBUG_P0(sc, "bit 15 went off");
8247 			/* If bit 15 is 0, then poll Dev1, Reg $C841 until it's
8248 			 * MSB (bit15) goes to 1 (indicating that the XAUI
8249 			 * workaround has completed), then continue on with
8250 			 * system initialization.
8251 			 */
8252 			for (cnt1 = 0; cnt1 < 1000; cnt1++) {
8253 				elink_cl45_read(sc, phy,
8254 					MDIO_PMA_DEVAD,
8255 					MDIO_PMA_REG_8073_XAUI_WA, &val);
8256 				if (val & (1 << 15)) {
8257 					ELINK_DEBUG_P0(sc,
8258 					  "XAUI workaround has completed");
8259 					return ELINK_STATUS_OK;
8260 				}
8261 				DELAY(1000 * 3);
8262 			}
8263 			break;
8264 		}
8265 		DELAY(1000 * 3);
8266 	}
8267 	ELINK_DEBUG_P0(sc, "Warning: XAUI work-around timeout !!!");
8268 	return ELINK_STATUS_ERROR;
8269 }
8270 
elink_807x_force_10G(struct bnx2x_softc * sc,struct elink_phy * phy)8271 static void elink_807x_force_10G(struct bnx2x_softc *sc, struct elink_phy *phy)
8272 {
8273 	/* Force KR or KX */
8274 	elink_cl45_write(sc, phy,
8275 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
8276 	elink_cl45_write(sc, phy,
8277 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
8278 	elink_cl45_write(sc, phy,
8279 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
8280 	elink_cl45_write(sc, phy,
8281 			 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
8282 }
8283 
elink_8073_set_pause_cl37(struct elink_params * params,struct elink_phy * phy,struct elink_vars * vars)8284 static void elink_8073_set_pause_cl37(struct elink_params *params,
8285 				      struct elink_phy *phy,
8286 				      struct elink_vars *vars)
8287 {
8288 	uint16_t cl37_val;
8289 	struct bnx2x_softc *sc = params->sc;
8290 	elink_cl45_read(sc, phy,
8291 			MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
8292 
8293 	cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
8294 	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
8295 	elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
8296 	if ((vars->ieee_fc &
8297 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
8298 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
8299 		cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
8300 	}
8301 	if ((vars->ieee_fc &
8302 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
8303 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
8304 		cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
8305 	}
8306 	if ((vars->ieee_fc &
8307 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
8308 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
8309 		cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
8310 	}
8311 	ELINK_DEBUG_P1(sc,
8312 		 "Ext phy AN advertize cl37 0x%x", cl37_val);
8313 
8314 	elink_cl45_write(sc, phy,
8315 			 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
8316 	DELAY(1000 * 500);
8317 }
8318 
elink_8073_specific_func(struct elink_phy * phy,struct elink_params * params,uint32_t action)8319 static void elink_8073_specific_func(struct elink_phy *phy,
8320 				     struct elink_params *params,
8321 				     uint32_t action)
8322 {
8323 	struct bnx2x_softc *sc = params->sc;
8324 	switch (action) {
8325 	case ELINK_PHY_INIT:
8326 		/* Enable LASI */
8327 		elink_cl45_write(sc, phy,
8328 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8329 				 (1 << 2));
8330 		elink_cl45_write(sc, phy,
8331 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,  0x0004);
8332 		break;
8333 	}
8334 }
8335 
elink_8073_config_init(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)8336 static uint8_t elink_8073_config_init(struct elink_phy *phy,
8337 				  struct elink_params *params,
8338 				  struct elink_vars *vars)
8339 {
8340 	struct bnx2x_softc *sc = params->sc;
8341 	uint16_t val = 0, tmp1;
8342 	uint8_t gpio_port;
8343 	ELINK_DEBUG_P0(sc, "Init 8073");
8344 
8345 	if (CHIP_IS_E2(sc))
8346 		gpio_port = SC_PATH(sc);
8347 	else
8348 		gpio_port = params->port;
8349 	/* Restore normal power mode*/
8350 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8351 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
8352 
8353 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
8354 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
8355 
8356 	elink_8073_specific_func(phy, params, ELINK_PHY_INIT);
8357 	elink_8073_set_pause_cl37(params, phy, vars);
8358 
8359 	elink_cl45_read(sc, phy,
8360 			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
8361 
8362 	elink_cl45_read(sc, phy,
8363 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
8364 
8365 	ELINK_DEBUG_P1(sc, "Before rom RX_ALARM(port1): 0x%x", tmp1);
8366 
8367 	/* Swap polarity if required - Must be done only in non-1G mode */
8368 	if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
8369 		/* Configure the 8073 to swap _P and _N of the KR lines */
8370 		ELINK_DEBUG_P0(sc, "Swapping polarity for the 8073");
8371 		/* 10G Rx/Tx and 1G Tx signal polarity swap */
8372 		elink_cl45_read(sc, phy,
8373 				MDIO_PMA_DEVAD,
8374 				MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
8375 		elink_cl45_write(sc, phy,
8376 				 MDIO_PMA_DEVAD,
8377 				 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
8378 				 (val | (3 << 9)));
8379 	}
8380 
8381 
8382 	/* Enable CL37 BAM */
8383 	if (REG_RD(sc, params->shmem_base +
8384 			 offsetof(struct shmem_region, dev_info.
8385 				  port_hw_config[params->port].default_cfg)) &
8386 	    PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
8387 
8388 		elink_cl45_read(sc, phy,
8389 				MDIO_AN_DEVAD,
8390 				MDIO_AN_REG_8073_BAM, &val);
8391 		elink_cl45_write(sc, phy,
8392 				 MDIO_AN_DEVAD,
8393 				 MDIO_AN_REG_8073_BAM, val | 1);
8394 		ELINK_DEBUG_P0(sc, "Enable CL37 BAM on KR");
8395 	}
8396 	if (params->loopback_mode == ELINK_LOOPBACK_EXT) {
8397 		elink_807x_force_10G(sc, phy);
8398 		ELINK_DEBUG_P0(sc, "Forced speed 10G on 807X");
8399 		return ELINK_STATUS_OK;
8400 	} else {
8401 		elink_cl45_write(sc, phy,
8402 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
8403 	}
8404 	if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG) {
8405 		if (phy->req_line_speed == ELINK_SPEED_10000) {
8406 			val = (1 << 7);
8407 		} else if (phy->req_line_speed ==  ELINK_SPEED_2500) {
8408 			val = (1 << 5);
8409 			/* Note that 2.5G works only when used with 1G
8410 			 * advertisement
8411 			 */
8412 		} else
8413 			val = (1 << 5);
8414 	} else {
8415 		val = 0;
8416 		if (phy->speed_cap_mask &
8417 			PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
8418 			val |= (1 << 7);
8419 
8420 		/* Note that 2.5G works only when used with 1G advertisement */
8421 		if (phy->speed_cap_mask &
8422 			(PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
8423 			 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
8424 			val |= (1 << 5);
8425 		ELINK_DEBUG_P1(sc, "807x autoneg val = 0x%x", val);
8426 	}
8427 
8428 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
8429 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
8430 
8431 	if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
8432 	     (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)) ||
8433 	    (phy->req_line_speed == ELINK_SPEED_2500)) {
8434 		uint16_t phy_ver;
8435 		/* Allow 2.5G for A1 and above */
8436 		elink_cl45_read(sc, phy,
8437 				MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
8438 				&phy_ver);
8439 		ELINK_DEBUG_P0(sc, "Add 2.5G");
8440 		if (phy_ver > 0)
8441 			tmp1 |= 1;
8442 		else
8443 			tmp1 &= 0xfffe;
8444 	} else {
8445 		ELINK_DEBUG_P0(sc, "Disable 2.5G");
8446 		tmp1 &= 0xfffe;
8447 	}
8448 
8449 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
8450 	/* Add support for CL37 (passive mode) II */
8451 
8452 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
8453 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
8454 			 (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
8455 				  0x20 : 0x40)));
8456 
8457 	/* Add support for CL37 (passive mode) III */
8458 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8459 
8460 	/* The SNR will improve about 2db by changing BW and FEE main
8461 	 * tap. Rest commands are executed after link is up
8462 	 * Change FFE main cursor to 5 in EDC register
8463 	 */
8464 	if (elink_8073_is_snr_needed(sc, phy))
8465 		elink_cl45_write(sc, phy,
8466 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
8467 				 0xFB0C);
8468 
8469 	/* Enable FEC (Forware Error Correction) Request in the AN */
8470 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
8471 	tmp1 |= (1 << 15);
8472 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
8473 
8474 	elink_ext_phy_set_pause(params, phy, vars);
8475 
8476 	/* Restart autoneg */
8477 	DELAY(1000 * 500);
8478 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8479 	ELINK_DEBUG_P2(sc, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x",
8480 		   ((val & (1 << 5)) > 0), ((val & (1 << 7)) > 0));
8481 	return ELINK_STATUS_OK;
8482 }
8483 
elink_8073_read_status(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)8484 static uint8_t elink_8073_read_status(struct elink_phy *phy,
8485 				 struct elink_params *params,
8486 				 struct elink_vars *vars)
8487 {
8488 	struct bnx2x_softc *sc = params->sc;
8489 	uint8_t link_up = 0;
8490 	uint16_t val1, val2;
8491 	uint16_t link_status = 0;
8492 	uint16_t an1000_status = 0;
8493 
8494 	elink_cl45_read(sc, phy,
8495 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
8496 
8497 	ELINK_DEBUG_P1(sc, "8703 LASI status 0x%x", val1);
8498 
8499 	/* Clear the interrupt LASI status register */
8500 	elink_cl45_read(sc, phy,
8501 			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
8502 	elink_cl45_read(sc, phy,
8503 			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
8504 	ELINK_DEBUG_P2(sc, "807x PCS status 0x%x->0x%x", val2, val1);
8505 	/* Clear MSG-OUT */
8506 	elink_cl45_read(sc, phy,
8507 			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
8508 
8509 	/* Check the LASI */
8510 	elink_cl45_read(sc, phy,
8511 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
8512 
8513 	ELINK_DEBUG_P1(sc, "KR 0x9003 0x%x", val2);
8514 
8515 	/* Check the link status */
8516 	elink_cl45_read(sc, phy,
8517 			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
8518 	ELINK_DEBUG_P1(sc, "KR PCS status 0x%x", val2);
8519 
8520 	elink_cl45_read(sc, phy,
8521 			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
8522 	elink_cl45_read(sc, phy,
8523 			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
8524 	link_up = ((val1 & 4) == 4);
8525 	ELINK_DEBUG_P1(sc, "PMA_REG_STATUS=0x%x", val1);
8526 
8527 	if (link_up &&
8528 	     ((phy->req_line_speed != ELINK_SPEED_10000))) {
8529 		if (elink_8073_xaui_wa(sc, phy) != 0)
8530 			return 0;
8531 	}
8532 	elink_cl45_read(sc, phy,
8533 			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
8534 	elink_cl45_read(sc, phy,
8535 			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
8536 
8537 	/* Check the link status on 1.1.2 */
8538 	elink_cl45_read(sc, phy,
8539 			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
8540 	elink_cl45_read(sc, phy,
8541 			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
8542 	ELINK_DEBUG_P3(sc, "KR PMA status 0x%x->0x%x,"
8543 		   "an_link_status=0x%x", val2, val1, an1000_status);
8544 
8545 	link_up = (((val1 & 4) == 4) || (an1000_status & (1 << 1)));
8546 	if (link_up && elink_8073_is_snr_needed(sc, phy)) {
8547 		/* The SNR will improve about 2dbby changing the BW and FEE main
8548 		 * tap. The 1st write to change FFE main tap is set before
8549 		 * restart AN. Change PLL Bandwidth in EDC register
8550 		 */
8551 		elink_cl45_write(sc, phy,
8552 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
8553 				 0x26BC);
8554 
8555 		/* Change CDR Bandwidth in EDC register */
8556 		elink_cl45_write(sc, phy,
8557 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
8558 				 0x0333);
8559 	}
8560 	elink_cl45_read(sc, phy,
8561 			MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
8562 			&link_status);
8563 
8564 	/* Bits 0..2 --> speed detected, bits 13..15--> link is down */
8565 	if ((link_status & (1 << 2)) && (!(link_status & (1 << 15)))) {
8566 		link_up = 1;
8567 		vars->line_speed = ELINK_SPEED_10000;
8568 		ELINK_DEBUG_P1(sc, "port %x: External link up in 10G",
8569 			   params->port);
8570 	} else if ((link_status & (1 << 1)) && (!(link_status & (1 << 14)))) {
8571 		link_up = 1;
8572 		vars->line_speed = ELINK_SPEED_2500;
8573 		ELINK_DEBUG_P1(sc, "port %x: External link up in 2.5G",
8574 			   params->port);
8575 	} else if ((link_status & (1 << 0)) && (!(link_status & (1 << 13)))) {
8576 		link_up = 1;
8577 		vars->line_speed = ELINK_SPEED_1000;
8578 		ELINK_DEBUG_P1(sc, "port %x: External link up in 1G",
8579 			   params->port);
8580 	} else {
8581 		link_up = 0;
8582 		ELINK_DEBUG_P1(sc, "port %x: External link is down",
8583 			   params->port);
8584 	}
8585 
8586 	if (link_up) {
8587 		/* Swap polarity if required */
8588 		if (params->lane_config &
8589 		    PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
8590 			/* Configure the 8073 to swap P and N of the KR lines */
8591 			elink_cl45_read(sc, phy,
8592 					MDIO_XS_DEVAD,
8593 					MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
8594 			/* Set bit 3 to invert Rx in 1G mode and clear this bit
8595 			 * when it`s in 10G mode.
8596 			 */
8597 			if (vars->line_speed == ELINK_SPEED_1000) {
8598 				ELINK_DEBUG_P0(sc, "Swapping 1G polarity for"
8599 					       " the 8073");
8600 				val1 |= (1 << 3);
8601 			} else
8602 				val1 &= ~(1 << 3);
8603 
8604 			elink_cl45_write(sc, phy,
8605 					 MDIO_XS_DEVAD,
8606 					 MDIO_XS_REG_8073_RX_CTRL_PCIE,
8607 					 val1);
8608 		}
8609 		elink_ext_phy_10G_an_resolve(sc, phy, vars);
8610 		elink_8073_resolve_fc(phy, params, vars);
8611 		vars->duplex = DUPLEX_FULL;
8612 	}
8613 
8614 	if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
8615 		elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
8616 				MDIO_AN_REG_LP_AUTO_NEG2, &val1);
8617 
8618 		if (val1 & (1 << 5))
8619 			vars->link_status |=
8620 				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
8621 		if (val1 & (1 << 7))
8622 			vars->link_status |=
8623 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
8624 	}
8625 
8626 	return link_up;
8627 }
8628 
elink_8073_link_reset(__rte_unused struct elink_phy * phy,struct elink_params * params)8629 static void elink_8073_link_reset(__rte_unused struct elink_phy *phy,
8630 				  struct elink_params *params)
8631 {
8632 	struct bnx2x_softc *sc = params->sc;
8633 	uint8_t gpio_port;
8634 	if (CHIP_IS_E2(sc))
8635 		gpio_port = SC_PATH(sc);
8636 	else
8637 		gpio_port = params->port;
8638 	ELINK_DEBUG_P1(sc, "Setting 8073 port %d into low power mode",
8639 	   gpio_port);
8640 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8641 		       MISC_REGISTERS_GPIO_OUTPUT_LOW,
8642 		       gpio_port);
8643 }
8644 
8645 /******************************************************************/
8646 /*			BNX2X8705 PHY SECTION			  */
8647 /******************************************************************/
elink_8705_config_init(struct elink_phy * phy,struct elink_params * params,__rte_unused struct elink_vars * vars)8648 static uint8_t elink_8705_config_init(struct elink_phy *phy,
8649 				  struct elink_params *params,
8650 				  __rte_unused struct elink_vars *vars)
8651 {
8652 	struct bnx2x_softc *sc = params->sc;
8653 	ELINK_DEBUG_P0(sc, "init 8705");
8654 	/* Restore normal power mode*/
8655 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8656 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8657 	/* HW reset */
8658 	elink_ext_phy_hw_reset(sc, params->port);
8659 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
8660 	elink_wait_reset_complete(sc, phy, params);
8661 
8662 	elink_cl45_write(sc, phy,
8663 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
8664 	elink_cl45_write(sc, phy,
8665 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
8666 	elink_cl45_write(sc, phy,
8667 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
8668 	elink_cl45_write(sc, phy,
8669 			 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
8670 	/* BNX2X8705 doesn't have microcode, hence the 0 */
8671 	elink_save_spirom_version(sc, params->port, params->shmem_base, 0);
8672 	return ELINK_STATUS_OK;
8673 }
8674 
elink_8705_read_status(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)8675 static uint8_t elink_8705_read_status(struct elink_phy *phy,
8676 				 struct elink_params *params,
8677 				 struct elink_vars *vars)
8678 {
8679 	uint8_t link_up = 0;
8680 	uint16_t val1, rx_sd;
8681 	struct bnx2x_softc *sc = params->sc;
8682 	ELINK_DEBUG_P0(sc, "read status 8705");
8683 	elink_cl45_read(sc, phy,
8684 		      MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
8685 	ELINK_DEBUG_P1(sc, "8705 LASI status 0x%x", val1);
8686 
8687 	elink_cl45_read(sc, phy,
8688 		      MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
8689 	ELINK_DEBUG_P1(sc, "8705 LASI status 0x%x", val1);
8690 
8691 	elink_cl45_read(sc, phy,
8692 		      MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
8693 
8694 	elink_cl45_read(sc, phy,
8695 		      MDIO_PMA_DEVAD, 0xc809, &val1);
8696 	elink_cl45_read(sc, phy,
8697 		      MDIO_PMA_DEVAD, 0xc809, &val1);
8698 
8699 	ELINK_DEBUG_P1(sc, "8705 1.c809 val=0x%x", val1);
8700 	link_up = ((rx_sd & 0x1) && (val1 & (1 << 9)) &&
8701 		   ((val1 & (1 << 8)) == 0));
8702 	if (link_up) {
8703 		vars->line_speed = ELINK_SPEED_10000;
8704 		elink_ext_phy_resolve_fc(phy, params, vars);
8705 	}
8706 	return link_up;
8707 }
8708 
8709 /******************************************************************/
8710 /*			SFP+ module Section			  */
8711 /******************************************************************/
elink_set_disable_pmd_transmit(struct elink_params * params,struct elink_phy * phy,uint8_t pmd_dis)8712 static void elink_set_disable_pmd_transmit(struct elink_params *params,
8713 					   struct elink_phy *phy,
8714 					   uint8_t pmd_dis)
8715 {
8716 	struct bnx2x_softc *sc = params->sc;
8717 	/* Disable transmitter only for bootcodes which can enable it afterwards
8718 	 * (for D3 link)
8719 	 */
8720 	if (pmd_dis) {
8721 		if (params->feature_config_flags &
8722 		     ELINK_FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED) {
8723 			ELINK_DEBUG_P0(sc, "Disabling PMD transmitter");
8724 		} else {
8725 			ELINK_DEBUG_P0(sc, "NOT disabling PMD transmitter");
8726 			return;
8727 		}
8728 	} else
8729 		ELINK_DEBUG_P0(sc, "Enabling PMD transmitter");
8730 	elink_cl45_write(sc, phy,
8731 			 MDIO_PMA_DEVAD,
8732 			 MDIO_PMA_REG_TX_DISABLE, pmd_dis);
8733 }
8734 
elink_get_gpio_port(struct elink_params * params)8735 static uint8_t elink_get_gpio_port(struct elink_params *params)
8736 {
8737 	uint8_t gpio_port;
8738 	uint32_t swap_val, swap_override;
8739 	struct bnx2x_softc *sc = params->sc;
8740 	if (CHIP_IS_E2(sc))
8741 		gpio_port = SC_PATH(sc);
8742 	else
8743 		gpio_port = params->port;
8744 	swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
8745 	swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
8746 	return gpio_port ^ (swap_val && swap_override);
8747 }
8748 
elink_sfp_e1e2_set_transmitter(struct elink_params * params,struct elink_phy * phy,uint8_t tx_en)8749 static void elink_sfp_e1e2_set_transmitter(struct elink_params *params,
8750 					   struct elink_phy *phy,
8751 					   uint8_t tx_en)
8752 {
8753 	uint16_t val;
8754 	uint8_t port = params->port;
8755 	struct bnx2x_softc *sc = params->sc;
8756 	uint32_t tx_en_mode;
8757 
8758 	/* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
8759 	tx_en_mode = REG_RD(sc, params->shmem_base +
8760 			    offsetof(struct shmem_region,
8761 				     dev_info.port_hw_config[port].sfp_ctrl)) &
8762 		PORT_HW_CFG_TX_LASER_MASK;
8763 	ELINK_DEBUG_P3(sc, "Setting transmitter tx_en=%x for port %x "
8764 			   "mode = %x", tx_en, port, tx_en_mode);
8765 	switch (tx_en_mode) {
8766 	case PORT_HW_CFG_TX_LASER_MDIO:
8767 
8768 		elink_cl45_read(sc, phy,
8769 				MDIO_PMA_DEVAD,
8770 				MDIO_PMA_REG_PHY_IDENTIFIER,
8771 				&val);
8772 
8773 		if (tx_en)
8774 			val &= ~(1 << 15);
8775 		else
8776 			val |= (1 << 15);
8777 
8778 		elink_cl45_write(sc, phy,
8779 				 MDIO_PMA_DEVAD,
8780 				 MDIO_PMA_REG_PHY_IDENTIFIER,
8781 				 val);
8782 	break;
8783 	case PORT_HW_CFG_TX_LASER_GPIO0:
8784 	case PORT_HW_CFG_TX_LASER_GPIO1:
8785 	case PORT_HW_CFG_TX_LASER_GPIO2:
8786 	case PORT_HW_CFG_TX_LASER_GPIO3:
8787 	{
8788 		uint16_t gpio_pin;
8789 		uint8_t gpio_port, gpio_mode;
8790 		if (tx_en)
8791 			gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
8792 		else
8793 			gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
8794 
8795 		gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
8796 		gpio_port = elink_get_gpio_port(params);
8797 		elink_cb_gpio_write(sc, gpio_pin, gpio_mode, gpio_port);
8798 		break;
8799 	}
8800 	default:
8801 		ELINK_DEBUG_P1(sc, "Invalid TX_LASER_MDIO 0x%x", tx_en_mode);
8802 		break;
8803 	}
8804 }
8805 
elink_sfp_set_transmitter(struct elink_params * params,struct elink_phy * phy,uint8_t tx_en)8806 static void elink_sfp_set_transmitter(struct elink_params *params,
8807 				      struct elink_phy *phy,
8808 				      uint8_t tx_en)
8809 {
8810 	struct bnx2x_softc *sc = params->sc;
8811 	ELINK_DEBUG_P1(sc, "Setting SFP+ transmitter to %d", tx_en);
8812 	if (CHIP_IS_E3(sc))
8813 		elink_sfp_e3_set_transmitter(params, phy, tx_en);
8814 	else
8815 		elink_sfp_e1e2_set_transmitter(params, phy, tx_en);
8816 }
8817 
elink_8726_read_sfp_module_eeprom(struct elink_phy * phy,struct elink_params * params,uint8_t dev_addr,uint16_t addr,uint8_t byte_cnt,uint8_t * o_buf,__rte_unused uint8_t is_init)8818 static elink_status_t elink_8726_read_sfp_module_eeprom(struct elink_phy *phy,
8819 			     struct elink_params *params,
8820 			     uint8_t dev_addr, uint16_t addr,
8821 			     uint8_t byte_cnt,
8822 			     uint8_t *o_buf, __rte_unused uint8_t is_init)
8823 {
8824 	struct bnx2x_softc *sc = params->sc;
8825 	uint16_t val = 0;
8826 	uint16_t i;
8827 	if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8828 		ELINK_DEBUG_P0(sc,
8829 		   "Reading from eeprom is limited to 0xf");
8830 		return ELINK_STATUS_ERROR;
8831 	}
8832 	/* Set the read command byte count */
8833 	elink_cl45_write(sc, phy,
8834 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
8835 			 (byte_cnt | (dev_addr << 8)));
8836 
8837 	/* Set the read command address */
8838 	elink_cl45_write(sc, phy,
8839 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
8840 			 addr);
8841 
8842 	/* Activate read command */
8843 	elink_cl45_write(sc, phy,
8844 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8845 			 0x2c0f);
8846 
8847 	/* Wait up to 500us for command complete status */
8848 	for (i = 0; i < 100; i++) {
8849 		elink_cl45_read(sc, phy,
8850 				MDIO_PMA_DEVAD,
8851 				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8852 		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8853 		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
8854 			break;
8855 		DELAY(5);
8856 	}
8857 
8858 	if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
8859 		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
8860 		ELINK_DEBUG_P1(sc,
8861 			 "Got bad status 0x%x when reading from SFP+ EEPROM",
8862 			 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
8863 		return ELINK_STATUS_ERROR;
8864 	}
8865 
8866 	/* Read the buffer */
8867 	for (i = 0; i < byte_cnt; i++) {
8868 		elink_cl45_read(sc, phy,
8869 				MDIO_PMA_DEVAD,
8870 				MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
8871 		o_buf[i] = (uint8_t)
8872 				(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
8873 	}
8874 
8875 	for (i = 0; i < 100; i++) {
8876 		elink_cl45_read(sc, phy,
8877 				MDIO_PMA_DEVAD,
8878 				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8879 		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8880 		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
8881 			return ELINK_STATUS_OK;
8882 		DELAY(1000 * 1);
8883 	}
8884 	return ELINK_STATUS_ERROR;
8885 }
8886 
elink_warpcore_power_module(struct elink_params * params,uint8_t power)8887 static void elink_warpcore_power_module(struct elink_params *params,
8888 					uint8_t power)
8889 {
8890 	uint32_t pin_cfg;
8891 	struct bnx2x_softc *sc = params->sc;
8892 
8893 	pin_cfg = (REG_RD(sc, params->shmem_base +
8894 			  offsetof(struct shmem_region,
8895 			dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
8896 			PORT_HW_CFG_E3_PWR_DIS_MASK) >>
8897 			PORT_HW_CFG_E3_PWR_DIS_SHIFT;
8898 
8899 	if (pin_cfg == PIN_CFG_NA)
8900 		return;
8901 	ELINK_DEBUG_P2(sc, "Setting SFP+ module power to %d using pin cfg %d",
8902 		       power, pin_cfg);
8903 	/* Low ==> corresponding SFP+ module is powered
8904 	 * high ==> the SFP+ module is powered down
8905 	 */
8906 	elink_set_cfg_pin(sc, pin_cfg, power ^ 1);
8907 }
elink_warpcore_read_sfp_module_eeprom(__rte_unused struct elink_phy * phy,struct elink_params * params,uint8_t dev_addr,uint16_t addr,uint8_t byte_cnt,uint8_t * o_buf,uint8_t is_init)8908 static elink_status_t elink_warpcore_read_sfp_module_eeprom(
8909 					 __rte_unused struct elink_phy *phy,
8910 					 struct elink_params *params,
8911 					 uint8_t dev_addr,
8912 					 uint16_t addr,
8913 					 uint8_t byte_cnt,
8914 					 uint8_t *o_buf,
8915 					 uint8_t is_init)
8916 {
8917 	elink_status_t rc = ELINK_STATUS_OK;
8918 	uint8_t i, j = 0, cnt = 0;
8919 	uint32_t data_array[4];
8920 	uint16_t addr32;
8921 	struct bnx2x_softc *sc = params->sc;
8922 
8923 	if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8924 		ELINK_DEBUG_P0(sc,
8925 		   "Reading from eeprom is limited to 16 bytes");
8926 		return ELINK_STATUS_ERROR;
8927 	}
8928 
8929 	/* 4 byte aligned address */
8930 	addr32 = addr & (~0x3);
8931 	do {
8932 		if ((!is_init) && (cnt == I2C_WA_PWR_ITER)) {
8933 			elink_warpcore_power_module(params, 0);
8934 			/* Note that 100us are not enough here */
8935 			DELAY(1000 * 1);
8936 			elink_warpcore_power_module(params, 1);
8937 		}
8938 
8939 		elink_bsc_module_sel(params);
8940 		rc = elink_bsc_read(sc, dev_addr, addr32, 0, byte_cnt,
8941 				    data_array);
8942 	} while ((rc != ELINK_STATUS_OK) && (++cnt < I2C_WA_RETRY_CNT));
8943 
8944 	if (rc == ELINK_STATUS_OK) {
8945 		for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
8946 			o_buf[j] = *((uint8_t *)data_array + i);
8947 			j++;
8948 		}
8949 	}
8950 
8951 	return rc;
8952 }
8953 
elink_8727_read_sfp_module_eeprom(struct elink_phy * phy,struct elink_params * params,uint8_t dev_addr,uint16_t addr,uint8_t byte_cnt,uint8_t * o_buf,__rte_unused uint8_t is_init)8954 static elink_status_t elink_8727_read_sfp_module_eeprom(struct elink_phy *phy,
8955 					     struct elink_params *params,
8956 					     uint8_t dev_addr, uint16_t addr,
8957 					     uint8_t byte_cnt,
8958 					     uint8_t *o_buf,
8959 					     __rte_unused uint8_t is_init)
8960 {
8961 	struct bnx2x_softc *sc = params->sc;
8962 	uint16_t val, i;
8963 
8964 	if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8965 		ELINK_DEBUG_P0(sc,
8966 		   "Reading from eeprom is limited to 0xf");
8967 		return ELINK_STATUS_ERROR;
8968 	}
8969 
8970 	/* Set 2-wire transfer rate of SFP+ module EEPROM
8971 	 * to 100Khz since some DACs(direct attached cables) do
8972 	 * not work at 400Khz.
8973 	 */
8974 	elink_cl45_write(sc, phy,
8975 			 MDIO_PMA_DEVAD,
8976 			 MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
8977 			 ((dev_addr << 8) | 1));
8978 
8979 	/* Need to read from 1.8000 to clear it */
8980 	elink_cl45_read(sc, phy,
8981 			MDIO_PMA_DEVAD,
8982 			MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8983 			&val);
8984 
8985 	/* Set the read command byte count */
8986 	elink_cl45_write(sc, phy,
8987 			 MDIO_PMA_DEVAD,
8988 			 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
8989 			 ((byte_cnt < 2) ? 2 : byte_cnt));
8990 
8991 	/* Set the read command address */
8992 	elink_cl45_write(sc, phy,
8993 			 MDIO_PMA_DEVAD,
8994 			 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
8995 			 addr);
8996 	/* Set the destination address */
8997 	elink_cl45_write(sc, phy,
8998 			 MDIO_PMA_DEVAD,
8999 			 0x8004,
9000 			 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
9001 
9002 	/* Activate read command */
9003 	elink_cl45_write(sc, phy,
9004 			 MDIO_PMA_DEVAD,
9005 			 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
9006 			 0x8002);
9007 	/* Wait appropriate time for two-wire command to finish before
9008 	 * polling the status register
9009 	 */
9010 	DELAY(1000 * 1);
9011 
9012 	/* Wait up to 500us for command complete status */
9013 	for (i = 0; i < 100; i++) {
9014 		elink_cl45_read(sc, phy,
9015 				MDIO_PMA_DEVAD,
9016 				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
9017 		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
9018 		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
9019 			break;
9020 		DELAY(5);
9021 	}
9022 
9023 	if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
9024 		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
9025 		ELINK_DEBUG_P1(sc,
9026 			 "Got bad status 0x%x when reading from SFP+ EEPROM",
9027 			 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
9028 		return ELINK_STATUS_TIMEOUT;
9029 	}
9030 
9031 	/* Read the buffer */
9032 	for (i = 0; i < byte_cnt; i++) {
9033 		elink_cl45_read(sc, phy,
9034 				MDIO_PMA_DEVAD,
9035 				MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
9036 		o_buf[i] = (uint8_t)
9037 				(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
9038 	}
9039 
9040 	for (i = 0; i < 100; i++) {
9041 		elink_cl45_read(sc, phy,
9042 				MDIO_PMA_DEVAD,
9043 				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
9044 		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
9045 		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
9046 			return ELINK_STATUS_OK;
9047 		DELAY(1000 * 1);
9048 	}
9049 
9050 	return ELINK_STATUS_ERROR;
9051 }
elink_read_sfp_module_eeprom(struct elink_phy * phy,struct elink_params * params,uint8_t dev_addr,uint16_t addr,uint16_t byte_cnt,uint8_t * o_buf)9052 elink_status_t elink_read_sfp_module_eeprom(struct elink_phy *phy,
9053 				 struct elink_params *params, uint8_t dev_addr,
9054 				 uint16_t addr, uint16_t byte_cnt,
9055 				 uint8_t *o_buf)
9056 {
9057 	elink_status_t rc = 0;
9058 	struct bnx2x_softc *sc = params->sc;
9059 	uint8_t xfer_size;
9060 	uint8_t *user_data = o_buf;
9061 	read_sfp_module_eeprom_func_p read_func;
9062 	if ((dev_addr != 0xa0) && (dev_addr != 0xa2)) {
9063 		ELINK_DEBUG_P1(sc, "invalid dev_addr 0x%x", dev_addr);
9064 		return ELINK_STATUS_ERROR;
9065 	}
9066 
9067 	switch (phy->type) {
9068 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726:
9069 		read_func = elink_8726_read_sfp_module_eeprom;
9070 		break;
9071 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
9072 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
9073 		read_func = elink_8727_read_sfp_module_eeprom;
9074 		break;
9075 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
9076 		read_func = elink_warpcore_read_sfp_module_eeprom;
9077 		break;
9078 	default:
9079 		return ELINK_OP_NOT_SUPPORTED;
9080 	}
9081 
9082 	while (!rc && (byte_cnt > 0)) {
9083 		xfer_size = (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) ?
9084 			ELINK_SFP_EEPROM_PAGE_SIZE : byte_cnt;
9085 		rc = read_func(phy, params, dev_addr, addr, xfer_size,
9086 			       user_data, 0);
9087 		byte_cnt -= xfer_size;
9088 		user_data += xfer_size;
9089 		addr += xfer_size;
9090 	}
9091 	return rc;
9092 }
9093 
elink_get_edc_mode(struct elink_phy * phy,struct elink_params * params,uint16_t * edc_mode)9094 static elink_status_t elink_get_edc_mode(struct elink_phy *phy,
9095 			      struct elink_params *params,
9096 			      uint16_t *edc_mode)
9097 {
9098 	struct bnx2x_softc *sc = params->sc;
9099 	uint32_t sync_offset = 0, phy_idx, media_types;
9100 	uint8_t val[ELINK_SFP_EEPROM_FC_TX_TECH_ADDR + 1];
9101 	uint8_t check_limiting_mode = 0;
9102 	*edc_mode = ELINK_EDC_MODE_LIMITING;
9103 	phy->media_type = ELINK_ETH_PHY_UNSPECIFIED;
9104 	/* First check for copper cable */
9105 	if (elink_read_sfp_module_eeprom(phy,
9106 					 params,
9107 					 ELINK_I2C_DEV_ADDR_A0,
9108 					 0,
9109 					 ELINK_SFP_EEPROM_FC_TX_TECH_ADDR + 1,
9110 					 (uint8_t *)val) != 0) {
9111 		ELINK_DEBUG_P0(sc, "Failed to read from SFP+ module EEPROM");
9112 		return ELINK_STATUS_ERROR;
9113 	}
9114 	params->link_attr_sync &= ~LINK_SFP_EEPROM_COMP_CODE_MASK;
9115 	params->link_attr_sync |= val[ELINK_SFP_EEPROM_10G_COMP_CODE_ADDR] <<
9116 		LINK_SFP_EEPROM_COMP_CODE_SHIFT;
9117 	elink_update_link_attr(params, params->link_attr_sync);
9118 	switch (val[ELINK_SFP_EEPROM_CON_TYPE_ADDR]) {
9119 	case ELINK_SFP_EEPROM_CON_TYPE_VAL_COPPER:
9120 	{
9121 		uint8_t copper_module_type;
9122 		phy->media_type = ELINK_ETH_PHY_DA_TWINAX;
9123 		/* Check if its active cable (includes SFP+ module)
9124 		 * of passive cable
9125 		 */
9126 		copper_module_type = val[ELINK_SFP_EEPROM_FC_TX_TECH_ADDR];
9127 		if (copper_module_type &
9128 		    ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
9129 			ELINK_DEBUG_P0(sc, "Active Copper cable detected");
9130 			if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
9131 				*edc_mode = ELINK_EDC_MODE_ACTIVE_DAC;
9132 			else
9133 				check_limiting_mode = 1;
9134 		} else {
9135 			*edc_mode = ELINK_EDC_MODE_PASSIVE_DAC;
9136 			/* Even in case PASSIVE_DAC indication is not set,
9137 			 * treat it as a passive DAC cable, since some cables
9138 			 * don't have this indication.
9139 			 */
9140 			if (copper_module_type &
9141 			   ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
9142 				ELINK_DEBUG_P0(sc,
9143 					       "Passive Copper cable detected");
9144 			} else {
9145 				ELINK_DEBUG_P0(sc,
9146 					       "Unknown copper-cable-type");
9147 			}
9148 		}
9149 		break;
9150 	}
9151 	case ELINK_SFP_EEPROM_CON_TYPE_VAL_UNKNOWN:
9152 	case ELINK_SFP_EEPROM_CON_TYPE_VAL_SC:
9153 	case ELINK_SFP_EEPROM_CON_TYPE_VAL_LC:
9154 	case ELINK_SFP_EEPROM_CON_TYPE_VAL_RJ45:
9155 		check_limiting_mode = 1;
9156 		/* Module is considered as 1G in case it's NOT compliant with
9157 		 * any 10G ethernet protocol, but is 1G Ethernet compliant.
9158 		 */
9159 		if (((val[ELINK_SFP_EEPROM_10G_COMP_CODE_ADDR] &
9160 		      (ELINK_SFP_EEPROM_10G_COMP_CODE_SR_MASK |
9161 		       ELINK_SFP_EEPROM_10G_COMP_CODE_LR_MASK |
9162 		       ELINK_SFP_EEPROM_10G_COMP_CODE_LRM_MASK)) == 0) &&
9163 		    (val[ELINK_SFP_EEPROM_1G_COMP_CODE_ADDR] != 0)) {
9164 			ELINK_DEBUG_P0(sc, "1G SFP module detected");
9165 			phy->media_type = ELINK_ETH_PHY_SFP_1G_FIBER;
9166 			if (phy->req_line_speed != ELINK_SPEED_1000 &&
9167 			    phy->req_line_speed != ELINK_SPEED_2500) {
9168 				uint8_t gport = params->port;
9169 				phy->req_line_speed = ELINK_SPEED_1000;
9170 				if (!CHIP_IS_E1x(sc)) {
9171 					gport = SC_PATH(sc) +
9172 					(params->port << 1);
9173 				}
9174 				elink_cb_event_log(sc,
9175 						   ELINK_LOG_ID_NON_10G_MODULE,
9176 						   gport);
9177 				 /*"Warning: Link speed was forced to 1000Mbps."
9178 				  *" Current SFP module in port %d is not"
9179 				  *" compliant with 10G Ethernet",
9180 				  */
9181 			}
9182 
9183 			if (val[ELINK_SFP_EEPROM_1G_COMP_CODE_ADDR] &
9184 			    ELINK_SFP_EEPROM_1G_COMP_CODE_BASE_T) {
9185 				/* Some 1G-baseT modules will not link up,
9186 				 * unless TX_EN is toggled with long delay in
9187 				 * between.
9188 				 */
9189 				elink_sfp_set_transmitter(params, phy, 0);
9190 				DELAY(1000 * 40);
9191 				elink_sfp_set_transmitter(params, phy, 1);
9192 			}
9193 		} else {
9194 			int idx, cfg_idx = 0;
9195 			ELINK_DEBUG_P0(sc, "10G Optic module detected");
9196 			for (idx = ELINK_INT_PHY; idx < ELINK_MAX_PHYS; idx++) {
9197 				if (params->phy[idx].type == phy->type) {
9198 					cfg_idx = ELINK_LINK_CONFIG_IDX(idx);
9199 					break;
9200 				}
9201 			}
9202 			phy->media_type = ELINK_ETH_PHY_SFPP_10G_FIBER;
9203 			phy->req_line_speed = params->req_line_speed[cfg_idx];
9204 		}
9205 		break;
9206 	default:
9207 		ELINK_DEBUG_P1(sc, "Unable to determine module type 0x%x !!!",
9208 			 val[ELINK_SFP_EEPROM_CON_TYPE_ADDR]);
9209 		return ELINK_STATUS_ERROR;
9210 	}
9211 	sync_offset = params->shmem_base +
9212 		offsetof(struct shmem_region,
9213 			 dev_info.port_hw_config[params->port].media_type);
9214 	media_types = REG_RD(sc, sync_offset);
9215 	/* Update media type for non-PMF sync */
9216 	for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
9217 		if (&(params->phy[phy_idx]) == phy) {
9218 			media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
9219 				(PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
9220 			media_types |= ((phy->media_type &
9221 					PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
9222 				(PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
9223 			break;
9224 		}
9225 	}
9226 	REG_WR(sc, sync_offset, media_types);
9227 	if (check_limiting_mode) {
9228 		uint8_t options[ELINK_SFP_EEPROM_OPTIONS_SIZE];
9229 		if (elink_read_sfp_module_eeprom(phy,
9230 						 params,
9231 						 ELINK_I2C_DEV_ADDR_A0,
9232 						 ELINK_SFP_EEPROM_OPTIONS_ADDR,
9233 						 ELINK_SFP_EEPROM_OPTIONS_SIZE,
9234 						 options) != 0) {
9235 			ELINK_DEBUG_P0(sc,
9236 			   "Failed to read Option field from module EEPROM");
9237 			return ELINK_STATUS_ERROR;
9238 		}
9239 		if ((options[0] & ELINK_SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
9240 			*edc_mode = ELINK_EDC_MODE_LINEAR;
9241 		else
9242 			*edc_mode = ELINK_EDC_MODE_LIMITING;
9243 	}
9244 	ELINK_DEBUG_P1(sc, "EDC mode is set to 0x%x", *edc_mode);
9245 	return ELINK_STATUS_OK;
9246 }
9247 /* This function read the relevant field from the module (SFP+), and verify it
9248  * is compliant with this board
9249  */
elink_verify_sfp_module(struct elink_phy * phy,struct elink_params * params)9250 static elink_status_t elink_verify_sfp_module(struct elink_phy *phy,
9251 				   struct elink_params *params)
9252 {
9253 	struct bnx2x_softc *sc = params->sc;
9254 	uint32_t val, cmd;
9255 	uint32_t fw_resp, fw_cmd_param;
9256 	char vendor_name[ELINK_SFP_EEPROM_VENDOR_NAME_SIZE + 1];
9257 	char vendor_pn[ELINK_SFP_EEPROM_PART_NO_SIZE + 1];
9258 	phy->flags &= ~ELINK_FLAGS_SFP_NOT_APPROVED;
9259 	val = REG_RD(sc, params->shmem_base +
9260 			 offsetof(struct shmem_region, dev_info.
9261 				  port_feature_config[params->port].config));
9262 	if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9263 	    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
9264 		ELINK_DEBUG_P0(sc, "NOT enforcing module verification");
9265 		return ELINK_STATUS_OK;
9266 	}
9267 
9268 	if (params->feature_config_flags &
9269 	    ELINK_FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
9270 		/* Use specific phy request */
9271 		cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
9272 	} else if (params->feature_config_flags &
9273 		   ELINK_FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
9274 		/* Use first phy request only in case of non-dual media*/
9275 		if (ELINK_DUAL_MEDIA(params)) {
9276 			ELINK_DEBUG_P0(sc,
9277 			   "FW does not support OPT MDL verification");
9278 			return ELINK_STATUS_ERROR;
9279 		}
9280 		cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
9281 	} else {
9282 		/* No support in OPT MDL detection */
9283 		ELINK_DEBUG_P0(sc,
9284 		   "FW does not support OPT MDL verification");
9285 		return ELINK_STATUS_ERROR;
9286 	}
9287 
9288 	fw_cmd_param = ELINK_FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
9289 	fw_resp = elink_cb_fw_command(sc, cmd, fw_cmd_param);
9290 	if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
9291 		ELINK_DEBUG_P0(sc, "Approved module");
9292 		return ELINK_STATUS_OK;
9293 	}
9294 
9295 	/* Format the warning message */
9296 	if (elink_read_sfp_module_eeprom(phy,
9297 					 params,
9298 					 ELINK_I2C_DEV_ADDR_A0,
9299 					 ELINK_SFP_EEPROM_VENDOR_NAME_ADDR,
9300 					 ELINK_SFP_EEPROM_VENDOR_NAME_SIZE,
9301 					 (uint8_t *)vendor_name))
9302 		vendor_name[0] = '\0';
9303 	else
9304 		vendor_name[ELINK_SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
9305 	if (elink_read_sfp_module_eeprom(phy,
9306 					 params,
9307 					 ELINK_I2C_DEV_ADDR_A0,
9308 					 ELINK_SFP_EEPROM_PART_NO_ADDR,
9309 					 ELINK_SFP_EEPROM_PART_NO_SIZE,
9310 					 (uint8_t *)vendor_pn))
9311 		vendor_pn[0] = '\0';
9312 	else
9313 		vendor_pn[ELINK_SFP_EEPROM_PART_NO_SIZE] = '\0';
9314 
9315 	elink_cb_event_log(sc, ELINK_LOG_ID_UNQUAL_IO_MODULE, params->port,
9316 			   vendor_name, vendor_pn);
9317 			     /* "Warning: Unqualified SFP+ module detected,"
9318 			      * " Port %d from %s part number %s",
9319 			      */
9320 
9321 	if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
9322 	    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_WARNING_MSG)
9323 		phy->flags |= ELINK_FLAGS_SFP_NOT_APPROVED;
9324 	return ELINK_STATUS_ERROR;
9325 }
9326 
elink_wait_for_sfp_module_initialized(struct elink_phy * phy,struct elink_params * params)9327 static elink_status_t elink_wait_for_sfp_module_initialized(
9328 						 struct elink_phy *phy,
9329 						 struct elink_params *params)
9330 
9331 {
9332 	uint8_t val;
9333 	elink_status_t rc;
9334 	struct bnx2x_softc *sc = params->sc;
9335 	uint16_t timeout;
9336 	/* Initialization time after hot-plug may take up to 300ms for
9337 	 * some phys type ( e.g. JDSU )
9338 	 */
9339 
9340 	for (timeout = 0; timeout < 1800; timeout++) {
9341 		if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
9342 			rc = elink_warpcore_read_sfp_module_eeprom(
9343 				phy, params, ELINK_I2C_DEV_ADDR_A0, 1, 1, &val,
9344 				1);
9345 		else
9346 			rc = elink_read_sfp_module_eeprom(phy, params,
9347 							  ELINK_I2C_DEV_ADDR_A0,
9348 							  1, 1, &val);
9349 		if (rc == 0) {
9350 			ELINK_DEBUG_P1(sc,
9351 			   "SFP+ module initialization took %d ms",
9352 			   timeout * 5);
9353 			return ELINK_STATUS_OK;
9354 		}
9355 		DELAY(1000 * 5);
9356 	}
9357 	rc = elink_read_sfp_module_eeprom(phy, params, ELINK_I2C_DEV_ADDR_A0,
9358 					  1, 1, &val);
9359 	return rc;
9360 }
9361 
elink_8727_power_module(struct bnx2x_softc * sc,struct elink_phy * phy,uint8_t is_power_up)9362 static void elink_8727_power_module(struct bnx2x_softc *sc,
9363 				    struct elink_phy *phy,
9364 				    uint8_t is_power_up) {
9365 	/* Make sure GPIOs are not using for LED mode */
9366 	uint16_t val;
9367 	/* In the GPIO register, bit 4 is use to determine if the GPIOs are
9368 	 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
9369 	 * output
9370 	 * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
9371 	 * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
9372 	 * where the 1st bit is the over-current(only input), and 2nd bit is
9373 	 * for power( only output )
9374 	 *
9375 	 * In case of NOC feature is disabled and power is up, set GPIO control
9376 	 *  as input to enable listening of over-current indication
9377 	 */
9378 	if (phy->flags & ELINK_FLAGS_NOC)
9379 		return;
9380 	if (is_power_up)
9381 		val = (1 << 4);
9382 	else
9383 		/* Set GPIO control to OUTPUT, and set the power bit
9384 		 * to according to the is_power_up
9385 		 */
9386 		val = (1 << 1);
9387 
9388 	elink_cl45_write(sc, phy,
9389 			 MDIO_PMA_DEVAD,
9390 			 MDIO_PMA_REG_8727_GPIO_CTRL,
9391 			 val);
9392 }
9393 
elink_8726_set_limiting_mode(struct bnx2x_softc * sc,struct elink_phy * phy,uint16_t edc_mode)9394 static elink_status_t elink_8726_set_limiting_mode(struct bnx2x_softc *sc,
9395 					struct elink_phy *phy,
9396 					uint16_t edc_mode)
9397 {
9398 	uint16_t cur_limiting_mode;
9399 
9400 	elink_cl45_read(sc, phy,
9401 			MDIO_PMA_DEVAD,
9402 			MDIO_PMA_REG_ROM_VER2,
9403 			&cur_limiting_mode);
9404 	ELINK_DEBUG_P1(sc, "Current Limiting mode is 0x%x",
9405 		 cur_limiting_mode);
9406 
9407 	if (edc_mode == ELINK_EDC_MODE_LIMITING) {
9408 		ELINK_DEBUG_P0(sc, "Setting LIMITING MODE");
9409 		elink_cl45_write(sc, phy,
9410 				 MDIO_PMA_DEVAD,
9411 				 MDIO_PMA_REG_ROM_VER2,
9412 				 ELINK_EDC_MODE_LIMITING);
9413 	} else { /* LRM mode ( default )*/
9414 
9415 		ELINK_DEBUG_P0(sc, "Setting LRM MODE");
9416 
9417 		/* Changing to LRM mode takes quite few seconds. So do it only
9418 		 * if current mode is limiting (default is LRM)
9419 		 */
9420 		if (cur_limiting_mode != ELINK_EDC_MODE_LIMITING)
9421 			return ELINK_STATUS_OK;
9422 
9423 		elink_cl45_write(sc, phy,
9424 				 MDIO_PMA_DEVAD,
9425 				 MDIO_PMA_REG_LRM_MODE,
9426 				 0);
9427 		elink_cl45_write(sc, phy,
9428 				 MDIO_PMA_DEVAD,
9429 				 MDIO_PMA_REG_ROM_VER2,
9430 				 0x128);
9431 		elink_cl45_write(sc, phy,
9432 				 MDIO_PMA_DEVAD,
9433 				 MDIO_PMA_REG_MISC_CTRL0,
9434 				 0x4008);
9435 		elink_cl45_write(sc, phy,
9436 				 MDIO_PMA_DEVAD,
9437 				 MDIO_PMA_REG_LRM_MODE,
9438 				 0xaaaa);
9439 	}
9440 	return ELINK_STATUS_OK;
9441 }
9442 
elink_8727_set_limiting_mode(struct bnx2x_softc * sc,struct elink_phy * phy,uint16_t edc_mode)9443 static elink_status_t elink_8727_set_limiting_mode(struct bnx2x_softc *sc,
9444 					struct elink_phy *phy,
9445 					uint16_t edc_mode)
9446 {
9447 	uint16_t phy_identifier;
9448 	uint16_t rom_ver2_val;
9449 	elink_cl45_read(sc, phy,
9450 			MDIO_PMA_DEVAD,
9451 			MDIO_PMA_REG_PHY_IDENTIFIER,
9452 			&phy_identifier);
9453 
9454 	elink_cl45_write(sc, phy,
9455 			 MDIO_PMA_DEVAD,
9456 			 MDIO_PMA_REG_PHY_IDENTIFIER,
9457 			 (phy_identifier & ~(1 << 9)));
9458 
9459 	elink_cl45_read(sc, phy,
9460 			MDIO_PMA_DEVAD,
9461 			MDIO_PMA_REG_ROM_VER2,
9462 			&rom_ver2_val);
9463 	/* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
9464 	elink_cl45_write(sc, phy,
9465 			 MDIO_PMA_DEVAD,
9466 			 MDIO_PMA_REG_ROM_VER2,
9467 			 (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
9468 
9469 	elink_cl45_write(sc, phy,
9470 			 MDIO_PMA_DEVAD,
9471 			 MDIO_PMA_REG_PHY_IDENTIFIER,
9472 			 (phy_identifier | (1 << 9)));
9473 
9474 	return ELINK_STATUS_OK;
9475 }
9476 
elink_8727_specific_func(struct elink_phy * phy,struct elink_params * params,uint32_t action)9477 static void elink_8727_specific_func(struct elink_phy *phy,
9478 				     struct elink_params *params,
9479 				     uint32_t action)
9480 {
9481 	struct bnx2x_softc *sc = params->sc;
9482 	uint16_t val;
9483 	switch (action) {
9484 	case ELINK_DISABLE_TX:
9485 		elink_sfp_set_transmitter(params, phy, 0);
9486 		break;
9487 	case ELINK_ENABLE_TX:
9488 		if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED))
9489 			elink_sfp_set_transmitter(params, phy, 1);
9490 		break;
9491 	case ELINK_PHY_INIT:
9492 		elink_cl45_write(sc, phy,
9493 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9494 				 (1 << 2) | (1 << 5));
9495 		elink_cl45_write(sc, phy,
9496 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
9497 				 0);
9498 		elink_cl45_write(sc, phy,
9499 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x0006);
9500 		/* Make MOD_ABS give interrupt on change */
9501 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9502 				MDIO_PMA_REG_8727_PCS_OPT_CTRL,
9503 				&val);
9504 		val |= (1 << 12);
9505 		if (phy->flags & ELINK_FLAGS_NOC)
9506 			val |= (3 << 5);
9507 		/* Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
9508 		 * status which reflect SFP+ module over-current
9509 		 */
9510 		if (!(phy->flags & ELINK_FLAGS_NOC))
9511 			val &= 0xff8f; /* Reset bits 4-6 */
9512 		elink_cl45_write(sc, phy,
9513 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
9514 				 val);
9515 		break;
9516 	default:
9517 		ELINK_DEBUG_P1(sc, "Function 0x%x not supported by 8727",
9518 		   action);
9519 		return;
9520 	}
9521 }
9522 
elink_set_e1e2_module_fault_led(struct elink_params * params,uint8_t gpio_mode)9523 static void elink_set_e1e2_module_fault_led(struct elink_params *params,
9524 					   uint8_t gpio_mode)
9525 {
9526 	struct bnx2x_softc *sc = params->sc;
9527 
9528 	uint32_t fault_led_gpio = REG_RD(sc, params->shmem_base +
9529 			    offsetof(struct shmem_region,
9530 			dev_info.port_hw_config[params->port].sfp_ctrl)) &
9531 		PORT_HW_CFG_FAULT_MODULE_LED_MASK;
9532 	switch (fault_led_gpio) {
9533 	case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
9534 		return;
9535 	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
9536 	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
9537 	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
9538 	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
9539 	{
9540 		uint8_t gpio_port = elink_get_gpio_port(params);
9541 		uint16_t gpio_pin = fault_led_gpio -
9542 			PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
9543 		ELINK_DEBUG_P3(sc, "Set fault module-detected led "
9544 				   "pin %x port %x mode %x",
9545 			       gpio_pin, gpio_port, gpio_mode);
9546 		elink_cb_gpio_write(sc, gpio_pin, gpio_mode, gpio_port);
9547 	}
9548 	break;
9549 	default:
9550 		ELINK_DEBUG_P1(sc, "Error: Invalid fault led mode 0x%x",
9551 			       fault_led_gpio);
9552 	}
9553 }
9554 
elink_set_e3_module_fault_led(struct elink_params * params,uint8_t gpio_mode)9555 static void elink_set_e3_module_fault_led(struct elink_params *params,
9556 					  uint8_t gpio_mode)
9557 {
9558 	uint32_t pin_cfg;
9559 	uint8_t port = params->port;
9560 	struct bnx2x_softc *sc = params->sc;
9561 	pin_cfg = (REG_RD(sc, params->shmem_base +
9562 			 offsetof(struct shmem_region,
9563 				  dev_info.port_hw_config[port].e3_sfp_ctrl)) &
9564 		PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >>
9565 		PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT;
9566 	ELINK_DEBUG_P2(sc, "Setting Fault LED to %d using pin cfg %d",
9567 		       gpio_mode, pin_cfg);
9568 	elink_set_cfg_pin(sc, pin_cfg, gpio_mode);
9569 }
9570 
elink_set_sfp_module_fault_led(struct elink_params * params,uint8_t gpio_mode)9571 static void elink_set_sfp_module_fault_led(struct elink_params *params,
9572 					   uint8_t gpio_mode)
9573 {
9574 	struct bnx2x_softc *sc = params->sc;
9575 	ELINK_DEBUG_P1(sc, "Setting SFP+ module fault LED to %d", gpio_mode);
9576 	if (CHIP_IS_E3(sc)) {
9577 		/* Low ==> if SFP+ module is supported otherwise
9578 		 * High ==> if SFP+ module is not on the approved vendor list
9579 		 */
9580 		elink_set_e3_module_fault_led(params, gpio_mode);
9581 	} else
9582 		elink_set_e1e2_module_fault_led(params, gpio_mode);
9583 }
9584 
elink_warpcore_hw_reset(__rte_unused struct elink_phy * phy,struct elink_params * params)9585 static void elink_warpcore_hw_reset(__rte_unused struct elink_phy *phy,
9586 				    struct elink_params *params)
9587 {
9588 	struct bnx2x_softc *sc = params->sc;
9589 	elink_warpcore_power_module(params, 0);
9590 	/* Put Warpcore in low power mode */
9591 	REG_WR(sc, MISC_REG_WC0_RESET, 0x0c0e);
9592 
9593 	/* Put LCPLL in low power mode */
9594 	REG_WR(sc, MISC_REG_LCPLL_E40_PWRDWN, 1);
9595 	REG_WR(sc, MISC_REG_LCPLL_E40_RESETB_ANA, 0);
9596 	REG_WR(sc, MISC_REG_LCPLL_E40_RESETB_DIG, 0);
9597 }
9598 
elink_power_sfp_module(struct elink_params * params,struct elink_phy * phy,uint8_t power)9599 static void elink_power_sfp_module(struct elink_params *params,
9600 				   struct elink_phy *phy,
9601 				   uint8_t power)
9602 {
9603 	struct bnx2x_softc *sc = params->sc;
9604 	ELINK_DEBUG_P1(sc, "Setting SFP+ power to %x", power);
9605 
9606 	switch (phy->type) {
9607 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
9608 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
9609 		elink_8727_power_module(params->sc, phy, power);
9610 		break;
9611 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
9612 		elink_warpcore_power_module(params, power);
9613 		break;
9614 	default:
9615 		break;
9616 	}
9617 }
elink_warpcore_set_limiting_mode(struct elink_params * params,struct elink_phy * phy,uint16_t edc_mode)9618 static void elink_warpcore_set_limiting_mode(struct elink_params *params,
9619 					     struct elink_phy *phy,
9620 					     uint16_t edc_mode)
9621 {
9622 	uint16_t val = 0;
9623 	uint16_t mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
9624 	struct bnx2x_softc *sc = params->sc;
9625 
9626 	uint8_t lane = elink_get_warpcore_lane(phy, params);
9627 	/* This is a global register which controls all lanes */
9628 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
9629 			MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
9630 	val &= ~(0xf << (lane << 2));
9631 
9632 	switch (edc_mode) {
9633 	case ELINK_EDC_MODE_LINEAR:
9634 	case ELINK_EDC_MODE_LIMITING:
9635 		mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
9636 		break;
9637 	case ELINK_EDC_MODE_PASSIVE_DAC:
9638 	case ELINK_EDC_MODE_ACTIVE_DAC:
9639 		mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC;
9640 		break;
9641 	default:
9642 		break;
9643 	}
9644 
9645 	val |= (mode << (lane << 2));
9646 	elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
9647 			 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val);
9648 	/* A must read */
9649 	elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
9650 			MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
9651 
9652 	/* Restart microcode to re-read the new mode */
9653 	elink_warpcore_reset_lane(sc, phy, 1);
9654 	elink_warpcore_reset_lane(sc, phy, 0);
9655 
9656 }
9657 
elink_set_limiting_mode(struct elink_params * params,struct elink_phy * phy,uint16_t edc_mode)9658 static void elink_set_limiting_mode(struct elink_params *params,
9659 				    struct elink_phy *phy,
9660 				    uint16_t edc_mode)
9661 {
9662 	switch (phy->type) {
9663 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726:
9664 		elink_8726_set_limiting_mode(params->sc, phy, edc_mode);
9665 		break;
9666 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
9667 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
9668 		elink_8727_set_limiting_mode(params->sc, phy, edc_mode);
9669 		break;
9670 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
9671 		elink_warpcore_set_limiting_mode(params, phy, edc_mode);
9672 		break;
9673 	}
9674 }
9675 
elink_sfp_module_detection(struct elink_phy * phy,struct elink_params * params)9676 elink_status_t elink_sfp_module_detection(struct elink_phy *phy,
9677 			       struct elink_params *params)
9678 {
9679 	struct bnx2x_softc *sc = params->sc;
9680 	uint16_t edc_mode;
9681 	elink_status_t rc = ELINK_STATUS_OK;
9682 
9683 	uint32_t val = REG_RD(sc, params->shmem_base +
9684 			     offsetof(struct shmem_region, dev_info.
9685 				     port_feature_config[params->port].config));
9686 	/* Enabled transmitter by default */
9687 	elink_sfp_set_transmitter(params, phy, 1);
9688 	ELINK_DEBUG_P1(sc, "SFP+ module plugged in/out detected on port %d",
9689 		 params->port);
9690 	/* Power up module */
9691 	elink_power_sfp_module(params, phy, 1);
9692 	if (elink_get_edc_mode(phy, params, &edc_mode) != 0) {
9693 		ELINK_DEBUG_P0(sc, "Failed to get valid module type");
9694 		return ELINK_STATUS_ERROR;
9695 	} else if (elink_verify_sfp_module(phy, params) != 0) {
9696 		/* Check SFP+ module compatibility */
9697 		ELINK_DEBUG_P0(sc, "Module verification failed!!");
9698 		rc = ELINK_STATUS_ERROR;
9699 		/* Turn on fault module-detected led */
9700 		elink_set_sfp_module_fault_led(params,
9701 					       MISC_REGISTERS_GPIO_HIGH);
9702 
9703 		/* Check if need to power down the SFP+ module */
9704 		if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9705 		     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) {
9706 			ELINK_DEBUG_P0(sc, "Shutdown SFP+ module!!");
9707 			elink_power_sfp_module(params, phy, 0);
9708 			return rc;
9709 		}
9710 	} else {
9711 		/* Turn off fault module-detected led */
9712 		elink_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
9713 	}
9714 
9715 	/* Check and set limiting mode / LRM mode on 8726. On 8727 it
9716 	 * is done automatically
9717 	 */
9718 	elink_set_limiting_mode(params, phy, edc_mode);
9719 
9720 	/* Disable transmit for this module if the module is not approved, and
9721 	 * laser needs to be disabled.
9722 	 */
9723 	if ((rc != 0) &&
9724 	    ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9725 	     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER))
9726 		elink_sfp_set_transmitter(params, phy, 0);
9727 
9728 	return rc;
9729 }
9730 
elink_handle_module_detect_int(struct elink_params * params)9731 void elink_handle_module_detect_int(struct elink_params *params)
9732 {
9733 	struct bnx2x_softc *sc = params->sc;
9734 	struct elink_phy *phy;
9735 	uint32_t gpio_val;
9736 	uint8_t gpio_num, gpio_port;
9737 	if (CHIP_IS_E3(sc)) {
9738 		phy = &params->phy[ELINK_INT_PHY];
9739 		/* Always enable TX laser, will be disabled in case of fault */
9740 		elink_sfp_set_transmitter(params, phy, 1);
9741 	} else {
9742 		phy = &params->phy[ELINK_EXT_PHY1];
9743 	}
9744 	if (elink_get_mod_abs_int_cfg(sc, params->chip_id, params->shmem_base,
9745 				      params->port, &gpio_num, &gpio_port) ==
9746 	    ELINK_STATUS_ERROR) {
9747 		ELINK_DEBUG_P0(sc, "Failed to get MOD_ABS interrupt config");
9748 		return;
9749 	}
9750 
9751 	/* Set valid module led off */
9752 	elink_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
9753 
9754 	/* Get current gpio val reflecting module plugged in / out*/
9755 	gpio_val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
9756 
9757 	/* Call the handling function in case module is detected */
9758 	if (gpio_val == 0) {
9759 		elink_set_mdio_emac_per_phy(sc, params);
9760 		elink_set_aer_mmd(params, phy);
9761 
9762 		elink_power_sfp_module(params, phy, 1);
9763 		elink_cb_gpio_int_write(sc, gpio_num,
9764 				   MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
9765 				   gpio_port);
9766 		if (elink_wait_for_sfp_module_initialized(phy, params) == 0) {
9767 			elink_sfp_module_detection(phy, params);
9768 			if (CHIP_IS_E3(sc)) {
9769 				uint16_t rx_tx_in_reset;
9770 				/* In case WC is out of reset, reconfigure the
9771 				 * link speed while taking into account 1G
9772 				 * module limitation.
9773 				 */
9774 				elink_cl45_read(sc, phy,
9775 						MDIO_WC_DEVAD,
9776 						MDIO_WC_REG_DIGITAL5_MISC6,
9777 						&rx_tx_in_reset);
9778 				if ((!rx_tx_in_reset) &&
9779 				    (params->link_flags &
9780 				     ELINK_PHY_INITIALIZED)) {
9781 					elink_warpcore_reset_lane(sc, phy, 1);
9782 					elink_warpcore_config_sfi(phy, params);
9783 					elink_warpcore_reset_lane(sc, phy, 0);
9784 				}
9785 			}
9786 		} else {
9787 			ELINK_DEBUG_P0(sc, "SFP+ module is not initialized");
9788 		}
9789 	} else {
9790 		elink_cb_gpio_int_write(sc, gpio_num,
9791 				   MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
9792 				   gpio_port);
9793 		/* Module was plugged out.
9794 		 * Disable transmit for this module
9795 		 */
9796 		phy->media_type = ELINK_ETH_PHY_NOT_PRESENT;
9797 	}
9798 }
9799 
9800 /******************************************************************/
9801 /*		Used by 8706 and 8727                             */
9802 /******************************************************************/
elink_sfp_mask_fault(struct bnx2x_softc * sc,struct elink_phy * phy,uint16_t alarm_status_offset,uint16_t alarm_ctrl_offset)9803 static void elink_sfp_mask_fault(struct bnx2x_softc *sc,
9804 				 struct elink_phy *phy,
9805 				 uint16_t alarm_status_offset,
9806 				 uint16_t alarm_ctrl_offset)
9807 {
9808 	uint16_t alarm_status, val;
9809 	elink_cl45_read(sc, phy,
9810 			MDIO_PMA_DEVAD, alarm_status_offset,
9811 			&alarm_status);
9812 	elink_cl45_read(sc, phy,
9813 			MDIO_PMA_DEVAD, alarm_status_offset,
9814 			&alarm_status);
9815 	/* Mask or enable the fault event. */
9816 	elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
9817 	if (alarm_status & (1 << 0))
9818 		val &= ~(1 << 0);
9819 	else
9820 		val |= (1 << 0);
9821 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
9822 }
9823 /******************************************************************/
9824 /*		common BNX2X8706/BNX2X8726 PHY SECTION		  */
9825 /******************************************************************/
elink_8706_8726_read_status(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)9826 static uint8_t elink_8706_8726_read_status(struct elink_phy *phy,
9827 				      struct elink_params *params,
9828 				      struct elink_vars *vars)
9829 {
9830 	uint8_t link_up = 0;
9831 	uint16_t val1, val2, rx_sd, pcs_status;
9832 	struct bnx2x_softc *sc = params->sc;
9833 	ELINK_DEBUG_P0(sc, "XGXS 8706/8726");
9834 	/* Clear RX Alarm*/
9835 	elink_cl45_read(sc, phy,
9836 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
9837 
9838 	elink_sfp_mask_fault(sc, phy, MDIO_PMA_LASI_TXSTAT,
9839 			     MDIO_PMA_LASI_TXCTRL);
9840 
9841 	/* Clear LASI indication*/
9842 	elink_cl45_read(sc, phy,
9843 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
9844 	elink_cl45_read(sc, phy,
9845 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
9846 	ELINK_DEBUG_P2(sc, "8706/8726 LASI status 0x%x--> 0x%x", val1, val2);
9847 
9848 	elink_cl45_read(sc, phy,
9849 			MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
9850 	elink_cl45_read(sc, phy,
9851 			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
9852 	elink_cl45_read(sc, phy,
9853 			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
9854 	elink_cl45_read(sc, phy,
9855 			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
9856 
9857 	ELINK_DEBUG_P3(sc, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
9858 			" link_status 0x%x", rx_sd, pcs_status, val2);
9859 	/* Link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
9860 	 * are set, or if the autoneg bit 1 is set
9861 	 */
9862 	link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1 << 1)));
9863 	if (link_up) {
9864 		if (val2 & (1 << 1))
9865 			vars->line_speed = ELINK_SPEED_1000;
9866 		else
9867 			vars->line_speed = ELINK_SPEED_10000;
9868 		elink_ext_phy_resolve_fc(phy, params, vars);
9869 		vars->duplex = DUPLEX_FULL;
9870 	}
9871 
9872 	/* Capture 10G link fault. Read twice to clear stale value. */
9873 	if (vars->line_speed == ELINK_SPEED_10000) {
9874 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9875 			    MDIO_PMA_LASI_TXSTAT, &val1);
9876 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9877 			    MDIO_PMA_LASI_TXSTAT, &val1);
9878 		if (val1 & (1 << 0))
9879 			vars->fault_detected = 1;
9880 	}
9881 
9882 	return link_up;
9883 }
9884 
9885 /******************************************************************/
9886 /*			BNX2X8706 PHY SECTION			  */
9887 /******************************************************************/
elink_8706_config_init(struct elink_phy * phy,struct elink_params * params,__rte_unused struct elink_vars * vars)9888 static uint8_t elink_8706_config_init(struct elink_phy *phy,
9889 				 struct elink_params *params,
9890 				 __rte_unused struct elink_vars *vars)
9891 {
9892 	uint32_t tx_en_mode;
9893 	uint16_t cnt, val, tmp1;
9894 	struct bnx2x_softc *sc = params->sc;
9895 
9896 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
9897 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
9898 	/* HW reset */
9899 	elink_ext_phy_hw_reset(sc, params->port);
9900 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
9901 	elink_wait_reset_complete(sc, phy, params);
9902 
9903 	/* Wait until fw is loaded */
9904 	for (cnt = 0; cnt < 100; cnt++) {
9905 		elink_cl45_read(sc, phy,
9906 				MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
9907 		if (val)
9908 			break;
9909 		DELAY(1000 * 10);
9910 	}
9911 	ELINK_DEBUG_P1(sc, "XGXS 8706 is initialized after %d ms", cnt);
9912 	if ((params->feature_config_flags &
9913 	     ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
9914 		uint8_t i;
9915 		uint16_t reg;
9916 		for (i = 0; i < 4; i++) {
9917 			reg = MDIO_XS_8706_REG_BANK_RX0 +
9918 				i * (MDIO_XS_8706_REG_BANK_RX1 -
9919 				     MDIO_XS_8706_REG_BANK_RX0);
9920 			elink_cl45_read(sc, phy, MDIO_XS_DEVAD, reg, &val);
9921 			/* Clear first 3 bits of the control */
9922 			val &= ~0x7;
9923 			/* Set control bits according to configuration */
9924 			val |= (phy->rx_preemphasis[i] & 0x7);
9925 			ELINK_DEBUG_P2(sc, "Setting RX Equalizer to BNX2X8706"
9926 				   " reg 0x%x <-- val 0x%x", reg, val);
9927 			elink_cl45_write(sc, phy, MDIO_XS_DEVAD, reg, val);
9928 		}
9929 	}
9930 	/* Force speed */
9931 	if (phy->req_line_speed == ELINK_SPEED_10000) {
9932 		ELINK_DEBUG_P0(sc, "XGXS 8706 force 10Gbps");
9933 
9934 		elink_cl45_write(sc, phy,
9935 				 MDIO_PMA_DEVAD,
9936 				 MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
9937 		elink_cl45_write(sc, phy,
9938 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
9939 				 0);
9940 		/* Arm LASI for link and Tx fault. */
9941 		elink_cl45_write(sc, phy,
9942 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 3);
9943 	} else {
9944 		/* Force 1Gbps using autoneg with 1G advertisement */
9945 
9946 		/* Allow CL37 through CL73 */
9947 		ELINK_DEBUG_P0(sc, "XGXS 8706 AutoNeg");
9948 		elink_cl45_write(sc, phy,
9949 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
9950 
9951 		/* Enable Full-Duplex advertisement on CL37 */
9952 		elink_cl45_write(sc, phy,
9953 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
9954 		/* Enable CL37 AN */
9955 		elink_cl45_write(sc, phy,
9956 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
9957 		/* 1G support */
9958 		elink_cl45_write(sc, phy,
9959 				 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1 << 5));
9960 
9961 		/* Enable clause 73 AN */
9962 		elink_cl45_write(sc, phy,
9963 				 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
9964 		elink_cl45_write(sc, phy,
9965 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9966 				 0x0400);
9967 		elink_cl45_write(sc, phy,
9968 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
9969 				 0x0004);
9970 	}
9971 	elink_save_bnx2x_spirom_ver(sc, phy, params->port);
9972 
9973 	/* If TX Laser is controlled by GPIO_0, do not let PHY go into low
9974 	 * power mode, if TX Laser is disabled
9975 	 */
9976 
9977 	tx_en_mode = REG_RD(sc, params->shmem_base +
9978 			    offsetof(struct shmem_region,
9979 				dev_info.port_hw_config[params->port].sfp_ctrl))
9980 			& PORT_HW_CFG_TX_LASER_MASK;
9981 
9982 	if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
9983 		ELINK_DEBUG_P0(sc, "Enabling TXONOFF_PWRDN_DIS");
9984 		elink_cl45_read(sc, phy,
9985 			MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
9986 		tmp1 |= 0x1;
9987 		elink_cl45_write(sc, phy,
9988 			MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
9989 	}
9990 
9991 	return ELINK_STATUS_OK;
9992 }
9993 
elink_8706_read_status(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)9994 static uint8_t elink_8706_read_status(struct elink_phy *phy,
9995 				  struct elink_params *params,
9996 				  struct elink_vars *vars)
9997 {
9998 	return elink_8706_8726_read_status(phy, params, vars);
9999 }
10000 
10001 /******************************************************************/
10002 /*			BNX2X8726 PHY SECTION			  */
10003 /******************************************************************/
elink_8726_config_loopback(struct elink_phy * phy,struct elink_params * params)10004 static void elink_8726_config_loopback(struct elink_phy *phy,
10005 				       struct elink_params *params)
10006 {
10007 	struct bnx2x_softc *sc = params->sc;
10008 	ELINK_DEBUG_P0(sc, "PMA/PMD ext_phy_loopback: 8726");
10009 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
10010 }
10011 
elink_8726_external_rom_boot(struct elink_phy * phy,struct elink_params * params)10012 static void elink_8726_external_rom_boot(struct elink_phy *phy,
10013 					 struct elink_params *params)
10014 {
10015 	struct bnx2x_softc *sc = params->sc;
10016 	/* Need to wait 100ms after reset */
10017 	DELAY(1000 * 100);
10018 
10019 	/* Micro controller re-boot */
10020 	elink_cl45_write(sc, phy,
10021 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
10022 
10023 	/* Set soft reset */
10024 	elink_cl45_write(sc, phy,
10025 			 MDIO_PMA_DEVAD,
10026 			 MDIO_PMA_REG_GEN_CTRL,
10027 			 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
10028 
10029 	elink_cl45_write(sc, phy,
10030 			 MDIO_PMA_DEVAD,
10031 			 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
10032 
10033 	elink_cl45_write(sc, phy,
10034 			 MDIO_PMA_DEVAD,
10035 			 MDIO_PMA_REG_GEN_CTRL,
10036 			 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
10037 
10038 	/* Wait for 150ms for microcode load */
10039 	DELAY(1000 * 150);
10040 
10041 	/* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
10042 	elink_cl45_write(sc, phy,
10043 			 MDIO_PMA_DEVAD,
10044 			 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
10045 
10046 	DELAY(1000 * 200);
10047 	elink_save_bnx2x_spirom_ver(sc, phy, params->port);
10048 }
10049 
elink_8726_read_status(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)10050 static uint8_t elink_8726_read_status(struct elink_phy *phy,
10051 				 struct elink_params *params,
10052 				 struct elink_vars *vars)
10053 {
10054 	struct bnx2x_softc *sc = params->sc;
10055 	uint16_t val1;
10056 	uint8_t link_up = elink_8706_8726_read_status(phy, params, vars);
10057 	if (link_up) {
10058 		elink_cl45_read(sc, phy,
10059 				MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
10060 				&val1);
10061 		if (val1 & (1 << 15)) {
10062 			ELINK_DEBUG_P0(sc, "Tx is disabled");
10063 			link_up = 0;
10064 			vars->line_speed = 0;
10065 		}
10066 	}
10067 	return link_up;
10068 }
10069 
10070 
elink_8726_config_init(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)10071 static uint8_t elink_8726_config_init(struct elink_phy *phy,
10072 				  struct elink_params *params,
10073 				  struct elink_vars *vars)
10074 {
10075 	struct bnx2x_softc *sc = params->sc;
10076 	ELINK_DEBUG_P0(sc, "Initializing BNX2X8726");
10077 
10078 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1 << 15);
10079 	elink_wait_reset_complete(sc, phy, params);
10080 
10081 	elink_8726_external_rom_boot(phy, params);
10082 
10083 	/* Need to call module detected on initialization since the module
10084 	 * detection triggered by actual module insertion might occur before
10085 	 * driver is loaded, and when driver is loaded, it reset all
10086 	 * registers, including the transmitter
10087 	 */
10088 	elink_sfp_module_detection(phy, params);
10089 
10090 	if (phy->req_line_speed == ELINK_SPEED_1000) {
10091 		ELINK_DEBUG_P0(sc, "Setting 1G force");
10092 		elink_cl45_write(sc, phy,
10093 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
10094 		elink_cl45_write(sc, phy,
10095 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
10096 		elink_cl45_write(sc, phy,
10097 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x5);
10098 		elink_cl45_write(sc, phy,
10099 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
10100 				 0x400);
10101 	} else if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10102 		   (phy->speed_cap_mask &
10103 		      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
10104 		   ((phy->speed_cap_mask &
10105 		      PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
10106 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
10107 		ELINK_DEBUG_P0(sc, "Setting 1G clause37");
10108 		/* Set Flow control */
10109 		elink_ext_phy_set_pause(params, phy, vars);
10110 		elink_cl45_write(sc, phy,
10111 				 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
10112 		elink_cl45_write(sc, phy,
10113 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
10114 		elink_cl45_write(sc, phy,
10115 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
10116 		elink_cl45_write(sc, phy,
10117 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
10118 		elink_cl45_write(sc, phy,
10119 				MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
10120 		/* Enable RX-ALARM control to receive interrupt for 1G speed
10121 		 * change
10122 		 */
10123 		elink_cl45_write(sc, phy,
10124 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x4);
10125 		elink_cl45_write(sc, phy,
10126 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
10127 				 0x400);
10128 
10129 	} else { /* Default 10G. Set only LASI control */
10130 		elink_cl45_write(sc, phy,
10131 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 1);
10132 	}
10133 
10134 	/* Set TX PreEmphasis if needed */
10135 	if ((params->feature_config_flags &
10136 	     ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
10137 		ELINK_DEBUG_P2(sc,
10138 		   "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x",
10139 			 phy->tx_preemphasis[0],
10140 			 phy->tx_preemphasis[1]);
10141 		elink_cl45_write(sc, phy,
10142 				 MDIO_PMA_DEVAD,
10143 				 MDIO_PMA_REG_8726_TX_CTRL1,
10144 				 phy->tx_preemphasis[0]);
10145 
10146 		elink_cl45_write(sc, phy,
10147 				 MDIO_PMA_DEVAD,
10148 				 MDIO_PMA_REG_8726_TX_CTRL2,
10149 				 phy->tx_preemphasis[1]);
10150 	}
10151 
10152 	return ELINK_STATUS_OK;
10153 
10154 }
10155 
elink_8726_link_reset(struct elink_phy * phy,struct elink_params * params)10156 static void elink_8726_link_reset(struct elink_phy *phy,
10157 				  struct elink_params *params)
10158 {
10159 	struct bnx2x_softc *sc = params->sc;
10160 	ELINK_DEBUG_P1(sc, "elink_8726_link_reset port %d", params->port);
10161 	/* Set serial boot control for external load */
10162 	elink_cl45_write(sc, phy,
10163 			 MDIO_PMA_DEVAD,
10164 			 MDIO_PMA_REG_GEN_CTRL, 0x0001);
10165 }
10166 
10167 /******************************************************************/
10168 /*			BNX2X8727 PHY SECTION			  */
10169 /******************************************************************/
10170 
elink_8727_set_link_led(struct elink_phy * phy,struct elink_params * params,uint8_t mode)10171 static void elink_8727_set_link_led(struct elink_phy *phy,
10172 				    struct elink_params *params, uint8_t mode)
10173 {
10174 	struct bnx2x_softc *sc = params->sc;
10175 	uint16_t led_mode_bitmask = 0;
10176 	uint16_t gpio_pins_bitmask = 0;
10177 	uint16_t val;
10178 	/* Only NOC flavor requires to set the LED specifically */
10179 	if (!(phy->flags & ELINK_FLAGS_NOC))
10180 		return;
10181 	switch (mode) {
10182 	case ELINK_LED_MODE_FRONT_PANEL_OFF:
10183 	case ELINK_LED_MODE_OFF:
10184 		led_mode_bitmask = 0;
10185 		gpio_pins_bitmask = 0x03;
10186 		break;
10187 	case ELINK_LED_MODE_ON:
10188 		led_mode_bitmask = 0;
10189 		gpio_pins_bitmask = 0x02;
10190 		break;
10191 	case ELINK_LED_MODE_OPER:
10192 		led_mode_bitmask = 0x60;
10193 		gpio_pins_bitmask = 0x11;
10194 		break;
10195 	}
10196 	elink_cl45_read(sc, phy,
10197 			MDIO_PMA_DEVAD,
10198 			MDIO_PMA_REG_8727_PCS_OPT_CTRL,
10199 			&val);
10200 	val &= 0xff8f;
10201 	val |= led_mode_bitmask;
10202 	elink_cl45_write(sc, phy,
10203 			 MDIO_PMA_DEVAD,
10204 			 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
10205 			 val);
10206 	elink_cl45_read(sc, phy,
10207 			MDIO_PMA_DEVAD,
10208 			MDIO_PMA_REG_8727_GPIO_CTRL,
10209 			&val);
10210 	val &= 0xffe0;
10211 	val |= gpio_pins_bitmask;
10212 	elink_cl45_write(sc, phy,
10213 			 MDIO_PMA_DEVAD,
10214 			 MDIO_PMA_REG_8727_GPIO_CTRL,
10215 			 val);
10216 }
elink_8727_hw_reset(__rte_unused struct elink_phy * phy,struct elink_params * params)10217 static void elink_8727_hw_reset(__rte_unused struct elink_phy *phy,
10218 				struct elink_params *params) {
10219 	uint32_t swap_val, swap_override;
10220 	uint8_t port;
10221 	/* The PHY reset is controlled by GPIO 1. Fake the port number
10222 	 * to cancel the swap done in set_gpio()
10223 	 */
10224 	struct bnx2x_softc *sc = params->sc;
10225 	swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
10226 	swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
10227 	port = (swap_val && swap_override) ^ 1;
10228 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
10229 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
10230 }
10231 
elink_8727_config_speed(struct elink_phy * phy,struct elink_params * params)10232 static void elink_8727_config_speed(struct elink_phy *phy,
10233 				    struct elink_params *params)
10234 {
10235 	struct bnx2x_softc *sc = params->sc;
10236 	uint16_t tmp1, val;
10237 	/* Set option 1G speed */
10238 	if ((phy->req_line_speed == ELINK_SPEED_1000) ||
10239 	    (phy->media_type == ELINK_ETH_PHY_SFP_1G_FIBER)) {
10240 		ELINK_DEBUG_P0(sc, "Setting 1G force");
10241 		elink_cl45_write(sc, phy,
10242 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
10243 		elink_cl45_write(sc, phy,
10244 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
10245 		elink_cl45_read(sc, phy,
10246 				MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
10247 		ELINK_DEBUG_P1(sc, "1.7 = 0x%x", tmp1);
10248 		/* Power down the XAUI until link is up in case of dual-media
10249 		 * and 1G
10250 		 */
10251 		if (ELINK_DUAL_MEDIA(params)) {
10252 			elink_cl45_read(sc, phy,
10253 					MDIO_PMA_DEVAD,
10254 					MDIO_PMA_REG_8727_PCS_GP, &val);
10255 			val |= (3 << 10);
10256 			elink_cl45_write(sc, phy,
10257 					 MDIO_PMA_DEVAD,
10258 					 MDIO_PMA_REG_8727_PCS_GP, val);
10259 		}
10260 	} else if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10261 		   ((phy->speed_cap_mask &
10262 		     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
10263 		   ((phy->speed_cap_mask &
10264 		      PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
10265 		   PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
10266 
10267 		ELINK_DEBUG_P0(sc, "Setting 1G clause37");
10268 		elink_cl45_write(sc, phy,
10269 				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
10270 		elink_cl45_write(sc, phy,
10271 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
10272 	} else {
10273 		/* Since the 8727 has only single reset pin, need to set the 10G
10274 		 * registers although it is default
10275 		 */
10276 		elink_cl45_write(sc, phy,
10277 				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
10278 				 0x0020);
10279 		elink_cl45_write(sc, phy,
10280 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
10281 		elink_cl45_write(sc, phy,
10282 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
10283 		elink_cl45_write(sc, phy,
10284 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
10285 				 0x0008);
10286 	}
10287 }
10288 
elink_8727_config_init(struct elink_phy * phy,struct elink_params * params,__rte_unused struct elink_vars * vars)10289 static uint8_t elink_8727_config_init(struct elink_phy *phy,
10290 				  struct elink_params *params,
10291 				  __rte_unused struct elink_vars *vars)
10292 {
10293 	uint32_t tx_en_mode;
10294 	uint16_t tmp1, mod_abs, tmp2;
10295 	struct bnx2x_softc *sc = params->sc;
10296 	/* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
10297 
10298 	elink_wait_reset_complete(sc, phy, params);
10299 
10300 	ELINK_DEBUG_P0(sc, "Initializing BNX2X8727");
10301 
10302 	elink_8727_specific_func(phy, params, ELINK_PHY_INIT);
10303 	/* Initially configure MOD_ABS to interrupt when module is
10304 	 * presence( bit 8)
10305 	 */
10306 	elink_cl45_read(sc, phy,
10307 			MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
10308 	/* Set EDC off by setting OPTXLOS signal input to low (bit 9).
10309 	 * When the EDC is off it locks onto a reference clock and avoids
10310 	 * 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, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10317 
10318 	/* Enable/Disable PHY transmitter output */
10319 	elink_set_disable_pmd_transmit(params, phy, 0);
10320 
10321 	elink_8727_power_module(sc, phy, 1);
10322 
10323 	elink_cl45_read(sc, phy,
10324 			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
10325 
10326 	elink_cl45_read(sc, phy,
10327 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
10328 
10329 	elink_8727_config_speed(phy, params);
10330 
10331 
10332 	/* Set TX PreEmphasis if needed */
10333 	if ((params->feature_config_flags &
10334 	     ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
10335 		ELINK_DEBUG_P2(sc, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x",
10336 			   phy->tx_preemphasis[0],
10337 			   phy->tx_preemphasis[1]);
10338 		elink_cl45_write(sc, phy,
10339 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
10340 				 phy->tx_preemphasis[0]);
10341 
10342 		elink_cl45_write(sc, phy,
10343 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
10344 				 phy->tx_preemphasis[1]);
10345 	}
10346 
10347 	/* If TX Laser is controlled by GPIO_0, do not let PHY go into low
10348 	 * power mode, if TX Laser is disabled
10349 	 */
10350 	tx_en_mode = REG_RD(sc, params->shmem_base +
10351 			    offsetof(struct shmem_region,
10352 				dev_info.port_hw_config[params->port].sfp_ctrl))
10353 			& PORT_HW_CFG_TX_LASER_MASK;
10354 
10355 	if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
10356 
10357 		ELINK_DEBUG_P0(sc, "Enabling TXONOFF_PWRDN_DIS");
10358 		elink_cl45_read(sc, phy,
10359 			MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
10360 		tmp2 |= 0x1000;
10361 		tmp2 &= 0xFFEF;
10362 		elink_cl45_write(sc, phy,
10363 			MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
10364 		elink_cl45_read(sc, phy,
10365 				MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
10366 				&tmp2);
10367 		elink_cl45_write(sc, phy,
10368 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
10369 				 (tmp2 & 0x7fff));
10370 	}
10371 
10372 	return ELINK_STATUS_OK;
10373 }
10374 
elink_8727_handle_mod_abs(struct elink_phy * phy,struct elink_params * params)10375 static void elink_8727_handle_mod_abs(struct elink_phy *phy,
10376 				      struct elink_params *params)
10377 {
10378 	struct bnx2x_softc *sc = params->sc;
10379 	uint16_t mod_abs, rx_alarm_status;
10380 	uint32_t val = REG_RD(sc, params->shmem_base +
10381 			     offsetof(struct shmem_region, dev_info.
10382 				      port_feature_config[params->port].
10383 				      config));
10384 	elink_cl45_read(sc, phy,
10385 			MDIO_PMA_DEVAD,
10386 			MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
10387 	if (mod_abs & (1 << 8)) {
10388 
10389 		/* Module is absent */
10390 		ELINK_DEBUG_P0(sc,
10391 		   "MOD_ABS indication show module is absent");
10392 		phy->media_type = ELINK_ETH_PHY_NOT_PRESENT;
10393 		/* 1. Set mod_abs to detect next module
10394 		 *    presence event
10395 		 * 2. Set EDC off by setting OPTXLOS signal input to low
10396 		 *    (bit 9).
10397 		 *    When the EDC is off it locks onto a reference clock and
10398 		 *    avoids becoming 'lost'.
10399 		 */
10400 		mod_abs &= ~(1 << 8);
10401 		if (!(phy->flags & ELINK_FLAGS_NOC))
10402 			mod_abs &= ~(1 << 9);
10403 		elink_cl45_write(sc, phy,
10404 				 MDIO_PMA_DEVAD,
10405 				 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10406 
10407 		/* Clear RX alarm since it stays up as long as
10408 		 * the mod_abs wasn't changed
10409 		 */
10410 		elink_cl45_read(sc, phy,
10411 				MDIO_PMA_DEVAD,
10412 				MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10413 
10414 	} else {
10415 		/* Module is present */
10416 		ELINK_DEBUG_P0(sc,
10417 		   "MOD_ABS indication show module is present");
10418 		/* First disable transmitter, and if the module is ok, the
10419 		 * module_detection will enable it
10420 		 * 1. Set mod_abs to detect next module absent event ( bit 8)
10421 		 * 2. Restore the default polarity of the OPRXLOS signal and
10422 		 * this signal will then correctly indicate the presence or
10423 		 * absence of the Rx signal. (bit 9)
10424 		 */
10425 		mod_abs |= (1 << 8);
10426 		if (!(phy->flags & ELINK_FLAGS_NOC))
10427 			mod_abs |= (1 << 9);
10428 		elink_cl45_write(sc, phy,
10429 				 MDIO_PMA_DEVAD,
10430 				 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10431 
10432 		/* Clear RX alarm since it stays up as long as the mod_abs
10433 		 * wasn't changed. This is need to be done before calling the
10434 		 * module detection, otherwise it will clear* the link update
10435 		 * alarm
10436 		 */
10437 		elink_cl45_read(sc, phy,
10438 				MDIO_PMA_DEVAD,
10439 				MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10440 
10441 
10442 		if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
10443 		    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
10444 			elink_sfp_set_transmitter(params, phy, 0);
10445 
10446 		if (elink_wait_for_sfp_module_initialized(phy, params) == 0)
10447 			elink_sfp_module_detection(phy, params);
10448 		else
10449 			ELINK_DEBUG_P0(sc, "SFP+ module is not initialized");
10450 
10451 		/* Reconfigure link speed based on module type limitations */
10452 		elink_8727_config_speed(phy, params);
10453 	}
10454 
10455 	ELINK_DEBUG_P1(sc, "8727 RX_ALARM_STATUS 0x%x",
10456 		   rx_alarm_status);
10457 	/* No need to check link status in case of module plugged in/out */
10458 }
10459 
elink_8727_read_status(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)10460 static uint8_t elink_8727_read_status(struct elink_phy *phy,
10461 				 struct elink_params *params,
10462 				 struct elink_vars *vars)
10463 
10464 {
10465 	struct bnx2x_softc *sc = params->sc;
10466 	uint8_t link_up = 0;
10467 	uint16_t link_status = 0;
10468 	uint16_t rx_alarm_status, lasi_ctrl, val1;
10469 
10470 	/* If PHY is not initialized, do not check link status */
10471 	elink_cl45_read(sc, phy,
10472 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
10473 			&lasi_ctrl);
10474 	if (!lasi_ctrl)
10475 		return 0;
10476 
10477 	/* Check the LASI on Rx */
10478 	elink_cl45_read(sc, phy,
10479 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT,
10480 			&rx_alarm_status);
10481 	vars->line_speed = 0;
10482 	ELINK_DEBUG_P1(sc, "8727 RX_ALARM_STATUS  0x%x", rx_alarm_status);
10483 
10484 	elink_sfp_mask_fault(sc, phy, MDIO_PMA_LASI_TXSTAT,
10485 			     MDIO_PMA_LASI_TXCTRL);
10486 
10487 	elink_cl45_read(sc, phy,
10488 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
10489 
10490 	ELINK_DEBUG_P1(sc, "8727 LASI status 0x%x", val1);
10491 
10492 	/* Clear MSG-OUT */
10493 	elink_cl45_read(sc, phy,
10494 			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
10495 
10496 	/* If a module is present and there is need to check
10497 	 * for over current
10498 	 */
10499 	if (!(phy->flags & ELINK_FLAGS_NOC) && !(rx_alarm_status & (1 << 5))) {
10500 		/* Check over-current using 8727 GPIO0 input*/
10501 		elink_cl45_read(sc, phy,
10502 				MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
10503 				&val1);
10504 
10505 		if ((val1 & (1 << 8)) == 0) {
10506 			uint8_t oc_port = params->port;
10507 			if (!CHIP_IS_E1x(sc))
10508 				oc_port = SC_PATH(sc) + (params->port << 1);
10509 			ELINK_DEBUG_P1(sc,
10510 			   "8727 Power fault has been detected on port %d",
10511 			   oc_port);
10512 			elink_cb_event_log(sc, ELINK_LOG_ID_OVER_CURRENT,
10513 					   oc_port);
10514 					/* "Error: Power fault on Port %d has "
10515 					 *  "been detected and the power to "
10516 					 *  "that SFP+ module has been removed "
10517 					 *  "to prevent failure of the card. "
10518 					 *  "Please remove the SFP+ module and "
10519 					 *  "restart the system to clear this "
10520 					 *  "error.",
10521 					 */
10522 			/* Disable all RX_ALARMs except for mod_abs */
10523 			elink_cl45_write(sc, phy,
10524 					 MDIO_PMA_DEVAD,
10525 					 MDIO_PMA_LASI_RXCTRL, (1 << 5));
10526 
10527 			elink_cl45_read(sc, phy,
10528 					MDIO_PMA_DEVAD,
10529 					MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
10530 			/* Wait for module_absent_event */
10531 			val1 |= (1 << 8);
10532 			elink_cl45_write(sc, phy,
10533 					 MDIO_PMA_DEVAD,
10534 					 MDIO_PMA_REG_PHY_IDENTIFIER, val1);
10535 			/* Clear RX alarm */
10536 			elink_cl45_read(sc, phy,
10537 				MDIO_PMA_DEVAD,
10538 				MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10539 			elink_8727_power_module(params->sc, phy, 0);
10540 			return 0;
10541 		}
10542 	} /* Over current check */
10543 
10544 	/* When module absent bit is set, check module */
10545 	if (rx_alarm_status & (1 << 5)) {
10546 		elink_8727_handle_mod_abs(phy, params);
10547 		/* Enable all mod_abs and link detection bits */
10548 		elink_cl45_write(sc, phy,
10549 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
10550 				 ((1 << 5) | (1 << 2)));
10551 	}
10552 
10553 	if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED)) {
10554 		ELINK_DEBUG_P0(sc, "Enabling 8727 TX laser");
10555 		elink_sfp_set_transmitter(params, phy, 1);
10556 	} else {
10557 		ELINK_DEBUG_P0(sc, "Tx is disabled");
10558 		return 0;
10559 	}
10560 
10561 	elink_cl45_read(sc, phy,
10562 			MDIO_PMA_DEVAD,
10563 			MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
10564 
10565 	/* Bits 0..2 --> speed detected,
10566 	 * Bits 13..15--> link is down
10567 	 */
10568 	if ((link_status & (1 << 2)) && (!(link_status & (1 << 15)))) {
10569 		link_up = 1;
10570 		vars->line_speed = ELINK_SPEED_10000;
10571 		ELINK_DEBUG_P1(sc, "port %x: External link up in 10G",
10572 			   params->port);
10573 	} else if ((link_status & (1 << 0)) && (!(link_status & (1 << 13)))) {
10574 		link_up = 1;
10575 		vars->line_speed = ELINK_SPEED_1000;
10576 		ELINK_DEBUG_P1(sc, "port %x: External link up in 1G",
10577 			   params->port);
10578 	} else {
10579 		link_up = 0;
10580 		ELINK_DEBUG_P1(sc, "port %x: External link is down",
10581 			   params->port);
10582 	}
10583 
10584 	/* Capture 10G link fault. */
10585 	if (vars->line_speed == ELINK_SPEED_10000) {
10586 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
10587 			    MDIO_PMA_LASI_TXSTAT, &val1);
10588 
10589 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
10590 			    MDIO_PMA_LASI_TXSTAT, &val1);
10591 
10592 		if (val1 & (1 << 0)) {
10593 			vars->fault_detected = 1;
10594 		}
10595 	}
10596 
10597 	if (link_up) {
10598 		elink_ext_phy_resolve_fc(phy, params, vars);
10599 		vars->duplex = DUPLEX_FULL;
10600 		ELINK_DEBUG_P1(sc, "duplex = 0x%x", vars->duplex);
10601 	}
10602 
10603 	if ((ELINK_DUAL_MEDIA(params)) &&
10604 	    (phy->req_line_speed == ELINK_SPEED_1000)) {
10605 		elink_cl45_read(sc, phy,
10606 				MDIO_PMA_DEVAD,
10607 				MDIO_PMA_REG_8727_PCS_GP, &val1);
10608 		/* In case of dual-media board and 1G, power up the XAUI side,
10609 		 * otherwise power it down. For 10G it is done automatically
10610 		 */
10611 		if (link_up)
10612 			val1 &= ~(3 << 10);
10613 		else
10614 			val1 |= (3 << 10);
10615 		elink_cl45_write(sc, phy,
10616 				 MDIO_PMA_DEVAD,
10617 				 MDIO_PMA_REG_8727_PCS_GP, val1);
10618 	}
10619 	return link_up;
10620 }
10621 
elink_8727_link_reset(struct elink_phy * phy,struct elink_params * params)10622 static void elink_8727_link_reset(struct elink_phy *phy,
10623 				  struct elink_params *params)
10624 {
10625 	struct bnx2x_softc *sc = params->sc;
10626 
10627 	/* Enable/Disable PHY transmitter output */
10628 	elink_set_disable_pmd_transmit(params, phy, 1);
10629 
10630 	/* Disable Transmitter */
10631 	elink_sfp_set_transmitter(params, phy, 0);
10632 	/* Clear LASI */
10633 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0);
10634 
10635 }
10636 
10637 /******************************************************************/
10638 /*		BNX2X8481/BNX2X84823/BNX2X84833 PHY SECTION	          */
10639 /******************************************************************/
elink_is_8483x_8485x(struct elink_phy * phy)10640 static int elink_is_8483x_8485x(struct elink_phy *phy)
10641 {
10642 	return ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84833) ||
10643 		(phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834) ||
10644 		(phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858));
10645 }
10646 
elink_save_848xx_spirom_version(struct elink_phy * phy,struct bnx2x_softc * sc,uint8_t port)10647 static void elink_save_848xx_spirom_version(struct elink_phy *phy,
10648 					    struct bnx2x_softc *sc,
10649 					    uint8_t port)
10650 {
10651 	uint16_t val, fw_ver2, cnt, i;
10652 	static struct elink_reg_set reg_set[] = {
10653 		{MDIO_PMA_DEVAD, 0xA819, 0x0014},
10654 		{MDIO_PMA_DEVAD, 0xA81A, 0xc200},
10655 		{MDIO_PMA_DEVAD, 0xA81B, 0x0000},
10656 		{MDIO_PMA_DEVAD, 0xA81C, 0x0300},
10657 		{MDIO_PMA_DEVAD, 0xA817, 0x0009}
10658 	};
10659 	uint16_t fw_ver1;
10660 
10661 	if (elink_is_8483x_8485x(phy)) {
10662 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1);
10663 		elink_save_spirom_version(sc, port, fw_ver1 & 0xfff,
10664 				phy->ver_addr);
10665 	} else {
10666 		/* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */
10667 		/* (1) set reg 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
10668 		for (i = 0; i < ARRAY_SIZE(reg_set); i++)
10669 			elink_cl45_write(sc, phy, reg_set[i].devad,
10670 					 reg_set[i].reg, reg_set[i].val);
10671 
10672 		for (cnt = 0; cnt < 100; cnt++) {
10673 			elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA818, &val);
10674 			if (val & 1)
10675 				break;
10676 			DELAY(5);
10677 		}
10678 		if (cnt == 100) {
10679 			ELINK_DEBUG_P0(sc, "Unable to read 848xx "
10680 					"phy fw version(1)");
10681 			elink_save_spirom_version(sc, port, 0,
10682 						  phy->ver_addr);
10683 			return;
10684 		}
10685 
10686 
10687 		/* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
10688 		elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
10689 		elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
10690 		elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
10691 		for (cnt = 0; cnt < 100; cnt++) {
10692 			elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA818, &val);
10693 			if (val & 1)
10694 				break;
10695 			DELAY(5);
10696 		}
10697 		if (cnt == 100) {
10698 			ELINK_DEBUG_P0(sc, "Unable to read 848xx phy fw "
10699 					"version(2)");
10700 			elink_save_spirom_version(sc, port, 0,
10701 						  phy->ver_addr);
10702 			return;
10703 		}
10704 
10705 		/* lower 16 bits of the register SPI_FW_STATUS */
10706 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
10707 		/* upper 16 bits of register SPI_FW_STATUS */
10708 		elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
10709 
10710 		elink_save_spirom_version(sc, port, (fw_ver2 << 16) | fw_ver1,
10711 					  phy->ver_addr);
10712 	}
10713 
10714 }
elink_848xx_set_led(struct bnx2x_softc * sc,struct elink_phy * phy)10715 static void elink_848xx_set_led(struct bnx2x_softc *sc,
10716 				struct elink_phy *phy)
10717 {
10718 	uint16_t val, offset, i;
10719 	static struct elink_reg_set reg_set[] = {
10720 		{MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, 0x0080},
10721 		{MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED2_MASK, 0x0018},
10722 		{MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_MASK, 0x0006},
10723 		{MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_BLINK, 0x0000},
10724 		{MDIO_PMA_DEVAD, MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH,
10725 			MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ},
10726 		{MDIO_AN_DEVAD, 0xFFFB, 0xFFFD}
10727 	};
10728 	/* PHYC_CTL_LED_CTL */
10729 	elink_cl45_read(sc, phy,
10730 			MDIO_PMA_DEVAD,
10731 			MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
10732 	val &= 0xFE00;
10733 	val |= 0x0092;
10734 
10735 	elink_cl45_write(sc, phy,
10736 			 MDIO_PMA_DEVAD,
10737 			 MDIO_PMA_REG_8481_LINK_SIGNAL, val);
10738 
10739 	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
10740 		elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
10741 				 reg_set[i].val);
10742 
10743 	if (elink_is_8483x_8485x(phy))
10744 		offset = MDIO_PMA_REG_84833_CTL_LED_CTL_1;
10745 	else
10746 		offset = MDIO_PMA_REG_84823_CTL_LED_CTL_1;
10747 
10748 	/* stretch_en for LED3*/
10749 	elink_cl45_read_or_write(sc, phy,
10750 				 MDIO_PMA_DEVAD, offset,
10751 				 MDIO_PMA_REG_84823_LED3_STRETCH_EN);
10752 }
10753 
elink_848xx_specific_func(struct elink_phy * phy,struct elink_params * params,uint32_t action)10754 static void elink_848xx_specific_func(struct elink_phy *phy,
10755 				      struct elink_params *params,
10756 				      uint32_t action)
10757 {
10758 	struct bnx2x_softc *sc = params->sc;
10759 	switch (action) {
10760 	case ELINK_PHY_INIT:
10761 		if (!elink_is_8483x_8485x(phy)) {
10762 			/* Save spirom version */
10763 			elink_save_848xx_spirom_version(phy, sc, params->port);
10764 		}
10765 		/* This phy uses the NIG latch mechanism since link indication
10766 		 * arrives through its LED4 and not via its LASI signal, so we
10767 		 * get steady signal instead of clear on read
10768 		 */
10769 		elink_bits_en(sc, NIG_REG_LATCH_BC_0 + params->port * 4,
10770 			      1 << ELINK_NIG_LATCH_BC_ENABLE_MI_INT);
10771 
10772 		elink_848xx_set_led(sc, phy);
10773 		break;
10774 	}
10775 }
10776 
elink_848xx_cmn_config_init(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)10777 static elink_status_t elink_848xx_cmn_config_init(struct elink_phy *phy,
10778 				       struct elink_params *params,
10779 				       struct elink_vars *vars)
10780 {
10781 	struct bnx2x_softc *sc = params->sc;
10782 	uint16_t autoneg_val, an_1000_val, an_10_100_val;
10783 
10784 	elink_848xx_specific_func(phy, params, ELINK_PHY_INIT);
10785 	elink_cl45_write(sc, phy,
10786 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
10787 
10788 	/* set 1000 speed advertisement */
10789 	elink_cl45_read(sc, phy,
10790 			MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
10791 			&an_1000_val);
10792 
10793 	elink_ext_phy_set_pause(params, phy, vars);
10794 	elink_cl45_read(sc, phy,
10795 			MDIO_AN_DEVAD,
10796 			MDIO_AN_REG_8481_LEGACY_AN_ADV,
10797 			&an_10_100_val);
10798 	elink_cl45_read(sc, phy,
10799 			MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
10800 			&autoneg_val);
10801 	/* Disable forced speed */
10802 	autoneg_val &= ~((1 << 6) | (1 << 8) | (1 << 9) | (1 << 12) |
10803 			 (1 << 13));
10804 	an_10_100_val &= ~((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8));
10805 
10806 	if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10807 	     (phy->speed_cap_mask &
10808 	     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
10809 	    (phy->req_line_speed == ELINK_SPEED_1000)) {
10810 		an_1000_val |= (1 << 8);
10811 		autoneg_val |= (1 << 9 | 1 << 12);
10812 		if (phy->req_duplex == DUPLEX_FULL)
10813 			an_1000_val |= (1 << 9);
10814 		ELINK_DEBUG_P0(sc, "Advertising 1G");
10815 	} else
10816 		an_1000_val &= ~((1 << 8) | (1 << 9));
10817 
10818 	elink_cl45_write(sc, phy,
10819 			 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
10820 			 an_1000_val);
10821 
10822 	/* Set 10/100 speed advertisement */
10823 	if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
10824 		if (phy->speed_cap_mask &
10825 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
10826 			/* Enable autoneg and restart autoneg for legacy speeds
10827 			 */
10828 			autoneg_val |= (1 << 9 | 1 << 12);
10829 			an_10_100_val |= (1 << 8);
10830 			ELINK_DEBUG_P0(sc, "Advertising 100M-FD");
10831 		}
10832 
10833 		if (phy->speed_cap_mask &
10834 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
10835 			/* Enable autoneg and restart autoneg for legacy speeds
10836 			 */
10837 			autoneg_val |= (1 << 9 | 1 << 12);
10838 			an_10_100_val |= (1 << 7);
10839 			ELINK_DEBUG_P0(sc, "Advertising 100M-HD");
10840 		}
10841 
10842 		if ((phy->speed_cap_mask &
10843 		     PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
10844 		    (phy->supported & ELINK_SUPPORTED_10baseT_Full)) {
10845 			an_10_100_val |= (1 << 6);
10846 			autoneg_val |= (1 << 9 | 1 << 12);
10847 			ELINK_DEBUG_P0(sc, "Advertising 10M-FD");
10848 		}
10849 
10850 		if ((phy->speed_cap_mask &
10851 		     PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) &&
10852 		    (phy->supported & ELINK_SUPPORTED_10baseT_Half)) {
10853 			an_10_100_val |= (1 << 5);
10854 			autoneg_val |= (1 << 9 | 1 << 12);
10855 			ELINK_DEBUG_P0(sc, "Advertising 10M-HD");
10856 		}
10857 	}
10858 
10859 	/* Only 10/100 are allowed to work in FORCE mode */
10860 	if ((phy->req_line_speed == ELINK_SPEED_100) &&
10861 	    (phy->supported &
10862 	     (ELINK_SUPPORTED_100baseT_Half |
10863 	      ELINK_SUPPORTED_100baseT_Full))) {
10864 		autoneg_val |= (1 << 13);
10865 		/* Enabled AUTO-MDIX when autoneg is disabled */
10866 		elink_cl45_write(sc, phy,
10867 				 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
10868 				 (1 << 15 | 1 << 9 | 7 << 0));
10869 		/* The PHY needs this set even for forced link. */
10870 		an_10_100_val |= (1 << 8) | (1 << 7);
10871 		ELINK_DEBUG_P0(sc, "Setting 100M force");
10872 	}
10873 	if ((phy->req_line_speed == ELINK_SPEED_10) &&
10874 	    (phy->supported &
10875 	     (ELINK_SUPPORTED_10baseT_Half |
10876 	      ELINK_SUPPORTED_10baseT_Full))) {
10877 		/* Enabled AUTO-MDIX when autoneg is disabled */
10878 		elink_cl45_write(sc, phy,
10879 				 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
10880 				 (1 << 15 | 1 << 9 | 7 << 0));
10881 		ELINK_DEBUG_P0(sc, "Setting 10M force");
10882 	}
10883 
10884 	elink_cl45_write(sc, phy,
10885 			 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
10886 			 an_10_100_val);
10887 
10888 	if (phy->req_duplex == DUPLEX_FULL)
10889 		autoneg_val |= (1 << 8);
10890 
10891 	/* Always write this if this is not 84833/4.
10892 	 * For 84833/4, write it only when it's a forced speed.
10893 	 */
10894 	if (!elink_is_8483x_8485x(phy) ||
10895 	    ((autoneg_val & (1 << 12)) == 0))
10896 		elink_cl45_write(sc, phy,
10897 			 MDIO_AN_DEVAD,
10898 			 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
10899 
10900 	if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10901 	     (phy->speed_cap_mask &
10902 	      PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
10903 	    (phy->req_line_speed == ELINK_SPEED_10000)) {
10904 		ELINK_DEBUG_P0(sc, "Advertising 10G");
10905 		/* Restart autoneg for 10G*/
10906 
10907 		elink_cl45_read_or_write(
10908 			sc, phy,
10909 			MDIO_AN_DEVAD,
10910 			MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
10911 			0x1000);
10912 		elink_cl45_write(sc, phy,
10913 				 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
10914 				 0x3200);
10915 	} else
10916 		elink_cl45_write(sc, phy,
10917 				 MDIO_AN_DEVAD,
10918 				 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
10919 				 1);
10920 
10921 	return ELINK_STATUS_OK;
10922 }
10923 
elink_8481_config_init(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)10924 static uint8_t elink_8481_config_init(struct elink_phy *phy,
10925 				  struct elink_params *params,
10926 				  struct elink_vars *vars)
10927 {
10928 	struct bnx2x_softc *sc = params->sc;
10929 	/* Restore normal power mode*/
10930 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
10931 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
10932 
10933 	/* HW reset */
10934 	elink_ext_phy_hw_reset(sc, params->port);
10935 	elink_wait_reset_complete(sc, phy, params);
10936 
10937 	elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1 << 15);
10938 	return elink_848xx_cmn_config_init(phy, params, vars);
10939 }
10940 
10941 #define PHY848xx_CMDHDLR_WAIT 300
10942 #define PHY848xx_CMDHDLR_MAX_ARGS 5
10943 
elink_84858_cmd_hdlr(struct elink_phy * phy,struct elink_params * params,uint16_t fw_cmd,uint16_t cmd_args[],int argc)10944 static elink_status_t elink_84858_cmd_hdlr(struct elink_phy *phy,
10945 					   struct elink_params *params,
10946 					   uint16_t fw_cmd,
10947 					   uint16_t cmd_args[], int argc)
10948 {
10949 	int idx;
10950 	uint16_t val;
10951 	struct bnx2x_softc *sc = params->sc;
10952 
10953 	/* Step 1: Poll the STATUS register to see whether the previous command
10954 	 * is in progress or the system is busy (CMD_IN_PROGRESS or
10955 	 * SYSTEM_BUSY). If previous command is in progress or system is busy,
10956 	 * check again until the previous command finishes execution and the
10957 	 * system is available for taking command
10958 	 */
10959 
10960 	for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
10961 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10962 				MDIO_848xx_CMD_HDLR_STATUS, &val);
10963 		if ((val != PHY84858_STATUS_CMD_IN_PROGRESS) &&
10964 		    (val != PHY84858_STATUS_CMD_SYSTEM_BUSY))
10965 			break;
10966 		DELAY(1000 * 1);
10967 	}
10968 	if (idx >= PHY848xx_CMDHDLR_WAIT) {
10969 		ELINK_DEBUG_P0(sc, "FW cmd: FW not ready.");
10970 		return ELINK_STATUS_ERROR;
10971 	}
10972 
10973 	/* Step2: If any parameters are required for the function, write them
10974 	 * to the required DATA registers
10975 	 */
10976 
10977 	for (idx = 0; idx < argc; idx++) {
10978 		elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10979 				 MDIO_848xx_CMD_HDLR_DATA1 + idx,
10980 				 cmd_args[idx]);
10981 	}
10982 
10983 	/* Step3: When the firmware is ready for commands, write the 'Command
10984 	 * code' to the CMD register
10985 	 */
10986 	elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10987 			 MDIO_848xx_CMD_HDLR_COMMAND, fw_cmd);
10988 
10989 	/* Step4: Once the command has been written, poll the STATUS register
10990 	 * to check whether the command has completed (CMD_COMPLETED_PASS/
10991 	 * CMD_FOR_CMDS or CMD_COMPLETED_ERROR).
10992 	 */
10993 
10994 	for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
10995 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10996 				MDIO_848xx_CMD_HDLR_STATUS, &val);
10997 		if ((val == PHY84858_STATUS_CMD_COMPLETE_PASS) ||
10998 		    (val == PHY84858_STATUS_CMD_COMPLETE_ERROR))
10999 			break;
11000 		DELAY(1000 * 1);
11001 	}
11002 	if ((idx >= PHY848xx_CMDHDLR_WAIT) ||
11003 	    (val == PHY84858_STATUS_CMD_COMPLETE_ERROR)) {
11004 		ELINK_DEBUG_P0(sc, "FW cmd failed.");
11005 		return ELINK_STATUS_ERROR;
11006 	}
11007 	/* Step5: Once the command has completed, read the specified DATA
11008 	 * registers for any saved results for the command, if applicable
11009 	 */
11010 
11011 	/* Gather returning data */
11012 	for (idx = 0; idx < argc; idx++) {
11013 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11014 				MDIO_848xx_CMD_HDLR_DATA1 + idx,
11015 				&cmd_args[idx]);
11016 	}
11017 
11018 	return ELINK_STATUS_OK;
11019 }
11020 
elink_84833_cmd_hdlr(struct elink_phy * phy,struct elink_params * params,uint16_t fw_cmd,uint16_t cmd_args[],int argc,int process)11021 static elink_status_t elink_84833_cmd_hdlr(struct elink_phy *phy,
11022 				struct elink_params *params, uint16_t fw_cmd,
11023 				uint16_t cmd_args[], int argc, int process)
11024 {
11025 	int idx;
11026 	uint16_t val;
11027 	struct bnx2x_softc *sc = params->sc;
11028 	elink_status_t rc = ELINK_STATUS_OK;
11029 
11030 	if (process == PHY84833_MB_PROCESS2) {
11031 	/* Write CMD_OPEN_OVERRIDE to STATUS reg */
11032 	elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11033 				 MDIO_848xx_CMD_HDLR_STATUS,
11034 			PHY84833_STATUS_CMD_OPEN_OVERRIDE);
11035 	}
11036 
11037 	for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
11038 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11039 			       MDIO_848xx_CMD_HDLR_STATUS, &val);
11040 		if (val == PHY84833_STATUS_CMD_OPEN_FOR_CMDS)
11041 			break;
11042 		DELAY(1000 * 1);
11043 	}
11044 	if (idx >= PHY848xx_CMDHDLR_WAIT) {
11045 		ELINK_DEBUG_P0(sc, "FW cmd: FW not ready.");
11046 		/* if the status is CMD_COMPLETE_PASS or CMD_COMPLETE_ERROR
11047 		 * clear the status to CMD_CLEAR_COMPLETE
11048 		 */
11049 		if (val == PHY84833_STATUS_CMD_COMPLETE_PASS ||
11050 		    val == PHY84833_STATUS_CMD_COMPLETE_ERROR) {
11051 			elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11052 					 MDIO_848xx_CMD_HDLR_STATUS,
11053 					 PHY84833_STATUS_CMD_CLEAR_COMPLETE);
11054 		}
11055 		return ELINK_STATUS_ERROR;
11056 	}
11057 	if (process == PHY84833_MB_PROCESS1 ||
11058 	    process == PHY84833_MB_PROCESS2) {
11059 		/* Prepare argument(s) */
11060 	for (idx = 0; idx < argc; idx++) {
11061 		elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11062 					 MDIO_848xx_CMD_HDLR_DATA1 + idx,
11063 				cmd_args[idx]);
11064 	}
11065 	}
11066 
11067 	/* Issue command */
11068 	elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11069 			MDIO_848xx_CMD_HDLR_COMMAND, fw_cmd);
11070 	for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
11071 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11072 			       MDIO_848xx_CMD_HDLR_STATUS, &val);
11073 		if ((val == PHY84833_STATUS_CMD_COMPLETE_PASS) ||
11074 			(val == PHY84833_STATUS_CMD_COMPLETE_ERROR))
11075 			break;
11076 		DELAY(1000 * 1);
11077 	}
11078 	if ((idx >= PHY848xx_CMDHDLR_WAIT) ||
11079 		(val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) {
11080 		ELINK_DEBUG_P0(sc, "FW cmd failed.");
11081 		rc = ELINK_STATUS_ERROR;
11082 	}
11083 	if (process == PHY84833_MB_PROCESS3 && rc == ELINK_STATUS_OK) {
11084 	/* Gather returning data */
11085 	for (idx = 0; idx < argc; idx++) {
11086 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11087 					MDIO_848xx_CMD_HDLR_DATA1 + idx,
11088 				&cmd_args[idx]);
11089 	}
11090 	}
11091 	if (val == PHY84833_STATUS_CMD_COMPLETE_ERROR ||
11092 	    val == PHY84833_STATUS_CMD_COMPLETE_PASS) {
11093 	elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11094 				 MDIO_848xx_CMD_HDLR_STATUS,
11095 			PHY84833_STATUS_CMD_CLEAR_COMPLETE);
11096 	}
11097 	return rc;
11098 }
11099 
elink_848xx_cmd_hdlr(struct elink_phy * phy,struct elink_params * params,uint16_t fw_cmd,uint16_t cmd_args[],int argc,int process)11100 static elink_status_t elink_848xx_cmd_hdlr(struct elink_phy *phy,
11101 					   struct elink_params *params,
11102 					   uint16_t fw_cmd,
11103 					   uint16_t cmd_args[], int argc,
11104 					   int process)
11105 {
11106 	struct bnx2x_softc *sc = params->sc;
11107 
11108 	if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858) ||
11109 	    (REG_RD(sc, params->shmem2_base +
11110 		    offsetof(struct shmem2_region,
11111 			     link_attr_sync[params->port])) &
11112 			     LINK_ATTR_84858)) {
11113 		return elink_84858_cmd_hdlr(phy, params, fw_cmd, cmd_args,
11114 					    argc);
11115 	} else {
11116 		return elink_84833_cmd_hdlr(phy, params, fw_cmd, cmd_args,
11117 					    argc, process);
11118 	}
11119 }
11120 
elink_848xx_pair_swap_cfg(struct elink_phy * phy,struct elink_params * params,__rte_unused struct elink_vars * vars)11121 static elink_status_t elink_848xx_pair_swap_cfg(struct elink_phy *phy,
11122 				   struct elink_params *params,
11123 				   __rte_unused struct elink_vars *vars)
11124 {
11125 	uint32_t pair_swap;
11126 	uint16_t data[PHY848xx_CMDHDLR_MAX_ARGS];
11127 	elink_status_t status;
11128 	struct bnx2x_softc *sc = params->sc;
11129 
11130 	/* Check for configuration. */
11131 	pair_swap = REG_RD(sc, params->shmem_base +
11132 			   offsetof(struct shmem_region,
11133 			dev_info.port_hw_config[params->port].xgbt_phy_cfg)) &
11134 		PORT_HW_CFG_RJ45_PAIR_SWAP_MASK;
11135 
11136 	if (pair_swap == 0)
11137 		return ELINK_STATUS_OK;
11138 
11139 	/* Only the second argument is used for this command */
11140 	data[1] = (uint16_t)pair_swap;
11141 
11142 	status = elink_848xx_cmd_hdlr(phy, params,
11143 				      PHY848xx_CMD_SET_PAIR_SWAP, data,
11144 				      2, PHY84833_MB_PROCESS2);
11145 	if (status == ELINK_STATUS_OK)
11146 		ELINK_DEBUG_P1(sc, "Pairswap OK, val=0x%x", data[1]);
11147 
11148 	return status;
11149 }
11150 
elink_84833_get_reset_gpios(struct bnx2x_softc * sc,uint32_t shmem_base_path[],__rte_unused uint32_t chip_id)11151 static uint8_t elink_84833_get_reset_gpios(struct bnx2x_softc *sc,
11152 				      uint32_t shmem_base_path[],
11153 				      __rte_unused uint32_t chip_id)
11154 {
11155 	uint32_t reset_pin[2];
11156 	uint32_t idx;
11157 	uint8_t reset_gpios;
11158 	if (CHIP_IS_E3(sc)) {
11159 		/* Assume that these will be GPIOs, not EPIOs. */
11160 		for (idx = 0; idx < 2; idx++) {
11161 			/* Map config param to register bit. */
11162 			reset_pin[idx] = REG_RD(sc, shmem_base_path[idx] +
11163 				offsetof(struct shmem_region,
11164 				dev_info.port_hw_config[0].e3_cmn_pin_cfg));
11165 			reset_pin[idx] = (reset_pin[idx] &
11166 				PORT_HW_CFG_E3_PHY_RESET_MASK) >>
11167 				PORT_HW_CFG_E3_PHY_RESET_SHIFT;
11168 			reset_pin[idx] -= PIN_CFG_GPIO0_P0;
11169 			reset_pin[idx] = (1 << reset_pin[idx]);
11170 		}
11171 		reset_gpios = (uint8_t)(reset_pin[0] | reset_pin[1]);
11172 	} else {
11173 		/* E2, look from diff place of shmem. */
11174 		for (idx = 0; idx < 2; idx++) {
11175 			reset_pin[idx] = REG_RD(sc, shmem_base_path[idx] +
11176 				offsetof(struct shmem_region,
11177 				dev_info.port_hw_config[0].default_cfg));
11178 			reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK;
11179 			reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0;
11180 			reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT;
11181 			reset_pin[idx] = (1 << reset_pin[idx]);
11182 		}
11183 		reset_gpios = (uint8_t)(reset_pin[0] | reset_pin[1]);
11184 	}
11185 
11186 	return reset_gpios;
11187 }
11188 
elink_84833_hw_reset_phy(struct elink_phy * phy,struct elink_params * params)11189 static void elink_84833_hw_reset_phy(struct elink_phy *phy,
11190 				struct elink_params *params)
11191 {
11192 	struct bnx2x_softc *sc = params->sc;
11193 	uint8_t reset_gpios;
11194 	uint32_t other_shmem_base_addr = REG_RD(sc, params->shmem2_base +
11195 				offsetof(struct shmem2_region,
11196 				other_shmem_base_addr));
11197 
11198 	uint32_t shmem_base_path[2];
11199 
11200 	/* Work around for 84833 LED failure inside RESET status */
11201 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
11202 		MDIO_AN_REG_8481_LEGACY_MII_CTRL,
11203 		MDIO_AN_REG_8481_MII_CTRL_FORCE_1G);
11204 	elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
11205 		MDIO_AN_REG_8481_1G_100T_EXT_CTRL,
11206 		MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF);
11207 
11208 	shmem_base_path[0] = params->shmem_base;
11209 	shmem_base_path[1] = other_shmem_base_addr;
11210 
11211 	reset_gpios = elink_84833_get_reset_gpios(sc, shmem_base_path,
11212 						  params->chip_id);
11213 
11214 	elink_cb_gpio_mult_write(sc, reset_gpios,
11215 				 MISC_REGISTERS_GPIO_OUTPUT_LOW);
11216 	DELAY(10);
11217 	ELINK_DEBUG_P1(sc, "84833 hw reset on pin values 0x%x",
11218 		reset_gpios);
11219 }
11220 
elink_8483x_disable_eee(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)11221 static elink_status_t elink_8483x_disable_eee(struct elink_phy *phy,
11222 				   struct elink_params *params,
11223 				   struct elink_vars *vars)
11224 {
11225 	elink_status_t rc;
11226 	struct bnx2x_softc *sc = params->sc;
11227 	uint16_t cmd_args = 0;
11228 
11229 	ELINK_DEBUG_P0(sc, "Don't Advertise 10GBase-T EEE");
11230 
11231 	/* Prevent Phy from working in EEE and advertising it */
11232 	rc = elink_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE,
11233 				  &cmd_args, 1, PHY84833_MB_PROCESS1);
11234 	if (rc != ELINK_STATUS_OK) {
11235 		ELINK_DEBUG_P0(sc, "EEE disable failed.");
11236 		return rc;
11237 	}
11238 
11239 	return elink_eee_disable(phy, params, vars);
11240 }
11241 
elink_8483x_enable_eee(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)11242 static elink_status_t elink_8483x_enable_eee(struct elink_phy *phy,
11243 				   struct elink_params *params,
11244 				   struct elink_vars *vars)
11245 {
11246 	elink_status_t rc;
11247 	struct bnx2x_softc *sc = params->sc;
11248 	uint16_t cmd_args = 1;
11249 
11250 	rc = elink_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE,
11251 				  &cmd_args, 1, PHY84833_MB_PROCESS1);
11252 	if (rc != ELINK_STATUS_OK) {
11253 		ELINK_DEBUG_P0(sc, "EEE enable failed.");
11254 		return rc;
11255 	}
11256 
11257 	return elink_eee_advertise(phy, params, vars, SHMEM_EEE_10G_ADV);
11258 }
11259 
11260 #define PHY84833_CONSTANT_LATENCY 1193
elink_848x3_config_init(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)11261 static uint8_t elink_848x3_config_init(struct elink_phy *phy,
11262 				   struct elink_params *params,
11263 				   struct elink_vars *vars)
11264 {
11265 	struct bnx2x_softc *sc = params->sc;
11266 	uint8_t port, initialize = 1;
11267 	uint16_t val;
11268 	uint32_t actual_phy_selection;
11269 	uint16_t cmd_args[PHY848xx_CMDHDLR_MAX_ARGS];
11270 	elink_status_t rc = ELINK_STATUS_OK;
11271 
11272 	DELAY(1000 * 1);
11273 
11274 	if (!(CHIP_IS_E1x(sc)))
11275 		port = SC_PATH(sc);
11276 	else
11277 		port = params->port;
11278 
11279 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823) {
11280 		elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_3,
11281 			       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
11282 			       port);
11283 	} else {
11284 		/* MDIO reset */
11285 		elink_cl45_write(sc, phy,
11286 				MDIO_PMA_DEVAD,
11287 				MDIO_PMA_REG_CTRL, 0x8000);
11288 	}
11289 
11290 	elink_wait_reset_complete(sc, phy, params);
11291 
11292 	/* Wait for GPHY to come out of reset */
11293 	DELAY(1000 * 50);
11294 	if (!elink_is_8483x_8485x(phy)) {
11295 		/* BNX2X84823 requires that XGXS links up first @ 10G for normal
11296 		 * behavior.
11297 		 */
11298 		uint16_t temp;
11299 		temp = vars->line_speed;
11300 		vars->line_speed = ELINK_SPEED_10000;
11301 		elink_set_autoneg(&params->phy[ELINK_INT_PHY], params, vars, 0);
11302 		elink_program_serdes(&params->phy[ELINK_INT_PHY], params, vars);
11303 		vars->line_speed = temp;
11304 	}
11305 	/* Check if this is actually BNX2X84858 */
11306 	if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858) {
11307 		uint16_t hw_rev;
11308 
11309 		elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11310 				MDIO_AN_REG_848xx_ID_MSB, &hw_rev);
11311 		if (hw_rev == BNX2X84858_PHY_ID) {
11312 			params->link_attr_sync |= LINK_ATTR_84858;
11313 			elink_update_link_attr(params, params->link_attr_sync);
11314 		}
11315 	}
11316 
11317 	/* Set dual-media configuration according to configuration */
11318 	elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11319 			MDIO_CTL_REG_84823_MEDIA, &val);
11320 	val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
11321 		 MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
11322 		 MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
11323 		 MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
11324 		 MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
11325 
11326 	if (CHIP_IS_E3(sc)) {
11327 		val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
11328 			 MDIO_CTL_REG_84823_MEDIA_LINE_MASK);
11329 	} else {
11330 		val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI |
11331 			MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L);
11332 	}
11333 
11334 	actual_phy_selection = elink_phy_selection(params);
11335 
11336 	switch (actual_phy_selection) {
11337 	case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
11338 		/* Do nothing. Essentially this is like the priority copper */
11339 		break;
11340 	case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
11341 		val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
11342 		break;
11343 	case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
11344 		val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
11345 		break;
11346 	case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
11347 		/* Do nothing here. The first PHY won't be initialized at all */
11348 		break;
11349 	case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
11350 		val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
11351 		initialize = 0;
11352 		break;
11353 	}
11354 	if (params->phy[ELINK_EXT_PHY2].req_line_speed == ELINK_SPEED_1000)
11355 		val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
11356 
11357 	elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11358 			 MDIO_CTL_REG_84823_MEDIA, val);
11359 	ELINK_DEBUG_P2(sc, "Multi_phy config = 0x%x, Media control = 0x%x",
11360 		   params->multi_phy_config, val);
11361 
11362 	if (elink_is_8483x_8485x(phy)) {
11363 		elink_848xx_pair_swap_cfg(phy, params, vars);
11364 
11365 		/* Keep AutogrEEEn disabled. */
11366 		cmd_args[0] = 0x0;
11367 		cmd_args[1] = 0x0;
11368 		cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1;
11369 		cmd_args[3] = PHY84833_CONSTANT_LATENCY;
11370 		rc = elink_848xx_cmd_hdlr(phy, params,
11371 					  PHY848xx_CMD_SET_EEE_MODE, cmd_args,
11372 					  4, PHY84833_MB_PROCESS1);
11373 		if (rc != ELINK_STATUS_OK)
11374 			ELINK_DEBUG_P0(sc, "Cfg AutogrEEEn failed.");
11375 	}
11376 	if (initialize)
11377 		rc = elink_848xx_cmn_config_init(phy, params, vars);
11378 	else
11379 		elink_save_848xx_spirom_version(phy, sc, params->port);
11380 	/* 84833 PHY has a better feature and doesn't need to support this. */
11381 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823) {
11382 		uint32_t cms_enable = REG_RD(sc, params->shmem_base +
11383 			offsetof(struct shmem_region,
11384 			dev_info.port_hw_config[params->port].default_cfg)) &
11385 			PORT_HW_CFG_ENABLE_CMS_MASK;
11386 
11387 		elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11388 				MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
11389 		if (cms_enable)
11390 			val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
11391 		else
11392 			val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
11393 		elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11394 				 MDIO_CTL_REG_84823_USER_CTRL_REG, val);
11395 	}
11396 
11397 	elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11398 			MDIO_84833_TOP_CFG_FW_REV, &val);
11399 
11400 	/* Configure EEE support */
11401 	if ((val >= MDIO_84833_TOP_CFG_FW_EEE) &&
11402 	    (val != MDIO_84833_TOP_CFG_FW_NO_EEE) &&
11403 	    elink_eee_has_cap(params)) {
11404 		rc = elink_eee_initial_config(params, vars, SHMEM_EEE_10G_ADV);
11405 		if (rc != ELINK_STATUS_OK) {
11406 			ELINK_DEBUG_P0(sc, "Failed to configure EEE timers");
11407 			elink_8483x_disable_eee(phy, params, vars);
11408 			return rc;
11409 		}
11410 
11411 		if ((phy->req_duplex == DUPLEX_FULL) &&
11412 		    (params->eee_mode & ELINK_EEE_MODE_ADV_LPI) &&
11413 		    (elink_eee_calc_timer(params) ||
11414 		     !(params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)))
11415 			rc = elink_8483x_enable_eee(phy, params, vars);
11416 		else
11417 			rc = elink_8483x_disable_eee(phy, params, vars);
11418 		if (rc != ELINK_STATUS_OK) {
11419 			ELINK_DEBUG_P0(sc, "Failed to set EEE advertisement");
11420 			return rc;
11421 		}
11422 	} else {
11423 		vars->eee_status &= ~SHMEM_EEE_SUPPORTED_MASK;
11424 	}
11425 
11426 	if (elink_is_8483x_8485x(phy)) {
11427 		/* Bring PHY out of super isolate mode as the final step. */
11428 		elink_cl45_read_and_write(sc, phy,
11429 					  MDIO_CTL_DEVAD,
11430 					  MDIO_84833_TOP_CFG_XGPHY_STRAP1,
11431 					  (uint16_t)~MDIO_84833_SUPER_ISOLATE);
11432 	}
11433 	return rc;
11434 }
11435 
elink_848xx_read_status(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)11436 static uint8_t elink_848xx_read_status(struct elink_phy *phy,
11437 				  struct elink_params *params,
11438 				  struct elink_vars *vars)
11439 {
11440 	struct bnx2x_softc *sc = params->sc;
11441 	uint16_t val, val1, val2;
11442 	uint8_t link_up = 0;
11443 
11444 
11445 	/* Check 10G-BaseT link status */
11446 	/* Check PMD signal ok */
11447 	elink_cl45_read(sc, phy,
11448 			MDIO_AN_DEVAD, 0xFFFA, &val1);
11449 	elink_cl45_read(sc, phy,
11450 			MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
11451 			&val2);
11452 	ELINK_DEBUG_P1(sc, "BNX2X848xx: PMD_SIGNAL 1.a811 = 0x%x", val2);
11453 
11454 	/* Check link 10G */
11455 	if (val2 & (1 << 11)) {
11456 		vars->line_speed = ELINK_SPEED_10000;
11457 		vars->duplex = DUPLEX_FULL;
11458 		link_up = 1;
11459 		elink_ext_phy_10G_an_resolve(sc, phy, vars);
11460 	} else { /* Check Legacy speed link */
11461 		uint16_t legacy_status, legacy_speed;
11462 
11463 		/* Enable expansion register 0x42 (Operation mode status) */
11464 		elink_cl45_write(sc, phy,
11465 				 MDIO_AN_DEVAD,
11466 				 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
11467 
11468 		/* Get legacy speed operation status */
11469 		elink_cl45_read(sc, phy,
11470 				MDIO_AN_DEVAD,
11471 				MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
11472 				&legacy_status);
11473 
11474 		ELINK_DEBUG_P1(sc, "Legacy speed status = 0x%x",
11475 		   legacy_status);
11476 		link_up = ((legacy_status & (1 << 11)) == (1 << 11));
11477 		legacy_speed = (legacy_status & (3 << 9));
11478 		if (legacy_speed == (0 << 9))
11479 			vars->line_speed = ELINK_SPEED_10;
11480 		else if (legacy_speed == (1 << 9))
11481 			vars->line_speed = ELINK_SPEED_100;
11482 		else if (legacy_speed == (2 << 9))
11483 			vars->line_speed = ELINK_SPEED_1000;
11484 		else { /* Should not happen: Treat as link down */
11485 			vars->line_speed = 0;
11486 			link_up = 0;
11487 		}
11488 
11489 		if (params->feature_config_flags &
11490 			ELINK_FEATURE_CONFIG_IEEE_PHY_TEST) {
11491 			uint16_t mii_ctrl;
11492 
11493 			elink_cl45_read(sc, phy,
11494 					MDIO_AN_DEVAD,
11495 					MDIO_AN_REG_8481_LEGACY_MII_CTRL,
11496 					&mii_ctrl);
11497 			/* For IEEE testing, check for a fake link. */
11498 			link_up |= ((mii_ctrl & 0x3040) == 0x40);
11499 		}
11500 
11501 		if (link_up) {
11502 			if (legacy_status & (1 << 8))
11503 				vars->duplex = DUPLEX_FULL;
11504 			else
11505 				vars->duplex = DUPLEX_HALF;
11506 
11507 			ELINK_DEBUG_P2(sc,
11508 			   "Link is up in %dMbps, is_duplex_full= %d",
11509 			   vars->line_speed,
11510 			   (vars->duplex == DUPLEX_FULL));
11511 			/* Check legacy speed AN resolution */
11512 			elink_cl45_read(sc, phy,
11513 					MDIO_AN_DEVAD,
11514 					MDIO_AN_REG_8481_LEGACY_MII_STATUS,
11515 					&val);
11516 			if (val & (1 << 5))
11517 				vars->link_status |=
11518 					LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
11519 			elink_cl45_read(sc, phy,
11520 					MDIO_AN_DEVAD,
11521 					MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
11522 					&val);
11523 			if ((val & (1 << 0)) == 0)
11524 				vars->link_status |=
11525 					LINK_STATUS_PARALLEL_DETECTION_USED;
11526 		}
11527 	}
11528 	if (link_up) {
11529 		ELINK_DEBUG_P1(sc, "BNX2X848x3: link speed is %d",
11530 			   vars->line_speed);
11531 		elink_ext_phy_resolve_fc(phy, params, vars);
11532 
11533 		/* Read LP advertised speeds */
11534 		elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11535 				MDIO_AN_REG_CL37_FC_LP, &val);
11536 		if (val & (1 << 5))
11537 			vars->link_status |=
11538 				LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
11539 		if (val & (1 << 6))
11540 			vars->link_status |=
11541 				LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
11542 		if (val & (1 << 7))
11543 			vars->link_status |=
11544 				LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
11545 		if (val & (1 << 8))
11546 			vars->link_status |=
11547 				LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
11548 		if (val & (1 << 9))
11549 			vars->link_status |=
11550 				LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
11551 
11552 		elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11553 				MDIO_AN_REG_1000T_STATUS, &val);
11554 
11555 		if (val & (1 << 10))
11556 			vars->link_status |=
11557 				LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
11558 		if (val & (1 << 11))
11559 			vars->link_status |=
11560 				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
11561 
11562 		elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11563 				MDIO_AN_REG_MASTER_STATUS, &val);
11564 
11565 		if (val & (1 << 11))
11566 			vars->link_status |=
11567 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
11568 
11569 		/* Determine if EEE was negotiated */
11570 		if (elink_is_8483x_8485x(phy))
11571 			elink_eee_an_resolve(phy, params, vars);
11572 	}
11573 
11574 	return link_up;
11575 }
11576 
elink_848xx_format_ver(uint32_t raw_ver,uint8_t * str,uint16_t * len)11577 static elink_status_t elink_848xx_format_ver(uint32_t raw_ver, uint8_t *str,
11578 					     uint16_t *len)
11579 {
11580 	elink_status_t status = ELINK_STATUS_OK;
11581 	uint32_t spirom_ver;
11582 	spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
11583 	status = elink_format_ver(spirom_ver, str, len);
11584 	return status;
11585 }
11586 
elink_8481_hw_reset(__rte_unused struct elink_phy * phy,struct elink_params * params)11587 static void elink_8481_hw_reset(__rte_unused struct elink_phy *phy,
11588 				struct elink_params *params)
11589 {
11590 	elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
11591 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
11592 	elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
11593 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
11594 }
11595 
elink_8481_link_reset(struct elink_phy * phy,struct elink_params * params)11596 static void elink_8481_link_reset(struct elink_phy *phy,
11597 					struct elink_params *params)
11598 {
11599 	elink_cl45_write(params->sc, phy,
11600 			 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
11601 	elink_cl45_write(params->sc, phy,
11602 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
11603 }
11604 
elink_848x3_link_reset(struct elink_phy * phy,struct elink_params * params)11605 static void elink_848x3_link_reset(struct elink_phy *phy,
11606 				   struct elink_params *params)
11607 {
11608 	struct bnx2x_softc *sc = params->sc;
11609 	uint8_t port;
11610 	uint16_t val16;
11611 
11612 	if (!(CHIP_IS_E1x(sc)))
11613 		port = SC_PATH(sc);
11614 	else
11615 		port = params->port;
11616 
11617 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823) {
11618 		elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_3,
11619 			       MISC_REGISTERS_GPIO_OUTPUT_LOW,
11620 			       port);
11621 	} else {
11622 		elink_cl45_read(sc, phy,
11623 				MDIO_CTL_DEVAD,
11624 				MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val16);
11625 		val16 |= MDIO_84833_SUPER_ISOLATE;
11626 		elink_cl45_write(sc, phy,
11627 				 MDIO_CTL_DEVAD,
11628 				 MDIO_84833_TOP_CFG_XGPHY_STRAP1, val16);
11629 	}
11630 }
11631 
elink_848xx_set_link_led(struct elink_phy * phy,struct elink_params * params,uint8_t mode)11632 static void elink_848xx_set_link_led(struct elink_phy *phy,
11633 				     struct elink_params *params, uint8_t mode)
11634 {
11635 	struct bnx2x_softc *sc = params->sc;
11636 	uint16_t val;
11637 	uint8_t port;
11638 
11639 	if (!(CHIP_IS_E1x(sc)))
11640 		port = SC_PATH(sc);
11641 	else
11642 		port = params->port;
11643 	switch (mode) {
11644 	case ELINK_LED_MODE_OFF:
11645 
11646 		ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE OFF", port);
11647 
11648 		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11649 		    SHARED_HW_CFG_LED_EXTPHY1) {
11650 
11651 			/* Set LED masks */
11652 			elink_cl45_write(sc, phy,
11653 					MDIO_PMA_DEVAD,
11654 					MDIO_PMA_REG_8481_LED1_MASK,
11655 					0x0);
11656 
11657 			elink_cl45_write(sc, phy,
11658 					MDIO_PMA_DEVAD,
11659 					MDIO_PMA_REG_8481_LED2_MASK,
11660 					0x0);
11661 
11662 			elink_cl45_write(sc, phy,
11663 					MDIO_PMA_DEVAD,
11664 					MDIO_PMA_REG_8481_LED3_MASK,
11665 					0x0);
11666 
11667 			elink_cl45_write(sc, phy,
11668 					MDIO_PMA_DEVAD,
11669 					MDIO_PMA_REG_8481_LED5_MASK,
11670 					0x0);
11671 
11672 		} else {
11673 			elink_cl45_write(sc, phy,
11674 					 MDIO_PMA_DEVAD,
11675 					 MDIO_PMA_REG_8481_LED1_MASK,
11676 					 0x0);
11677 		}
11678 		break;
11679 	case ELINK_LED_MODE_FRONT_PANEL_OFF:
11680 
11681 		ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE FRONT PANEL OFF",
11682 		   port);
11683 
11684 		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11685 		    SHARED_HW_CFG_LED_EXTPHY1) {
11686 
11687 			/* Set LED masks */
11688 			elink_cl45_write(sc, phy,
11689 					 MDIO_PMA_DEVAD,
11690 					 MDIO_PMA_REG_8481_LED1_MASK,
11691 					 0x0);
11692 
11693 			elink_cl45_write(sc, phy,
11694 					 MDIO_PMA_DEVAD,
11695 					 MDIO_PMA_REG_8481_LED2_MASK,
11696 					 0x0);
11697 
11698 			elink_cl45_write(sc, phy,
11699 					 MDIO_PMA_DEVAD,
11700 					 MDIO_PMA_REG_8481_LED3_MASK,
11701 					 0x0);
11702 
11703 			elink_cl45_write(sc, phy,
11704 					 MDIO_PMA_DEVAD,
11705 					 MDIO_PMA_REG_8481_LED5_MASK,
11706 					 0x20);
11707 
11708 		} else {
11709 			elink_cl45_write(sc, phy,
11710 					 MDIO_PMA_DEVAD,
11711 					 MDIO_PMA_REG_8481_LED1_MASK,
11712 					 0x0);
11713 			if (phy->type ==
11714 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834) {
11715 				/* Disable MI_INT interrupt before setting LED4
11716 				 * source to constant off.
11717 				 */
11718 				if (REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
11719 					   params->port * 4) &
11720 				    ELINK_NIG_MASK_MI_INT) {
11721 					params->link_flags |=
11722 					ELINK_LINK_FLAGS_INT_DISABLED;
11723 
11724 					elink_bits_dis(
11725 						sc,
11726 						NIG_REG_MASK_INTERRUPT_PORT0 +
11727 						params->port * 4,
11728 						ELINK_NIG_MASK_MI_INT);
11729 				}
11730 				elink_cl45_write(sc, phy,
11731 						 MDIO_PMA_DEVAD,
11732 						 MDIO_PMA_REG_8481_SIGNAL_MASK,
11733 						 0x0);
11734 			}
11735 		}
11736 		break;
11737 	case ELINK_LED_MODE_ON:
11738 
11739 		ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE ON", port);
11740 
11741 		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11742 		    SHARED_HW_CFG_LED_EXTPHY1) {
11743 			/* Set control reg */
11744 			elink_cl45_read(sc, phy,
11745 					MDIO_PMA_DEVAD,
11746 					MDIO_PMA_REG_8481_LINK_SIGNAL,
11747 					&val);
11748 			val &= 0x8000;
11749 			val |= 0x2492;
11750 
11751 			elink_cl45_write(sc, phy,
11752 					 MDIO_PMA_DEVAD,
11753 					 MDIO_PMA_REG_8481_LINK_SIGNAL,
11754 					 val);
11755 
11756 			/* Set LED masks */
11757 			elink_cl45_write(sc, phy,
11758 					 MDIO_PMA_DEVAD,
11759 					 MDIO_PMA_REG_8481_LED1_MASK,
11760 					 0x0);
11761 
11762 			elink_cl45_write(sc, phy,
11763 					 MDIO_PMA_DEVAD,
11764 					 MDIO_PMA_REG_8481_LED2_MASK,
11765 					 0x20);
11766 
11767 			elink_cl45_write(sc, phy,
11768 					 MDIO_PMA_DEVAD,
11769 					 MDIO_PMA_REG_8481_LED3_MASK,
11770 					 0x20);
11771 
11772 			elink_cl45_write(sc, phy,
11773 					 MDIO_PMA_DEVAD,
11774 					 MDIO_PMA_REG_8481_LED5_MASK,
11775 					 0x0);
11776 		} else {
11777 			elink_cl45_write(sc, phy,
11778 					 MDIO_PMA_DEVAD,
11779 					 MDIO_PMA_REG_8481_LED1_MASK,
11780 					 0x20);
11781 			if (phy->type ==
11782 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834) {
11783 				/* Disable MI_INT interrupt before setting LED4
11784 				 * source to constant on.
11785 				 */
11786 				if (REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
11787 					   params->port * 4) &
11788 				    ELINK_NIG_MASK_MI_INT) {
11789 					params->link_flags |=
11790 					ELINK_LINK_FLAGS_INT_DISABLED;
11791 
11792 					elink_bits_dis(
11793 						sc,
11794 						NIG_REG_MASK_INTERRUPT_PORT0 +
11795 						params->port * 4,
11796 						ELINK_NIG_MASK_MI_INT);
11797 				}
11798 				elink_cl45_write(sc, phy,
11799 						 MDIO_PMA_DEVAD,
11800 						 MDIO_PMA_REG_8481_SIGNAL_MASK,
11801 						 0x20);
11802 			}
11803 		}
11804 		break;
11805 
11806 	case ELINK_LED_MODE_OPER:
11807 
11808 		ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE OPER", port);
11809 
11810 		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11811 		    SHARED_HW_CFG_LED_EXTPHY1) {
11812 
11813 			/* Set control reg */
11814 			elink_cl45_read(sc, phy,
11815 					MDIO_PMA_DEVAD,
11816 					MDIO_PMA_REG_8481_LINK_SIGNAL,
11817 					&val);
11818 
11819 			if (!((val &
11820 			       MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
11821 			  >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
11822 				ELINK_DEBUG_P0(sc, "Setting LINK_SIGNAL");
11823 				elink_cl45_write(sc, phy,
11824 						 MDIO_PMA_DEVAD,
11825 						 MDIO_PMA_REG_8481_LINK_SIGNAL,
11826 						 0xa492);
11827 			}
11828 
11829 			/* Set LED masks */
11830 			elink_cl45_write(sc, phy,
11831 					 MDIO_PMA_DEVAD,
11832 					 MDIO_PMA_REG_8481_LED1_MASK,
11833 					 0x10);
11834 
11835 			elink_cl45_write(sc, phy,
11836 					 MDIO_PMA_DEVAD,
11837 					 MDIO_PMA_REG_8481_LED2_MASK,
11838 					 0x80);
11839 
11840 			elink_cl45_write(sc, phy,
11841 					 MDIO_PMA_DEVAD,
11842 					 MDIO_PMA_REG_8481_LED3_MASK,
11843 					 0x98);
11844 
11845 			elink_cl45_write(sc, phy,
11846 					 MDIO_PMA_DEVAD,
11847 					 MDIO_PMA_REG_8481_LED5_MASK,
11848 					 0x40);
11849 
11850 		} else {
11851 			/* EXTPHY2 LED mode indicate that the 100M/1G/10G LED
11852 			 * sources are all wired through LED1, rather than only
11853 			 * 10G in other modes.
11854 			 */
11855 			val = ((params->hw_led_mode <<
11856 				SHARED_HW_CFG_LED_MODE_SHIFT) ==
11857 			       SHARED_HW_CFG_LED_EXTPHY2) ? 0x98 : 0x80;
11858 
11859 			elink_cl45_write(sc, phy,
11860 					 MDIO_PMA_DEVAD,
11861 					 MDIO_PMA_REG_8481_LED1_MASK,
11862 					 val);
11863 
11864 			/* Tell LED3 to blink on source */
11865 			elink_cl45_read(sc, phy,
11866 					MDIO_PMA_DEVAD,
11867 					MDIO_PMA_REG_8481_LINK_SIGNAL,
11868 					&val);
11869 			val &= ~(7 << 6);
11870 			val |= (1 << 6); /* A83B[8:6]= 1 */
11871 			elink_cl45_write(sc, phy,
11872 					 MDIO_PMA_DEVAD,
11873 					 MDIO_PMA_REG_8481_LINK_SIGNAL,
11874 					 val);
11875 			if (phy->type ==
11876 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834) {
11877 				/* Restore LED4 source to external link,
11878 				 * and re-enable interrupts.
11879 				 */
11880 				elink_cl45_write(sc, phy,
11881 						 MDIO_PMA_DEVAD,
11882 						 MDIO_PMA_REG_8481_SIGNAL_MASK,
11883 						 0x40);
11884 				if (params->link_flags &
11885 				    ELINK_LINK_FLAGS_INT_DISABLED) {
11886 					elink_link_int_enable(params);
11887 					params->link_flags &=
11888 						~ELINK_LINK_FLAGS_INT_DISABLED;
11889 				}
11890 			}
11891 		}
11892 		break;
11893 	}
11894 
11895 	/* This is a workaround for E3 + 84833 until autoneg
11896 	 * restart is fixed in f/w
11897 	 */
11898 	if (CHIP_IS_E3(sc)) {
11899 		elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
11900 				MDIO_WC_REG_GP2_STATUS_GP_2_1, &val);
11901 	}
11902 }
11903 
11904 /******************************************************************/
11905 /*			54618SE PHY SECTION			  */
11906 /******************************************************************/
elink_54618se_specific_func(struct elink_phy * phy,struct elink_params * params,uint32_t action)11907 static void elink_54618se_specific_func(struct elink_phy *phy,
11908 					struct elink_params *params,
11909 					uint32_t action)
11910 {
11911 	struct bnx2x_softc *sc = params->sc;
11912 	uint16_t temp;
11913 	switch (action) {
11914 	case ELINK_PHY_INIT:
11915 		/* Configure LED4: set to INTR (0x6). */
11916 		/* Accessing shadow register 0xe. */
11917 		elink_cl22_write(sc, phy,
11918 				 MDIO_REG_GPHY_SHADOW,
11919 				 MDIO_REG_GPHY_SHADOW_LED_SEL2);
11920 		elink_cl22_read(sc, phy,
11921 				MDIO_REG_GPHY_SHADOW,
11922 				&temp);
11923 		temp &= ~(0xf << 4);
11924 		temp |= (0x6 << 4);
11925 		elink_cl22_write(sc, phy,
11926 				 MDIO_REG_GPHY_SHADOW,
11927 				 MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
11928 		/* Configure INTR based on link status change. */
11929 		elink_cl22_write(sc, phy,
11930 				 MDIO_REG_INTR_MASK,
11931 				 ~MDIO_REG_INTR_MASK_LINK_STATUS);
11932 		break;
11933 	}
11934 }
11935 
elink_54618se_config_init(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)11936 static uint8_t elink_54618se_config_init(struct elink_phy *phy,
11937 					       struct elink_params *params,
11938 					       struct elink_vars *vars)
11939 {
11940 	struct bnx2x_softc *sc = params->sc;
11941 	uint8_t port;
11942 	uint16_t autoneg_val, an_1000_val, an_10_100_val, fc_val, temp;
11943 	uint32_t cfg_pin;
11944 
11945 	ELINK_DEBUG_P0(sc, "54618SE cfg init");
11946 	DELAY(1000 * 1);
11947 
11948 	/* This works with E3 only, no need to check the chip
11949 	 * before determining the port.
11950 	 */
11951 	port = params->port;
11952 
11953 	cfg_pin = (REG_RD(sc, params->shmem_base +
11954 			offsetof(struct shmem_region,
11955 			dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
11956 			PORT_HW_CFG_E3_PHY_RESET_MASK) >>
11957 			PORT_HW_CFG_E3_PHY_RESET_SHIFT;
11958 
11959 	/* Drive pin high to bring the GPHY out of reset. */
11960 	elink_set_cfg_pin(sc, cfg_pin, 1);
11961 
11962 	/* wait for GPHY to reset */
11963 	DELAY(1000 * 50);
11964 
11965 	/* reset phy */
11966 	elink_cl22_write(sc, phy,
11967 			 MDIO_PMA_REG_CTRL, 0x8000);
11968 	elink_wait_reset_complete(sc, phy, params);
11969 
11970 	/* Wait for GPHY to reset */
11971 	DELAY(1000 * 50);
11972 
11973 
11974 	elink_54618se_specific_func(phy, params, ELINK_PHY_INIT);
11975 	/* Flip the signal detect polarity (set 0x1c.0x1e[8]). */
11976 	elink_cl22_write(sc, phy,
11977 			MDIO_REG_GPHY_SHADOW,
11978 			MDIO_REG_GPHY_SHADOW_AUTO_DET_MED);
11979 	elink_cl22_read(sc, phy,
11980 			MDIO_REG_GPHY_SHADOW,
11981 			&temp);
11982 	temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD;
11983 	elink_cl22_write(sc, phy,
11984 			MDIO_REG_GPHY_SHADOW,
11985 			MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
11986 
11987 	/* Set up fc */
11988 	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
11989 	elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
11990 	fc_val = 0;
11991 	if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
11992 			MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC)
11993 		fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
11994 
11995 	if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
11996 			MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
11997 		fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
11998 
11999 	/* Read all advertisement */
12000 	elink_cl22_read(sc, phy,
12001 			0x09,
12002 			&an_1000_val);
12003 
12004 	elink_cl22_read(sc, phy,
12005 			0x04,
12006 			&an_10_100_val);
12007 
12008 	elink_cl22_read(sc, phy,
12009 			MDIO_PMA_REG_CTRL,
12010 			&autoneg_val);
12011 
12012 	/* Disable forced speed */
12013 	autoneg_val &= ~((1 << 6) | (1 << 8) | (1 << 9) | (1 << 12) |
12014 			 (1 << 13));
12015 	an_10_100_val &= ~((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) |
12016 			   (1 << 10) | (1 << 11));
12017 
12018 	if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
12019 			(phy->speed_cap_mask &
12020 			PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
12021 			(phy->req_line_speed == ELINK_SPEED_1000)) {
12022 		an_1000_val |= (1 << 8);
12023 		autoneg_val |= (1 << 9 | 1 << 12);
12024 		if (phy->req_duplex == DUPLEX_FULL)
12025 			an_1000_val |= (1 << 9);
12026 		ELINK_DEBUG_P0(sc, "Advertising 1G");
12027 	} else
12028 		an_1000_val &= ~((1 << 8) | (1 << 9));
12029 
12030 	elink_cl22_write(sc, phy,
12031 			0x09,
12032 			an_1000_val);
12033 	elink_cl22_read(sc, phy,
12034 			0x09,
12035 			&an_1000_val);
12036 
12037 	/* Advertise 10/100 link speed */
12038 	if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
12039 		if (phy->speed_cap_mask &
12040 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) {
12041 			an_10_100_val |= (1 << 5);
12042 			autoneg_val |= (1 << 9 | 1 << 12);
12043 			ELINK_DEBUG_P0(sc, "Advertising 10M-HD");
12044 		}
12045 		if (phy->speed_cap_mask &
12046 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) {
12047 			an_10_100_val |= (1 << 6);
12048 			autoneg_val |= (1 << 9 | 1 << 12);
12049 			ELINK_DEBUG_P0(sc, "Advertising 10M-FD");
12050 		}
12051 		if (phy->speed_cap_mask &
12052 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
12053 			an_10_100_val |= (1 << 7);
12054 			autoneg_val |= (1 << 9 | 1 << 12);
12055 			ELINK_DEBUG_P0(sc, "Advertising 100M-HD");
12056 		}
12057 		if (phy->speed_cap_mask &
12058 		    PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
12059 			an_10_100_val |= (1 << 8);
12060 			autoneg_val |= (1 << 9 | 1 << 12);
12061 			ELINK_DEBUG_P0(sc, "Advertising 100M-FD");
12062 		}
12063 	}
12064 
12065 	/* Only 10/100 are allowed to work in FORCE mode */
12066 	if (phy->req_line_speed == ELINK_SPEED_100) {
12067 		autoneg_val |= (1 << 13);
12068 		/* Enabled AUTO-MDIX when autoneg is disabled */
12069 		elink_cl22_write(sc, phy,
12070 				0x18,
12071 				(1 << 15 | 1 << 9 | 7 << 0));
12072 		ELINK_DEBUG_P0(sc, "Setting 100M force");
12073 	}
12074 	if (phy->req_line_speed == ELINK_SPEED_10) {
12075 		/* Enabled AUTO-MDIX when autoneg is disabled */
12076 		elink_cl22_write(sc, phy,
12077 				0x18,
12078 				(1 << 15 | 1 << 9 | 7 << 0));
12079 		ELINK_DEBUG_P0(sc, "Setting 10M force");
12080 	}
12081 
12082 	if ((phy->flags & ELINK_FLAGS_EEE) && elink_eee_has_cap(params)) {
12083 		elink_status_t rc;
12084 
12085 		elink_cl22_write(sc, phy, MDIO_REG_GPHY_EXP_ACCESS,
12086 				 MDIO_REG_GPHY_EXP_ACCESS_TOP |
12087 				 MDIO_REG_GPHY_EXP_TOP_2K_BUF);
12088 		elink_cl22_read(sc, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, &temp);
12089 		temp &= 0xfffe;
12090 		elink_cl22_write(sc, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, temp);
12091 
12092 		rc = elink_eee_initial_config(params, vars, SHMEM_EEE_1G_ADV);
12093 		if (rc != ELINK_STATUS_OK) {
12094 			ELINK_DEBUG_P0(sc, "Failed to configure EEE timers");
12095 			elink_eee_disable(phy, params, vars);
12096 		} else if ((params->eee_mode & ELINK_EEE_MODE_ADV_LPI) &&
12097 			   (phy->req_duplex == DUPLEX_FULL) &&
12098 			   (elink_eee_calc_timer(params) ||
12099 			    !(params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI))) {
12100 			/* Need to advertise EEE only when requested,
12101 			 * and either no LPI assertion was requested,
12102 			 * or it was requested and a valid timer was set.
12103 			 * Also notice full duplex is required for EEE.
12104 			 */
12105 			elink_eee_advertise(phy, params, vars,
12106 					    SHMEM_EEE_1G_ADV);
12107 		} else {
12108 			ELINK_DEBUG_P0(sc, "Don't Advertise 1GBase-T EEE");
12109 			elink_eee_disable(phy, params, vars);
12110 		}
12111 	} else {
12112 		vars->eee_status &= ((uint32_t)(~SHMEM_EEE_1G_ADV) <<
12113 				    SHMEM_EEE_SUPPORTED_SHIFT);
12114 
12115 		if (phy->flags & ELINK_FLAGS_EEE) {
12116 			/* Handle legacy auto-grEEEn */
12117 			if (params->feature_config_flags &
12118 			    ELINK_FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
12119 				temp = 6;
12120 				ELINK_DEBUG_P0(sc, "Enabling Auto-GrEEEn");
12121 			} else {
12122 				temp = 0;
12123 				ELINK_DEBUG_P0(sc, "Don't Adv. EEE");
12124 			}
12125 			elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
12126 					 MDIO_AN_REG_EEE_ADV, temp);
12127 		}
12128 	}
12129 
12130 	elink_cl22_write(sc, phy,
12131 			0x04,
12132 			an_10_100_val | fc_val);
12133 
12134 	if (phy->req_duplex == DUPLEX_FULL)
12135 		autoneg_val |= (1 << 8);
12136 
12137 	elink_cl22_write(sc, phy,
12138 			MDIO_PMA_REG_CTRL, autoneg_val);
12139 
12140 	return ELINK_STATUS_OK;
12141 }
12142 
12143 
elink_5461x_set_link_led(struct elink_phy * phy,struct elink_params * params,uint8_t mode)12144 static void elink_5461x_set_link_led(struct elink_phy *phy,
12145 				     struct elink_params *params, uint8_t mode)
12146 {
12147 	struct bnx2x_softc *sc = params->sc;
12148 	uint16_t temp;
12149 
12150 	elink_cl22_write(sc, phy,
12151 		MDIO_REG_GPHY_SHADOW,
12152 		MDIO_REG_GPHY_SHADOW_LED_SEL1);
12153 	elink_cl22_read(sc, phy,
12154 		MDIO_REG_GPHY_SHADOW,
12155 		&temp);
12156 	temp &= 0xff00;
12157 
12158 	ELINK_DEBUG_P1(sc, "54618x set link led (mode=%x)", mode);
12159 	switch (mode) {
12160 	case ELINK_LED_MODE_FRONT_PANEL_OFF:
12161 	case ELINK_LED_MODE_OFF:
12162 		temp |= 0x00ee;
12163 		break;
12164 	case ELINK_LED_MODE_OPER:
12165 		temp |= 0x0001;
12166 		break;
12167 	case ELINK_LED_MODE_ON:
12168 		temp |= 0x00ff;
12169 		break;
12170 	default:
12171 		break;
12172 	}
12173 	elink_cl22_write(sc, phy,
12174 		MDIO_REG_GPHY_SHADOW,
12175 		MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
12176 	return;
12177 }
12178 
12179 
elink_54618se_link_reset(struct elink_phy * phy,struct elink_params * params)12180 static void elink_54618se_link_reset(struct elink_phy *phy,
12181 				     struct elink_params *params)
12182 {
12183 	struct bnx2x_softc *sc = params->sc;
12184 	uint32_t cfg_pin;
12185 	uint8_t port;
12186 
12187 	/* In case of no EPIO routed to reset the GPHY, put it
12188 	 * in low power mode.
12189 	 */
12190 	elink_cl22_write(sc, phy, MDIO_PMA_REG_CTRL, 0x800);
12191 	/* This works with E3 only, no need to check the chip
12192 	 * before determining the port.
12193 	 */
12194 	port = params->port;
12195 	cfg_pin = (REG_RD(sc, params->shmem_base +
12196 			offsetof(struct shmem_region,
12197 			dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
12198 			PORT_HW_CFG_E3_PHY_RESET_MASK) >>
12199 			PORT_HW_CFG_E3_PHY_RESET_SHIFT;
12200 
12201 	/* Drive pin low to put GPHY in reset. */
12202 	elink_set_cfg_pin(sc, cfg_pin, 0);
12203 }
12204 
elink_54618se_read_status(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)12205 static uint8_t elink_54618se_read_status(struct elink_phy *phy,
12206 				    struct elink_params *params,
12207 				    struct elink_vars *vars)
12208 {
12209 	struct bnx2x_softc *sc = params->sc;
12210 	uint16_t val;
12211 	uint8_t link_up = 0;
12212 	uint16_t legacy_status, legacy_speed;
12213 
12214 	/* Get speed operation status */
12215 	elink_cl22_read(sc, phy,
12216 			MDIO_REG_GPHY_AUX_STATUS,
12217 			&legacy_status);
12218 	ELINK_DEBUG_P1(sc, "54618SE read_status: 0x%x", legacy_status);
12219 
12220 	/* Read status to clear the PHY interrupt. */
12221 	elink_cl22_read(sc, phy,
12222 			MDIO_REG_INTR_STATUS,
12223 			&val);
12224 
12225 	link_up = ((legacy_status & (1 << 2)) == (1 << 2));
12226 
12227 	if (link_up) {
12228 		legacy_speed = (legacy_status & (7 << 8));
12229 		if (legacy_speed == (7 << 8)) {
12230 			vars->line_speed = ELINK_SPEED_1000;
12231 			vars->duplex = DUPLEX_FULL;
12232 		} else if (legacy_speed == (6 << 8)) {
12233 			vars->line_speed = ELINK_SPEED_1000;
12234 			vars->duplex = DUPLEX_HALF;
12235 		} else if (legacy_speed == (5 << 8)) {
12236 			vars->line_speed = ELINK_SPEED_100;
12237 			vars->duplex = DUPLEX_FULL;
12238 		}
12239 		/* Omitting 100Base-T4 for now */
12240 		else if (legacy_speed == (3 << 8)) {
12241 			vars->line_speed = ELINK_SPEED_100;
12242 			vars->duplex = DUPLEX_HALF;
12243 		} else if (legacy_speed == (2 << 8)) {
12244 			vars->line_speed = ELINK_SPEED_10;
12245 			vars->duplex = DUPLEX_FULL;
12246 		} else if (legacy_speed == (1 << 8)) {
12247 			vars->line_speed = ELINK_SPEED_10;
12248 			vars->duplex = DUPLEX_HALF;
12249 		} else /* Should not happen */
12250 			vars->line_speed = 0;
12251 
12252 		ELINK_DEBUG_P2(sc,
12253 		   "Link is up in %dMbps, is_duplex_full= %d",
12254 		   vars->line_speed,
12255 		   (vars->duplex == DUPLEX_FULL));
12256 
12257 		/* Check legacy speed AN resolution */
12258 		elink_cl22_read(sc, phy,
12259 				0x01,
12260 				&val);
12261 		if (val & (1 << 5))
12262 			vars->link_status |=
12263 				LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
12264 		elink_cl22_read(sc, phy,
12265 				0x06,
12266 				&val);
12267 		if ((val & (1 << 0)) == 0)
12268 			vars->link_status |=
12269 				LINK_STATUS_PARALLEL_DETECTION_USED;
12270 
12271 		ELINK_DEBUG_P1(sc, "BNX2X4618SE: link speed is %d",
12272 			   vars->line_speed);
12273 
12274 		elink_ext_phy_resolve_fc(phy, params, vars);
12275 
12276 		if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
12277 			/* Report LP advertised speeds */
12278 			elink_cl22_read(sc, phy, 0x5, &val);
12279 
12280 			if (val & (1 << 5))
12281 				vars->link_status |=
12282 				  LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
12283 			if (val & (1 << 6))
12284 				vars->link_status |=
12285 				  LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
12286 			if (val & (1 << 7))
12287 				vars->link_status |=
12288 				  LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
12289 			if (val & (1 << 8))
12290 				vars->link_status |=
12291 				  LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
12292 			if (val & (1 << 9))
12293 				vars->link_status |=
12294 				  LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
12295 
12296 			elink_cl22_read(sc, phy, 0xa, &val);
12297 			if (val & (1 << 10))
12298 				vars->link_status |=
12299 				  LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
12300 			if (val & (1 << 11))
12301 				vars->link_status |=
12302 				  LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
12303 
12304 			if ((phy->flags & ELINK_FLAGS_EEE) &&
12305 			    elink_eee_has_cap(params))
12306 				elink_eee_an_resolve(phy, params, vars);
12307 		}
12308 	}
12309 	return link_up;
12310 }
12311 
elink_54618se_config_loopback(struct elink_phy * phy,struct elink_params * params)12312 static void elink_54618se_config_loopback(struct elink_phy *phy,
12313 					  struct elink_params *params)
12314 {
12315 	struct bnx2x_softc *sc = params->sc;
12316 	uint16_t val;
12317 	uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
12318 
12319 	ELINK_DEBUG_P0(sc, "2PMA/PMD ext_phy_loopback: 54618se");
12320 
12321 	/* Enable master/slave manual mmode and set to master */
12322 	/* mii write 9 [bits set 11 12] */
12323 	elink_cl22_write(sc, phy, 0x09, 3 << 11);
12324 
12325 	/* forced 1G and disable autoneg */
12326 	/* set val [mii read 0] */
12327 	/* set val [expr $val & [bits clear 6 12 13]] */
12328 	/* set val [expr $val | [bits set 6 8]] */
12329 	/* mii write 0 $val */
12330 	elink_cl22_read(sc, phy, 0x00, &val);
12331 	val &= ~((1 << 6) | (1 << 12) | (1 << 13));
12332 	val |= (1 << 6) | (1 << 8);
12333 	elink_cl22_write(sc, phy, 0x00, val);
12334 
12335 	/* Set external loopback and Tx using 6dB coding */
12336 	/* mii write 0x18 7 */
12337 	/* set val [mii read 0x18] */
12338 	/* mii write 0x18 [expr $val | [bits set 10 15]] */
12339 	elink_cl22_write(sc, phy, 0x18, 7);
12340 	elink_cl22_read(sc, phy, 0x18, &val);
12341 	elink_cl22_write(sc, phy, 0x18, val | (1 << 10) | (1 << 15));
12342 
12343 	/* This register opens the gate for the UMAC despite its name */
12344 	REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port * 4, 1);
12345 
12346 	/* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
12347 	 * length used by the MAC receive logic to check frames.
12348 	 */
12349 	REG_WR(sc, umac_base + UMAC_REG_MAXFR, 0x2710);
12350 }
12351 
12352 /******************************************************************/
12353 /*			SFX7101 PHY SECTION			  */
12354 /******************************************************************/
elink_7101_config_loopback(struct elink_phy * phy,struct elink_params * params)12355 static void elink_7101_config_loopback(struct elink_phy *phy,
12356 				       struct elink_params *params)
12357 {
12358 	struct bnx2x_softc *sc = params->sc;
12359 	/* SFX7101_XGXS_TEST1 */
12360 	elink_cl45_write(sc, phy,
12361 			 MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
12362 }
12363 
elink_7101_config_init(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)12364 static uint8_t elink_7101_config_init(struct elink_phy *phy,
12365 				  struct elink_params *params,
12366 				  struct elink_vars *vars)
12367 {
12368 	uint16_t fw_ver1, fw_ver2, val;
12369 	struct bnx2x_softc *sc = params->sc;
12370 	ELINK_DEBUG_P0(sc, "Setting the SFX7101 LASI indication");
12371 
12372 	/* Restore normal power mode*/
12373 	elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
12374 		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
12375 	/* HW reset */
12376 	elink_ext_phy_hw_reset(sc, params->port);
12377 	elink_wait_reset_complete(sc, phy, params);
12378 
12379 	elink_cl45_write(sc, phy,
12380 			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x1);
12381 	ELINK_DEBUG_P0(sc, "Setting the SFX7101 LED to blink on traffic");
12382 	elink_cl45_write(sc, phy,
12383 			 MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1 << 3));
12384 
12385 	elink_ext_phy_set_pause(params, phy, vars);
12386 	/* Restart autoneg */
12387 	elink_cl45_read(sc, phy,
12388 			MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
12389 	val |= 0x200;
12390 	elink_cl45_write(sc, phy,
12391 			 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
12392 
12393 	/* Save spirom version */
12394 	elink_cl45_read(sc, phy,
12395 			MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
12396 
12397 	elink_cl45_read(sc, phy,
12398 			MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
12399 	elink_save_spirom_version(sc, params->port,
12400 				  (uint32_t)(fw_ver1 << 16 | fw_ver2),
12401 				  phy->ver_addr);
12402 	return ELINK_STATUS_OK;
12403 }
12404 
elink_7101_read_status(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)12405 static uint8_t elink_7101_read_status(struct elink_phy *phy,
12406 				 struct elink_params *params,
12407 				 struct elink_vars *vars)
12408 {
12409 	struct bnx2x_softc *sc = params->sc;
12410 	uint8_t link_up;
12411 	uint16_t val1, val2;
12412 	elink_cl45_read(sc, phy,
12413 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
12414 	elink_cl45_read(sc, phy,
12415 			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
12416 	ELINK_DEBUG_P2(sc, "10G-base-T LASI status 0x%x->0x%x",
12417 		   val2, val1);
12418 	elink_cl45_read(sc, phy,
12419 			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
12420 	elink_cl45_read(sc, phy,
12421 			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
12422 	ELINK_DEBUG_P2(sc, "10G-base-T PMA status 0x%x->0x%x",
12423 		   val2, val1);
12424 	link_up = ((val1 & 4) == 4);
12425 	/* If link is up print the AN outcome of the SFX7101 PHY */
12426 	if (link_up) {
12427 		elink_cl45_read(sc, phy,
12428 				MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
12429 				&val2);
12430 		vars->line_speed = ELINK_SPEED_10000;
12431 		vars->duplex = DUPLEX_FULL;
12432 		ELINK_DEBUG_P2(sc, "SFX7101 AN status 0x%x->Master=%x",
12433 			   val2, (val2 & (1 << 14)));
12434 		elink_ext_phy_10G_an_resolve(sc, phy, vars);
12435 		elink_ext_phy_resolve_fc(phy, params, vars);
12436 
12437 		/* Read LP advertised speeds */
12438 		if (val2 & (1 << 11))
12439 			vars->link_status |=
12440 				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
12441 	}
12442 	return link_up;
12443 }
12444 
elink_7101_format_ver(uint32_t spirom_ver,uint8_t * str,uint16_t * len)12445 static elink_status_t elink_7101_format_ver(uint32_t spirom_ver, uint8_t *str,
12446 					    uint16_t *len)
12447 {
12448 	if (*len < 5)
12449 		return ELINK_STATUS_ERROR;
12450 	str[0] = (spirom_ver & 0xFF);
12451 	str[1] = (spirom_ver & 0xFF00) >> 8;
12452 	str[2] = (spirom_ver & 0xFF0000) >> 16;
12453 	str[3] = (spirom_ver & 0xFF000000) >> 24;
12454 	str[4] = '\0';
12455 	*len -= 5;
12456 	return ELINK_STATUS_OK;
12457 }
12458 
elink_sfx7101_sp_sw_reset(struct bnx2x_softc * sc,struct elink_phy * phy)12459 void elink_sfx7101_sp_sw_reset(struct bnx2x_softc *sc, struct elink_phy *phy)
12460 {
12461 	uint16_t val, cnt;
12462 
12463 	elink_cl45_read(sc, phy,
12464 			MDIO_PMA_DEVAD,
12465 			MDIO_PMA_REG_7101_RESET, &val);
12466 
12467 	for (cnt = 0; cnt < 10; cnt++) {
12468 		DELAY(1000 * 50);
12469 		/* Writes a self-clearing reset */
12470 		elink_cl45_write(sc, phy,
12471 				 MDIO_PMA_DEVAD,
12472 				 MDIO_PMA_REG_7101_RESET,
12473 				 (val | (1 << 15)));
12474 		/* Wait for clear */
12475 		elink_cl45_read(sc, phy,
12476 				MDIO_PMA_DEVAD,
12477 				MDIO_PMA_REG_7101_RESET, &val);
12478 
12479 		if ((val & (1 << 15)) == 0)
12480 			break;
12481 	}
12482 }
12483 
elink_7101_hw_reset(__rte_unused struct elink_phy * phy,struct elink_params * params)12484 static void elink_7101_hw_reset(__rte_unused struct elink_phy *phy,
12485 				struct elink_params *params) {
12486 	/* Low power mode is controlled by GPIO 2 */
12487 	elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_2,
12488 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
12489 	/* The PHY reset is controlled by GPIO 1 */
12490 	elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
12491 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
12492 }
12493 
elink_7101_set_link_led(struct elink_phy * phy,struct elink_params * params,uint8_t mode)12494 static void elink_7101_set_link_led(struct elink_phy *phy,
12495 				    struct elink_params *params, uint8_t mode)
12496 {
12497 	uint16_t val = 0;
12498 	struct bnx2x_softc *sc = params->sc;
12499 	switch (mode) {
12500 	case ELINK_LED_MODE_FRONT_PANEL_OFF:
12501 	case ELINK_LED_MODE_OFF:
12502 		val = 2;
12503 		break;
12504 	case ELINK_LED_MODE_ON:
12505 		val = 1;
12506 		break;
12507 	case ELINK_LED_MODE_OPER:
12508 		val = 0;
12509 		break;
12510 	}
12511 	elink_cl45_write(sc, phy,
12512 			 MDIO_PMA_DEVAD,
12513 			 MDIO_PMA_REG_7107_LINK_LED_CNTL,
12514 			 val);
12515 }
12516 
12517 /******************************************************************/
12518 /*			STATIC PHY DECLARATION			  */
12519 /******************************************************************/
12520 
12521 static const struct elink_phy phy_null = {
12522 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
12523 	.addr		= 0,
12524 	.def_md_devad	= 0,
12525 	.flags		= ELINK_FLAGS_INIT_XGXS_FIRST,
12526 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12527 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12528 	.mdio_ctrl	= 0,
12529 	.supported	= 0,
12530 	.media_type	= ELINK_ETH_PHY_NOT_PRESENT,
12531 	.ver_addr	= 0,
12532 	.req_flow_ctrl	= 0,
12533 	.req_line_speed	= 0,
12534 	.speed_cap_mask	= 0,
12535 	.req_duplex	= 0,
12536 	.rsrv		= 0,
12537 	.config_init	= (config_init_t)NULL,
12538 	.read_status	= (read_status_t)NULL,
12539 	.link_reset	= (link_reset_t)NULL,
12540 	.config_loopback = (config_loopback_t)NULL,
12541 	.format_fw_ver	= (format_fw_ver_t)NULL,
12542 	.hw_reset	= (hw_reset_t)NULL,
12543 	.set_link_led	= (set_link_led_t)NULL,
12544 	.phy_specific_func = (phy_specific_func_t)NULL
12545 };
12546 
12547 static const struct elink_phy phy_serdes = {
12548 	.type		= PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
12549 	.addr		= 0xff,
12550 	.def_md_devad	= 0,
12551 	.flags		= 0,
12552 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12553 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12554 	.mdio_ctrl	= 0,
12555 	.supported	= (ELINK_SUPPORTED_10baseT_Half |
12556 			   ELINK_SUPPORTED_10baseT_Full |
12557 			   ELINK_SUPPORTED_100baseT_Half |
12558 			   ELINK_SUPPORTED_100baseT_Full |
12559 			   ELINK_SUPPORTED_1000baseT_Full |
12560 			   ELINK_SUPPORTED_2500baseX_Full |
12561 			   ELINK_SUPPORTED_TP |
12562 			   ELINK_SUPPORTED_Autoneg |
12563 			   ELINK_SUPPORTED_Pause |
12564 			   ELINK_SUPPORTED_Asym_Pause),
12565 	.media_type	= ELINK_ETH_PHY_BASE_T,
12566 	.ver_addr	= 0,
12567 	.req_flow_ctrl	= 0,
12568 	.req_line_speed	= 0,
12569 	.speed_cap_mask	= 0,
12570 	.req_duplex	= 0,
12571 	.rsrv		= 0,
12572 	.config_init	= (config_init_t)elink_xgxs_config_init,
12573 	.read_status	= (read_status_t)elink_link_settings_status,
12574 	.link_reset	= (link_reset_t)elink_int_link_reset,
12575 	.config_loopback = (config_loopback_t)NULL,
12576 	.format_fw_ver	= (format_fw_ver_t)NULL,
12577 	.hw_reset	= (hw_reset_t)NULL,
12578 	.set_link_led	= (set_link_led_t)NULL,
12579 	.phy_specific_func = (phy_specific_func_t)NULL
12580 };
12581 
12582 static const struct elink_phy phy_xgxs = {
12583 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
12584 	.addr		= 0xff,
12585 	.def_md_devad	= 0,
12586 	.flags		= 0,
12587 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12588 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12589 	.mdio_ctrl	= 0,
12590 	.supported	= (ELINK_SUPPORTED_10baseT_Half |
12591 			   ELINK_SUPPORTED_10baseT_Full |
12592 			   ELINK_SUPPORTED_100baseT_Half |
12593 			   ELINK_SUPPORTED_100baseT_Full |
12594 			   ELINK_SUPPORTED_1000baseT_Full |
12595 			   ELINK_SUPPORTED_2500baseX_Full |
12596 			   ELINK_SUPPORTED_10000baseT_Full |
12597 			   ELINK_SUPPORTED_FIBRE |
12598 			   ELINK_SUPPORTED_Autoneg |
12599 			   ELINK_SUPPORTED_Pause |
12600 			   ELINK_SUPPORTED_Asym_Pause),
12601 	.media_type	= ELINK_ETH_PHY_CX4,
12602 	.ver_addr	= 0,
12603 	.req_flow_ctrl	= 0,
12604 	.req_line_speed	= 0,
12605 	.speed_cap_mask	= 0,
12606 	.req_duplex	= 0,
12607 	.rsrv		= 0,
12608 	.config_init	= (config_init_t)elink_xgxs_config_init,
12609 	.read_status	= (read_status_t)elink_link_settings_status,
12610 	.link_reset	= (link_reset_t)elink_int_link_reset,
12611 	.config_loopback = (config_loopback_t)elink_set_xgxs_loopback,
12612 	.format_fw_ver	= (format_fw_ver_t)NULL,
12613 	.hw_reset	= (hw_reset_t)NULL,
12614 	.set_link_led	= (set_link_led_t)NULL,
12615 	.phy_specific_func = (phy_specific_func_t)elink_xgxs_specific_func
12616 };
12617 static const struct elink_phy phy_warpcore = {
12618 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
12619 	.addr		= 0xff,
12620 	.def_md_devad	= 0,
12621 	.flags		= ELINK_FLAGS_TX_ERROR_CHECK,
12622 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12623 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12624 	.mdio_ctrl	= 0,
12625 	.supported	= (ELINK_SUPPORTED_10baseT_Half |
12626 			   ELINK_SUPPORTED_10baseT_Full |
12627 			   ELINK_SUPPORTED_100baseT_Half |
12628 			   ELINK_SUPPORTED_100baseT_Full |
12629 			   ELINK_SUPPORTED_1000baseT_Full |
12630 			   ELINK_SUPPORTED_2500baseX_Full |
12631 			   ELINK_SUPPORTED_1000baseKX_Full |
12632 			   ELINK_SUPPORTED_10000baseT_Full |
12633 			   ELINK_SUPPORTED_10000baseKR_Full |
12634 			   ELINK_SUPPORTED_20000baseKR2_Full |
12635 			   ELINK_SUPPORTED_20000baseMLD2_Full |
12636 			   ELINK_SUPPORTED_FIBRE |
12637 			   ELINK_SUPPORTED_Autoneg |
12638 			   ELINK_SUPPORTED_Pause |
12639 			   ELINK_SUPPORTED_Asym_Pause),
12640 	.media_type	= ELINK_ETH_PHY_UNSPECIFIED,
12641 	.ver_addr	= 0,
12642 	.req_flow_ctrl	= 0,
12643 	.req_line_speed	= 0,
12644 	.speed_cap_mask	= 0,
12645 	/* req_duplex = */0,
12646 	/* rsrv = */0,
12647 	.config_init	= (config_init_t)elink_warpcore_config_init,
12648 	.read_status	= (read_status_t)elink_warpcore_read_status,
12649 	.link_reset	= (link_reset_t)elink_warpcore_link_reset,
12650 	.config_loopback = (config_loopback_t)elink_set_warpcore_loopback,
12651 	.format_fw_ver	= (format_fw_ver_t)NULL,
12652 	.hw_reset	= (hw_reset_t)elink_warpcore_hw_reset,
12653 	.set_link_led	= (set_link_led_t)NULL,
12654 	.phy_specific_func = (phy_specific_func_t)NULL
12655 };
12656 
12657 
12658 static const struct elink_phy phy_7101 = {
12659 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
12660 	.addr		= 0xff,
12661 	.def_md_devad	= 0,
12662 	.flags		= ELINK_FLAGS_FAN_FAILURE_DET_REQ,
12663 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12664 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12665 	.mdio_ctrl	= 0,
12666 	.supported	= (ELINK_SUPPORTED_10000baseT_Full |
12667 			   ELINK_SUPPORTED_TP |
12668 			   ELINK_SUPPORTED_Autoneg |
12669 			   ELINK_SUPPORTED_Pause |
12670 			   ELINK_SUPPORTED_Asym_Pause),
12671 	.media_type	= ELINK_ETH_PHY_BASE_T,
12672 	.ver_addr	= 0,
12673 	.req_flow_ctrl	= 0,
12674 	.req_line_speed	= 0,
12675 	.speed_cap_mask	= 0,
12676 	.req_duplex	= 0,
12677 	.rsrv		= 0,
12678 	.config_init	= (config_init_t)elink_7101_config_init,
12679 	.read_status	= (read_status_t)elink_7101_read_status,
12680 	.link_reset	= (link_reset_t)elink_common_ext_link_reset,
12681 	.config_loopback = (config_loopback_t)elink_7101_config_loopback,
12682 	.format_fw_ver	= (format_fw_ver_t)elink_7101_format_ver,
12683 	.hw_reset	= (hw_reset_t)elink_7101_hw_reset,
12684 	.set_link_led	= (set_link_led_t)elink_7101_set_link_led,
12685 	.phy_specific_func = (phy_specific_func_t)NULL
12686 };
12687 static const struct elink_phy phy_8073 = {
12688 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8073,
12689 	.addr		= 0xff,
12690 	.def_md_devad	= 0,
12691 	.flags		= 0,
12692 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12693 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12694 	.mdio_ctrl	= 0,
12695 	.supported	= (ELINK_SUPPORTED_10000baseT_Full |
12696 			   ELINK_SUPPORTED_2500baseX_Full |
12697 			   ELINK_SUPPORTED_1000baseT_Full |
12698 			   ELINK_SUPPORTED_FIBRE |
12699 			   ELINK_SUPPORTED_Autoneg |
12700 			   ELINK_SUPPORTED_Pause |
12701 			   ELINK_SUPPORTED_Asym_Pause),
12702 	.media_type	= ELINK_ETH_PHY_KR,
12703 	.ver_addr	= 0,
12704 	.req_flow_ctrl	= 0,
12705 	.req_line_speed	= 0,
12706 	.speed_cap_mask	= 0,
12707 	.req_duplex	= 0,
12708 	.rsrv		= 0,
12709 	.config_init	= (config_init_t)elink_8073_config_init,
12710 	.read_status	= (read_status_t)elink_8073_read_status,
12711 	.link_reset	= (link_reset_t)elink_8073_link_reset,
12712 	.config_loopback = (config_loopback_t)NULL,
12713 	.format_fw_ver	= (format_fw_ver_t)elink_format_ver,
12714 	.hw_reset	= (hw_reset_t)NULL,
12715 	.set_link_led	= (set_link_led_t)NULL,
12716 	.phy_specific_func = (phy_specific_func_t)elink_8073_specific_func
12717 };
12718 static const struct elink_phy phy_8705 = {
12719 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8705,
12720 	.addr		= 0xff,
12721 	.def_md_devad	= 0,
12722 	.flags		= ELINK_FLAGS_INIT_XGXS_FIRST,
12723 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12724 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12725 	.mdio_ctrl	= 0,
12726 	.supported	= (ELINK_SUPPORTED_10000baseT_Full |
12727 			   ELINK_SUPPORTED_FIBRE |
12728 			   ELINK_SUPPORTED_Pause |
12729 			   ELINK_SUPPORTED_Asym_Pause),
12730 	.media_type	= ELINK_ETH_PHY_XFP_FIBER,
12731 	.ver_addr	= 0,
12732 	.req_flow_ctrl	= 0,
12733 	.req_line_speed	= 0,
12734 	.speed_cap_mask	= 0,
12735 	.req_duplex	= 0,
12736 	.rsrv		= 0,
12737 	.config_init	= (config_init_t)elink_8705_config_init,
12738 	.read_status	= (read_status_t)elink_8705_read_status,
12739 	.link_reset	= (link_reset_t)elink_common_ext_link_reset,
12740 	.config_loopback = (config_loopback_t)NULL,
12741 	.format_fw_ver	= (format_fw_ver_t)elink_null_format_ver,
12742 	.hw_reset	= (hw_reset_t)NULL,
12743 	.set_link_led	= (set_link_led_t)NULL,
12744 	.phy_specific_func = (phy_specific_func_t)NULL
12745 };
12746 static const struct elink_phy phy_8706 = {
12747 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8706,
12748 	.addr		= 0xff,
12749 	.def_md_devad	= 0,
12750 	.flags		= ELINK_FLAGS_INIT_XGXS_FIRST,
12751 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12752 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12753 	.mdio_ctrl	= 0,
12754 	.supported	= (ELINK_SUPPORTED_10000baseT_Full |
12755 			   ELINK_SUPPORTED_1000baseT_Full |
12756 			   ELINK_SUPPORTED_FIBRE |
12757 			   ELINK_SUPPORTED_Pause |
12758 			   ELINK_SUPPORTED_Asym_Pause),
12759 	.media_type	= ELINK_ETH_PHY_SFPP_10G_FIBER,
12760 	.ver_addr	= 0,
12761 	.req_flow_ctrl	= 0,
12762 	.req_line_speed	= 0,
12763 	.speed_cap_mask	= 0,
12764 	.req_duplex	= 0,
12765 	.rsrv		= 0,
12766 	.config_init	= (config_init_t)elink_8706_config_init,
12767 	.read_status	= (read_status_t)elink_8706_read_status,
12768 	.link_reset	= (link_reset_t)elink_common_ext_link_reset,
12769 	.config_loopback = (config_loopback_t)NULL,
12770 	.format_fw_ver	= (format_fw_ver_t)elink_format_ver,
12771 	.hw_reset	= (hw_reset_t)NULL,
12772 	.set_link_led	= (set_link_led_t)NULL,
12773 	.phy_specific_func = (phy_specific_func_t)NULL
12774 };
12775 
12776 static const struct elink_phy phy_8726 = {
12777 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726,
12778 	.addr		= 0xff,
12779 	.def_md_devad	= 0,
12780 	.flags		= (ELINK_FLAGS_INIT_XGXS_FIRST |
12781 			   ELINK_FLAGS_TX_ERROR_CHECK),
12782 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12783 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12784 	.mdio_ctrl	= 0,
12785 	.supported	= (ELINK_SUPPORTED_10000baseT_Full |
12786 			   ELINK_SUPPORTED_1000baseT_Full |
12787 			   ELINK_SUPPORTED_Autoneg |
12788 			   ELINK_SUPPORTED_FIBRE |
12789 			   ELINK_SUPPORTED_Pause |
12790 			   ELINK_SUPPORTED_Asym_Pause),
12791 	.media_type	= ELINK_ETH_PHY_NOT_PRESENT,
12792 	.ver_addr	= 0,
12793 	.req_flow_ctrl	= 0,
12794 	.req_line_speed	= 0,
12795 	.speed_cap_mask	= 0,
12796 	.req_duplex	= 0,
12797 	.rsrv		= 0,
12798 	.config_init	= (config_init_t)elink_8726_config_init,
12799 	.read_status	= (read_status_t)elink_8726_read_status,
12800 	.link_reset	= (link_reset_t)elink_8726_link_reset,
12801 	.config_loopback = (config_loopback_t)elink_8726_config_loopback,
12802 	.format_fw_ver	= (format_fw_ver_t)elink_format_ver,
12803 	.hw_reset	= (hw_reset_t)NULL,
12804 	.set_link_led	= (set_link_led_t)NULL,
12805 	.phy_specific_func = (phy_specific_func_t)NULL
12806 };
12807 
12808 static const struct elink_phy phy_8727 = {
12809 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727,
12810 	.addr		= 0xff,
12811 	.def_md_devad	= 0,
12812 	.flags		= (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12813 			   ELINK_FLAGS_TX_ERROR_CHECK),
12814 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12815 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12816 	.mdio_ctrl	= 0,
12817 	.supported	= (ELINK_SUPPORTED_10000baseT_Full |
12818 			   ELINK_SUPPORTED_1000baseT_Full |
12819 			   ELINK_SUPPORTED_FIBRE |
12820 			   ELINK_SUPPORTED_Pause |
12821 			   ELINK_SUPPORTED_Asym_Pause),
12822 	.media_type	= ELINK_ETH_PHY_NOT_PRESENT,
12823 	.ver_addr	= 0,
12824 	.req_flow_ctrl	= 0,
12825 	.req_line_speed	= 0,
12826 	.speed_cap_mask	= 0,
12827 	.req_duplex	= 0,
12828 	.rsrv		= 0,
12829 	.config_init	= (config_init_t)elink_8727_config_init,
12830 	.read_status	= (read_status_t)elink_8727_read_status,
12831 	.link_reset	= (link_reset_t)elink_8727_link_reset,
12832 	.config_loopback = (config_loopback_t)NULL,
12833 	.format_fw_ver	= (format_fw_ver_t)elink_format_ver,
12834 	.hw_reset	= (hw_reset_t)elink_8727_hw_reset,
12835 	.set_link_led	= (set_link_led_t)elink_8727_set_link_led,
12836 	.phy_specific_func = (phy_specific_func_t)elink_8727_specific_func
12837 };
12838 static const struct elink_phy phy_8481 = {
12839 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8481,
12840 	.addr		= 0xff,
12841 	.def_md_devad	= 0,
12842 	.flags		= ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12843 			  ELINK_FLAGS_REARM_LATCH_SIGNAL,
12844 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12845 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12846 	.mdio_ctrl	= 0,
12847 	.supported	= (ELINK_SUPPORTED_10baseT_Half |
12848 			   ELINK_SUPPORTED_10baseT_Full |
12849 			   ELINK_SUPPORTED_100baseT_Half |
12850 			   ELINK_SUPPORTED_100baseT_Full |
12851 			   ELINK_SUPPORTED_1000baseT_Full |
12852 			   ELINK_SUPPORTED_10000baseT_Full |
12853 			   ELINK_SUPPORTED_TP |
12854 			   ELINK_SUPPORTED_Autoneg |
12855 			   ELINK_SUPPORTED_Pause |
12856 			   ELINK_SUPPORTED_Asym_Pause),
12857 	.media_type	= ELINK_ETH_PHY_BASE_T,
12858 	.ver_addr	= 0,
12859 	.req_flow_ctrl	= 0,
12860 	.req_line_speed	= 0,
12861 	.speed_cap_mask	= 0,
12862 	.req_duplex	= 0,
12863 	.rsrv		= 0,
12864 	.config_init	= (config_init_t)elink_8481_config_init,
12865 	.read_status	= (read_status_t)elink_848xx_read_status,
12866 	.link_reset	= (link_reset_t)elink_8481_link_reset,
12867 	.config_loopback = (config_loopback_t)NULL,
12868 	.format_fw_ver	= (format_fw_ver_t)elink_848xx_format_ver,
12869 	.hw_reset	= (hw_reset_t)elink_8481_hw_reset,
12870 	.set_link_led	= (set_link_led_t)elink_848xx_set_link_led,
12871 	.phy_specific_func = (phy_specific_func_t)NULL
12872 };
12873 
12874 static const struct elink_phy phy_84823 = {
12875 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823,
12876 	.addr		= 0xff,
12877 	.def_md_devad	= 0,
12878 	.flags		= (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12879 			   ELINK_FLAGS_REARM_LATCH_SIGNAL |
12880 			   ELINK_FLAGS_TX_ERROR_CHECK),
12881 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12882 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12883 	.mdio_ctrl	= 0,
12884 	.supported	= (ELINK_SUPPORTED_10baseT_Half |
12885 			   ELINK_SUPPORTED_10baseT_Full |
12886 			   ELINK_SUPPORTED_100baseT_Half |
12887 			   ELINK_SUPPORTED_100baseT_Full |
12888 			   ELINK_SUPPORTED_1000baseT_Full |
12889 			   ELINK_SUPPORTED_10000baseT_Full |
12890 			   ELINK_SUPPORTED_TP |
12891 			   ELINK_SUPPORTED_Autoneg |
12892 			   ELINK_SUPPORTED_Pause |
12893 			   ELINK_SUPPORTED_Asym_Pause),
12894 	.media_type	= ELINK_ETH_PHY_BASE_T,
12895 	.ver_addr	= 0,
12896 	.req_flow_ctrl	= 0,
12897 	.req_line_speed	= 0,
12898 	.speed_cap_mask	= 0,
12899 	.req_duplex	= 0,
12900 	.rsrv		= 0,
12901 	.config_init	= (config_init_t)elink_848x3_config_init,
12902 	.read_status	= (read_status_t)elink_848xx_read_status,
12903 	.link_reset	= (link_reset_t)elink_848x3_link_reset,
12904 	.config_loopback = (config_loopback_t)NULL,
12905 	.format_fw_ver	= (format_fw_ver_t)elink_848xx_format_ver,
12906 	.hw_reset	= (hw_reset_t)NULL,
12907 	.set_link_led	= (set_link_led_t)elink_848xx_set_link_led,
12908 	.phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12909 };
12910 
12911 static const struct elink_phy phy_84833 = {
12912 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84833,
12913 	.addr		= 0xff,
12914 	.def_md_devad	= 0,
12915 	.flags		= (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12916 			   ELINK_FLAGS_REARM_LATCH_SIGNAL |
12917 			   ELINK_FLAGS_TX_ERROR_CHECK |
12918 			   ELINK_FLAGS_TEMPERATURE),
12919 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12920 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12921 	.mdio_ctrl	= 0,
12922 	.supported	= (ELINK_SUPPORTED_100baseT_Half |
12923 			   ELINK_SUPPORTED_100baseT_Full |
12924 			   ELINK_SUPPORTED_1000baseT_Full |
12925 			   ELINK_SUPPORTED_10000baseT_Full |
12926 			   ELINK_SUPPORTED_TP |
12927 			   ELINK_SUPPORTED_Autoneg |
12928 			   ELINK_SUPPORTED_Pause |
12929 			   ELINK_SUPPORTED_Asym_Pause),
12930 	.media_type	= ELINK_ETH_PHY_BASE_T,
12931 	.ver_addr	= 0,
12932 	.req_flow_ctrl	= 0,
12933 	.req_line_speed	= 0,
12934 	.speed_cap_mask	= 0,
12935 	.req_duplex	= 0,
12936 	.rsrv		= 0,
12937 	.config_init	= (config_init_t)elink_848x3_config_init,
12938 	.read_status	= (read_status_t)elink_848xx_read_status,
12939 	.link_reset	= (link_reset_t)elink_848x3_link_reset,
12940 	.config_loopback = (config_loopback_t)NULL,
12941 	.format_fw_ver	= (format_fw_ver_t)elink_848xx_format_ver,
12942 	.hw_reset	= (hw_reset_t)elink_84833_hw_reset_phy,
12943 	.set_link_led	= (set_link_led_t)elink_848xx_set_link_led,
12944 	.phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12945 };
12946 
12947 static const struct elink_phy phy_84834 = {
12948 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834,
12949 	.addr		= 0xff,
12950 	.def_md_devad	= 0,
12951 	.flags		= ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12952 			    ELINK_FLAGS_REARM_LATCH_SIGNAL,
12953 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12954 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12955 	.mdio_ctrl	= 0,
12956 	.supported	= (ELINK_SUPPORTED_100baseT_Half |
12957 			   ELINK_SUPPORTED_100baseT_Full |
12958 			   ELINK_SUPPORTED_1000baseT_Full |
12959 			   ELINK_SUPPORTED_10000baseT_Full |
12960 			   ELINK_SUPPORTED_TP |
12961 			   ELINK_SUPPORTED_Autoneg |
12962 			   ELINK_SUPPORTED_Pause |
12963 			   ELINK_SUPPORTED_Asym_Pause),
12964 	.media_type	= ELINK_ETH_PHY_BASE_T,
12965 	.ver_addr	= 0,
12966 	.req_flow_ctrl	= 0,
12967 	.req_line_speed	= 0,
12968 	.speed_cap_mask	= 0,
12969 	.req_duplex	= 0,
12970 	.rsrv		= 0,
12971 	.config_init	= (config_init_t)elink_848x3_config_init,
12972 	.read_status	= (read_status_t)elink_848xx_read_status,
12973 	.link_reset	= (link_reset_t)elink_848x3_link_reset,
12974 	.config_loopback = (config_loopback_t)NULL,
12975 	.format_fw_ver	= (format_fw_ver_t)elink_848xx_format_ver,
12976 	.hw_reset	= (hw_reset_t)elink_84833_hw_reset_phy,
12977 	.set_link_led	= (set_link_led_t)elink_848xx_set_link_led,
12978 	.phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12979 };
12980 
12981 static const struct elink_phy phy_84858 = {
12982 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858,
12983 	.addr		= 0xff,
12984 	.def_md_devad	= 0,
12985 	.flags		= ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12986 			    ELINK_FLAGS_REARM_LATCH_SIGNAL,
12987 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12988 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
12989 	.mdio_ctrl	= 0,
12990 	.supported	= (ELINK_SUPPORTED_100baseT_Half |
12991 			   ELINK_SUPPORTED_100baseT_Full |
12992 			   ELINK_SUPPORTED_1000baseT_Full |
12993 			   ELINK_SUPPORTED_10000baseT_Full |
12994 			   ELINK_SUPPORTED_TP |
12995 			   ELINK_SUPPORTED_Autoneg |
12996 			   ELINK_SUPPORTED_Pause |
12997 			   ELINK_SUPPORTED_Asym_Pause),
12998 	.media_type	= ELINK_ETH_PHY_BASE_T,
12999 	.ver_addr	= 0,
13000 	.req_flow_ctrl	= 0,
13001 	.req_line_speed	= 0,
13002 	.speed_cap_mask	= 0,
13003 	.req_duplex	= 0,
13004 	.rsrv		= 0,
13005 	.config_init	= (config_init_t)elink_848x3_config_init,
13006 	.read_status	= (read_status_t)elink_848xx_read_status,
13007 	.link_reset	= (link_reset_t)elink_848x3_link_reset,
13008 	.config_loopback = (config_loopback_t)NULL,
13009 	.format_fw_ver	= (format_fw_ver_t)elink_848xx_format_ver,
13010 	.hw_reset	= (hw_reset_t)elink_84833_hw_reset_phy,
13011 	.set_link_led	= (set_link_led_t)elink_848xx_set_link_led,
13012 	.phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
13013 };
13014 
13015 
13016 static const struct elink_phy phy_54618se = {
13017 	.type		= PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE,
13018 	.addr		= 0xff,
13019 	.def_md_devad	= 0,
13020 	.flags		= ELINK_FLAGS_INIT_XGXS_FIRST,
13021 	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
13022 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
13023 	.mdio_ctrl	= 0,
13024 	.supported	= (ELINK_SUPPORTED_10baseT_Half |
13025 			   ELINK_SUPPORTED_10baseT_Full |
13026 			   ELINK_SUPPORTED_100baseT_Half |
13027 			   ELINK_SUPPORTED_100baseT_Full |
13028 			   ELINK_SUPPORTED_1000baseT_Full |
13029 			   ELINK_SUPPORTED_TP |
13030 			   ELINK_SUPPORTED_Autoneg |
13031 			   ELINK_SUPPORTED_Pause |
13032 			   ELINK_SUPPORTED_Asym_Pause),
13033 	.media_type	= ELINK_ETH_PHY_BASE_T,
13034 	.ver_addr	= 0,
13035 	.req_flow_ctrl	= 0,
13036 	.req_line_speed	= 0,
13037 	.speed_cap_mask	= 0,
13038 	/* req_duplex = */0,
13039 	/* rsrv = */0,
13040 	.config_init	= (config_init_t)elink_54618se_config_init,
13041 	.read_status	= (read_status_t)elink_54618se_read_status,
13042 	.link_reset	= (link_reset_t)elink_54618se_link_reset,
13043 	.config_loopback = (config_loopback_t)elink_54618se_config_loopback,
13044 	.format_fw_ver	= (format_fw_ver_t)NULL,
13045 	.hw_reset	= (hw_reset_t)NULL,
13046 	.set_link_led	= (set_link_led_t)elink_5461x_set_link_led,
13047 	.phy_specific_func = (phy_specific_func_t)elink_54618se_specific_func
13048 };
13049 /*****************************************************************/
13050 /*                                                               */
13051 /* Populate the phy according. Main function: elink_populate_phy   */
13052 /*                                                               */
13053 /*****************************************************************/
13054 
elink_populate_preemphasis(struct bnx2x_softc * sc,uint32_t shmem_base,struct elink_phy * phy,uint8_t port,uint8_t phy_index)13055 static void elink_populate_preemphasis(struct bnx2x_softc *sc,
13056 				     uint32_t shmem_base,
13057 				     struct elink_phy *phy, uint8_t port,
13058 				     uint8_t phy_index)
13059 {
13060 	/* Get the 4 lanes xgxs config rx and tx */
13061 	uint32_t rx = 0, tx = 0, i;
13062 	for (i = 0; i < 2; i++) {
13063 		/* INT_PHY and ELINK_EXT_PHY1 share the same value location in
13064 		 * the shmem. When num_phys is greater than 1, than this value
13065 		 * applies only to ELINK_EXT_PHY1
13066 		 */
13067 		if (phy_index == ELINK_INT_PHY || phy_index == ELINK_EXT_PHY1) {
13068 			rx = REG_RD(sc, shmem_base +
13069 				    offsetof(struct shmem_region,
13070 			dev_info.port_hw_config[port].xgxs_config_rx[i << 1]));
13071 
13072 			tx = REG_RD(sc, shmem_base +
13073 				    offsetof(struct shmem_region,
13074 			dev_info.port_hw_config[port].xgxs_config_tx[i << 1]));
13075 		} else {
13076 			rx = REG_RD(sc, shmem_base +
13077 				    offsetof(struct shmem_region,
13078 			dev_info.port_hw_config[port].xgxs_config2_rx[i << 1]));
13079 
13080 			tx = REG_RD(sc, shmem_base +
13081 				    offsetof(struct shmem_region,
13082 			dev_info.port_hw_config[port].xgxs_config2_rx[i << 1]));
13083 		}
13084 
13085 		phy->rx_preemphasis[i << 1] = ((rx >> 16) & 0xffff);
13086 		phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
13087 
13088 		phy->tx_preemphasis[i << 1] = ((tx >> 16) & 0xffff);
13089 		phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
13090 		ELINK_DEBUG_P2(sc, "phy->rx_preemphasis = %x, phy->tx_preemphasis = %x",
13091 			phy->rx_preemphasis[i << 1],
13092 			phy->tx_preemphasis[i << 1]);
13093 	}
13094 }
13095 
elink_get_ext_phy_config(struct bnx2x_softc * sc,uint32_t shmem_base,uint8_t phy_index,uint8_t port)13096 static uint32_t elink_get_ext_phy_config(struct bnx2x_softc *sc,
13097 				    uint32_t shmem_base,
13098 				    uint8_t phy_index, uint8_t port)
13099 {
13100 	uint32_t ext_phy_config = 0;
13101 	switch (phy_index) {
13102 	case ELINK_EXT_PHY1:
13103 		ext_phy_config = REG_RD(sc, shmem_base +
13104 					      offsetof(struct shmem_region,
13105 			dev_info.port_hw_config[port].external_phy_config));
13106 		break;
13107 	case ELINK_EXT_PHY2:
13108 		ext_phy_config = REG_RD(sc, shmem_base +
13109 					      offsetof(struct shmem_region,
13110 			dev_info.port_hw_config[port].external_phy_config2));
13111 		break;
13112 	default:
13113 		ELINK_DEBUG_P1(sc, "Invalid phy_index %d", phy_index);
13114 		return ELINK_STATUS_ERROR;
13115 	}
13116 
13117 	return ext_phy_config;
13118 }
elink_populate_int_phy(struct bnx2x_softc * sc,uint32_t shmem_base,uint8_t port,struct elink_phy * phy)13119 static elink_status_t elink_populate_int_phy(struct bnx2x_softc *sc,
13120 				  uint32_t shmem_base, uint8_t port,
13121 				  struct elink_phy *phy)
13122 {
13123 	uint32_t phy_addr;
13124 	uint32_t chip_id;
13125 	uint32_t switch_cfg = (REG_RD(sc, shmem_base +
13126 				       offsetof(struct shmem_region,
13127 			dev_info.port_feature_config[port].link_config)) &
13128 			  PORT_FEATURE_CONNECTED_SWITCH_MASK);
13129 	chip_id = (REG_RD(sc, MISC_REG_CHIP_NUM) << 16) |
13130 		((REG_RD(sc, MISC_REG_CHIP_REV) & 0xf) << 12);
13131 
13132 	ELINK_DEBUG_P1(sc, ":chip_id = 0x%x", chip_id);
13133 	if (USES_WARPCORE(sc)) {
13134 		uint32_t serdes_net_if;
13135 		phy_addr = REG_RD(sc,
13136 				  MISC_REG_WC0_CTRL_PHY_ADDR);
13137 		*phy = phy_warpcore;
13138 		if (REG_RD(sc, MISC_REG_PORT4MODE_EN_OVWR) == 0x3)
13139 			phy->flags |= ELINK_FLAGS_4_PORT_MODE;
13140 		else
13141 			phy->flags &= ~ELINK_FLAGS_4_PORT_MODE;
13142 			/* Check Dual mode */
13143 		serdes_net_if = (REG_RD(sc, shmem_base +
13144 					offsetof(struct shmem_region, dev_info.
13145 					port_hw_config[port].default_cfg)) &
13146 				 PORT_HW_CFG_NET_SERDES_IF_MASK);
13147 		/* Set the appropriate supported and flags indications per
13148 		 * interface type of the chip
13149 		 */
13150 		switch (serdes_net_if) {
13151 		case PORT_HW_CFG_NET_SERDES_IF_SGMII:
13152 			phy->supported &= (ELINK_SUPPORTED_10baseT_Half |
13153 					   ELINK_SUPPORTED_10baseT_Full |
13154 					   ELINK_SUPPORTED_100baseT_Half |
13155 					   ELINK_SUPPORTED_100baseT_Full |
13156 					   ELINK_SUPPORTED_1000baseT_Full |
13157 					   ELINK_SUPPORTED_FIBRE |
13158 					   ELINK_SUPPORTED_Autoneg |
13159 					   ELINK_SUPPORTED_Pause |
13160 					   ELINK_SUPPORTED_Asym_Pause);
13161 			phy->media_type = ELINK_ETH_PHY_BASE_T;
13162 			break;
13163 		case PORT_HW_CFG_NET_SERDES_IF_XFI:
13164 			phy->supported &= (ELINK_SUPPORTED_1000baseT_Full |
13165 					   ELINK_SUPPORTED_10000baseT_Full |
13166 					   ELINK_SUPPORTED_FIBRE |
13167 					   ELINK_SUPPORTED_Pause |
13168 					   ELINK_SUPPORTED_Asym_Pause);
13169 			phy->media_type = ELINK_ETH_PHY_XFP_FIBER;
13170 			break;
13171 		case PORT_HW_CFG_NET_SERDES_IF_SFI:
13172 			phy->supported &= (ELINK_SUPPORTED_1000baseT_Full |
13173 					   ELINK_SUPPORTED_2500baseX_Full |
13174 					   ELINK_SUPPORTED_10000baseT_Full |
13175 					   ELINK_SUPPORTED_FIBRE |
13176 					   ELINK_SUPPORTED_Pause |
13177 					   ELINK_SUPPORTED_Asym_Pause);
13178 			phy->media_type = ELINK_ETH_PHY_SFPP_10G_FIBER;
13179 			break;
13180 		case PORT_HW_CFG_NET_SERDES_IF_KR:
13181 			phy->media_type = ELINK_ETH_PHY_KR;
13182 			phy->supported &= (ELINK_SUPPORTED_1000baseKX_Full |
13183 					   ELINK_SUPPORTED_10000baseKR_Full |
13184 					   ELINK_SUPPORTED_FIBRE |
13185 					   ELINK_SUPPORTED_Autoneg |
13186 					   ELINK_SUPPORTED_Pause |
13187 					   ELINK_SUPPORTED_Asym_Pause);
13188 			break;
13189 		case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
13190 			phy->media_type = ELINK_ETH_PHY_KR;
13191 			phy->flags |= ELINK_FLAGS_WC_DUAL_MODE;
13192 			phy->supported &= (ELINK_SUPPORTED_20000baseMLD2_Full |
13193 					   ELINK_SUPPORTED_FIBRE |
13194 					   ELINK_SUPPORTED_Pause |
13195 					   ELINK_SUPPORTED_Asym_Pause);
13196 			break;
13197 		case PORT_HW_CFG_NET_SERDES_IF_KR2:
13198 			phy->media_type = ELINK_ETH_PHY_KR;
13199 			phy->flags |= ELINK_FLAGS_WC_DUAL_MODE;
13200 			phy->supported &= (ELINK_SUPPORTED_20000baseKR2_Full |
13201 					   ELINK_SUPPORTED_10000baseKR_Full |
13202 					   ELINK_SUPPORTED_1000baseKX_Full |
13203 					   ELINK_SUPPORTED_Autoneg |
13204 					   ELINK_SUPPORTED_FIBRE |
13205 					   ELINK_SUPPORTED_Pause |
13206 					   ELINK_SUPPORTED_Asym_Pause);
13207 			phy->flags &= ~ELINK_FLAGS_TX_ERROR_CHECK;
13208 			break;
13209 		default:
13210 			ELINK_DEBUG_P1(sc, "Unknown WC interface type 0x%x",
13211 				       serdes_net_if);
13212 			break;
13213 		}
13214 
13215 		/* Enable MDC/MDIO work-around for E3 A0 since free running MDC
13216 		 * was not set as expected. For B0, ECO will be enabled so there
13217 		 * won't be an issue there
13218 		 */
13219 		if (CHIP_REV(sc) == CHIP_REV_Ax)
13220 			phy->flags |= ELINK_FLAGS_MDC_MDIO_WA;
13221 		else
13222 			phy->flags |= ELINK_FLAGS_MDC_MDIO_WA_B0;
13223 		ELINK_DEBUG_P3(sc, "media_type = %x, flags = %x, supported = %x",
13224 				phy->media_type, phy->flags, phy->supported);
13225 	} else {
13226 		switch (switch_cfg) {
13227 		case ELINK_SWITCH_CFG_1G:
13228 			phy_addr = REG_RD(sc,
13229 					  NIG_REG_SERDES0_CTRL_PHY_ADDR +
13230 					  port * 0x10);
13231 			*phy = phy_serdes;
13232 			break;
13233 		case ELINK_SWITCH_CFG_10G:
13234 			phy_addr = REG_RD(sc,
13235 					  NIG_REG_XGXS0_CTRL_PHY_ADDR +
13236 					  port * 0x18);
13237 			*phy = phy_xgxs;
13238 			break;
13239 		default:
13240 			ELINK_DEBUG_P0(sc, "Invalid switch_cfg");
13241 			return ELINK_STATUS_ERROR;
13242 		}
13243 	}
13244 	phy->addr = (uint8_t)phy_addr;
13245 	phy->mdio_ctrl = elink_get_emac_base(sc,
13246 					    SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
13247 					    port);
13248 	if (CHIP_IS_E2(sc))
13249 		phy->def_md_devad = ELINK_E2_DEFAULT_PHY_DEV_ADDR;
13250 	else
13251 		phy->def_md_devad = ELINK_DEFAULT_PHY_DEV_ADDR;
13252 
13253 	ELINK_DEBUG_P3(sc, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x",
13254 		   port, phy->addr, phy->mdio_ctrl);
13255 
13256 	elink_populate_preemphasis(sc, shmem_base, phy, port, ELINK_INT_PHY);
13257 	return ELINK_STATUS_OK;
13258 }
13259 
elink_populate_ext_phy(struct bnx2x_softc * sc,uint8_t phy_index,uint32_t shmem_base,uint32_t shmem2_base,uint8_t port,struct elink_phy * phy)13260 static elink_status_t elink_populate_ext_phy(struct bnx2x_softc *sc,
13261 				  uint8_t phy_index,
13262 				  uint32_t shmem_base,
13263 				  uint32_t shmem2_base,
13264 				  uint8_t port,
13265 				  struct elink_phy *phy)
13266 {
13267 	uint32_t ext_phy_config, phy_type, config2;
13268 	uint32_t mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
13269 	ext_phy_config = elink_get_ext_phy_config(sc, shmem_base,
13270 						  phy_index, port);
13271 	phy_type = ELINK_XGXS_EXT_PHY_TYPE(ext_phy_config);
13272 	/* Select the phy type */
13273 	switch (phy_type) {
13274 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8073:
13275 		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
13276 		*phy = phy_8073;
13277 		break;
13278 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8705:
13279 		*phy = phy_8705;
13280 		break;
13281 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8706:
13282 		*phy = phy_8706;
13283 		break;
13284 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726:
13285 		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
13286 		*phy = phy_8726;
13287 		break;
13288 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727_NOC:
13289 		/* BNX2X8727_NOC => BNX2X8727 no over current */
13290 		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
13291 		*phy = phy_8727;
13292 		phy->flags |= ELINK_FLAGS_NOC;
13293 		break;
13294 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
13295 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
13296 		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
13297 		*phy = phy_8727;
13298 		break;
13299 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8481:
13300 		*phy = phy_8481;
13301 		break;
13302 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823:
13303 		*phy = phy_84823;
13304 		break;
13305 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84833:
13306 		*phy = phy_84833;
13307 		break;
13308 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834:
13309 		*phy = phy_84834;
13310 		break;
13311 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858:
13312 		*phy = phy_84858;
13313 		break;
13314 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X54616:
13315 	case PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE:
13316 		*phy = phy_54618se;
13317 		if (phy_type == PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE)
13318 			phy->flags |= ELINK_FLAGS_EEE;
13319 		break;
13320 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
13321 		*phy = phy_7101;
13322 		break;
13323 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
13324 		*phy = phy_null;
13325 		return ELINK_STATUS_ERROR;
13326 	default:
13327 		*phy = phy_null;
13328 		/* In case external PHY wasn't found */
13329 		if ((phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
13330 		    (phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
13331 			return ELINK_STATUS_ERROR;
13332 		return ELINK_STATUS_OK;
13333 	}
13334 
13335 	phy->addr = ELINK_XGXS_EXT_PHY_ADDR(ext_phy_config);
13336 	elink_populate_preemphasis(sc, shmem_base, phy, port, phy_index);
13337 
13338 	/* The shmem address of the phy version is located on different
13339 	 * structures. In case this structure is too old, do not set
13340 	 * the address
13341 	 */
13342 	config2 = REG_RD(sc, shmem_base + offsetof(struct shmem_region,
13343 					dev_info.shared_hw_config.config2));
13344 	if (phy_index == ELINK_EXT_PHY1) {
13345 		phy->ver_addr = shmem_base + offsetof(struct shmem_region,
13346 				port_mb[port].ext_phy_fw_version);
13347 
13348 		/* Check specific mdc mdio settings */
13349 		if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
13350 			mdc_mdio_access = config2 &
13351 			SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
13352 	} else {
13353 		uint32_t size = REG_RD(sc, shmem2_base);
13354 
13355 		if (size >
13356 		    offsetof(struct shmem2_region, ext_phy_fw_version2)) {
13357 			phy->ver_addr = shmem2_base +
13358 			    offsetof(struct shmem2_region,
13359 				     ext_phy_fw_version2[port]);
13360 		}
13361 		/* Check specific mdc mdio settings */
13362 		if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
13363 			mdc_mdio_access = (config2 &
13364 			SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
13365 			(SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
13366 			 SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
13367 	}
13368 	phy->mdio_ctrl = elink_get_emac_base(sc, mdc_mdio_access, port);
13369 
13370 	if (elink_is_8483x_8485x(phy) && (phy->ver_addr)) {
13371 		/* Remove 100Mb link supported for BNX2X84833/4 when phy fw
13372 		 * version lower than or equal to 1.39
13373 		 */
13374 		uint32_t raw_ver = REG_RD(sc, phy->ver_addr);
13375 		if (((raw_ver & 0x7F) <= 39) &&
13376 		    (((raw_ver & 0xF80) >> 7) <= 1))
13377 			phy->supported &= ~(ELINK_SUPPORTED_100baseT_Half |
13378 					    ELINK_SUPPORTED_100baseT_Full);
13379 	}
13380 
13381 	ELINK_DEBUG_P3(sc, "phy_type 0x%x port %d found in index %d",
13382 		   phy_type, port, phy_index);
13383 	ELINK_DEBUG_P2(sc, "             addr=0x%x, mdio_ctl=0x%x",
13384 		   phy->addr, phy->mdio_ctrl);
13385 	return ELINK_STATUS_OK;
13386 }
13387 
elink_populate_phy(struct bnx2x_softc * sc,uint8_t phy_index,uint32_t shmem_base,uint32_t shmem2_base,uint8_t port,struct elink_phy * phy)13388 static elink_status_t elink_populate_phy(struct bnx2x_softc *sc,
13389 			      uint8_t phy_index, uint32_t shmem_base,
13390 			      uint32_t shmem2_base, uint8_t port,
13391 			      struct elink_phy *phy)
13392 {
13393 	elink_status_t status = ELINK_STATUS_OK;
13394 	phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
13395 	if (phy_index == ELINK_INT_PHY)
13396 		return elink_populate_int_phy(sc, shmem_base, port, phy);
13397 	status = elink_populate_ext_phy(sc, phy_index, shmem_base, shmem2_base,
13398 					port, phy);
13399 	return status;
13400 }
13401 
elink_phy_def_cfg(struct elink_params * params,struct elink_phy * phy,uint8_t phy_index)13402 static void elink_phy_def_cfg(struct elink_params *params,
13403 			      struct elink_phy *phy,
13404 			      uint8_t phy_index)
13405 {
13406 	struct bnx2x_softc *sc = params->sc;
13407 	uint32_t link_config;
13408 	/* Populate the default phy configuration for MF mode */
13409 	if (phy_index == ELINK_EXT_PHY2) {
13410 		link_config = REG_RD(sc, params->shmem_base +
13411 				     offsetof(struct shmem_region, dev_info.
13412 			port_feature_config[params->port].link_config2));
13413 		phy->speed_cap_mask = REG_RD(sc, params->shmem_base +
13414 					     offsetof(struct shmem_region,
13415 						      dev_info.
13416 			port_hw_config[params->port].speed_capability_mask2));
13417 	} else {
13418 		link_config = REG_RD(sc, params->shmem_base +
13419 				     offsetof(struct shmem_region, dev_info.
13420 				port_feature_config[params->port].link_config));
13421 		phy->speed_cap_mask = REG_RD(sc, params->shmem_base +
13422 					     offsetof(struct shmem_region,
13423 						      dev_info.
13424 			port_hw_config[params->port].speed_capability_mask));
13425 	}
13426 	ELINK_DEBUG_P3(sc,
13427 	   "Default config phy idx %x cfg 0x%x speed_cap_mask 0x%x",
13428 	   phy_index, link_config, phy->speed_cap_mask);
13429 
13430 	phy->req_duplex = DUPLEX_FULL;
13431 	switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
13432 	case PORT_FEATURE_LINK_SPEED_10M_HALF:
13433 		phy->req_duplex = DUPLEX_HALF;
13434 		/* fallthrough */
13435 	case PORT_FEATURE_LINK_SPEED_10M_FULL:
13436 		phy->req_line_speed = ELINK_SPEED_10;
13437 		break;
13438 	case PORT_FEATURE_LINK_SPEED_100M_HALF:
13439 		phy->req_duplex = DUPLEX_HALF;
13440 		/* fallthrough */
13441 	case PORT_FEATURE_LINK_SPEED_100M_FULL:
13442 		phy->req_line_speed = ELINK_SPEED_100;
13443 		break;
13444 	case PORT_FEATURE_LINK_SPEED_1G:
13445 		phy->req_line_speed = ELINK_SPEED_1000;
13446 		break;
13447 	case PORT_FEATURE_LINK_SPEED_2_5G:
13448 		phy->req_line_speed = ELINK_SPEED_2500;
13449 		break;
13450 	case PORT_FEATURE_LINK_SPEED_10G_CX4:
13451 		phy->req_line_speed = ELINK_SPEED_10000;
13452 		break;
13453 	default:
13454 		phy->req_line_speed = ELINK_SPEED_AUTO_NEG;
13455 		break;
13456 	}
13457 
13458 	ELINK_DEBUG_P2(sc, "Default config phy idx %x, req_duplex config %x",
13459 			phy_index, phy->req_duplex);
13460 
13461 	switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
13462 	case PORT_FEATURE_FLOW_CONTROL_AUTO:
13463 		phy->req_flow_ctrl = ELINK_FLOW_CTRL_AUTO;
13464 		break;
13465 	case PORT_FEATURE_FLOW_CONTROL_TX:
13466 		phy->req_flow_ctrl = ELINK_FLOW_CTRL_TX;
13467 		break;
13468 	case PORT_FEATURE_FLOW_CONTROL_RX:
13469 		phy->req_flow_ctrl = ELINK_FLOW_CTRL_RX;
13470 		break;
13471 	case PORT_FEATURE_FLOW_CONTROL_BOTH:
13472 		phy->req_flow_ctrl = ELINK_FLOW_CTRL_BOTH;
13473 		break;
13474 	default:
13475 		phy->req_flow_ctrl = ELINK_FLOW_CTRL_NONE;
13476 		break;
13477 	}
13478 	ELINK_DEBUG_P3(sc, "Requested Duplex = %x, line_speed = %x, flow_ctrl = %x",
13479 		       phy->req_duplex, phy->req_line_speed,
13480 		       phy->req_flow_ctrl);
13481 }
13482 
elink_phy_selection(struct elink_params * params)13483 uint32_t elink_phy_selection(struct elink_params *params)
13484 {
13485 	uint32_t phy_config_swapped, prio_cfg;
13486 	uint32_t return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
13487 
13488 	phy_config_swapped = params->multi_phy_config &
13489 		PORT_HW_CFG_PHY_SWAPPED_ENABLED;
13490 
13491 	prio_cfg = params->multi_phy_config &
13492 			PORT_HW_CFG_PHY_SELECTION_MASK;
13493 
13494 	if (phy_config_swapped) {
13495 		switch (prio_cfg) {
13496 		case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
13497 		     return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
13498 			break;
13499 		case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
13500 		     return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
13501 			break;
13502 		case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
13503 		     return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
13504 			break;
13505 		case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
13506 		     return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
13507 			break;
13508 		}
13509 	} else
13510 		return_cfg = prio_cfg;
13511 
13512 	return return_cfg;
13513 }
13514 
elink_phy_probe(struct elink_params * params)13515 elink_status_t elink_phy_probe(struct elink_params *params)
13516 {
13517 	uint8_t phy_index, actual_phy_idx;
13518 	uint32_t phy_config_swapped, sync_offset, media_types;
13519 	struct bnx2x_softc *sc = params->sc;
13520 	struct elink_phy *phy;
13521 	params->num_phys = 0;
13522 	ELINK_DEBUG_P0(sc, "Begin phy probe");
13523 #ifdef ELINK_INCLUDE_EMUL
13524 	if (CHIP_REV_IS_EMUL(sc))
13525 		return ELINK_STATUS_OK;
13526 #endif
13527 	phy_config_swapped = params->multi_phy_config &
13528 		PORT_HW_CFG_PHY_SWAPPED_ENABLED;
13529 
13530 	for (phy_index = ELINK_INT_PHY; phy_index < ELINK_MAX_PHYS;
13531 	      phy_index++) {
13532 		actual_phy_idx = phy_index;
13533 		if (phy_config_swapped) {
13534 			if (phy_index == ELINK_EXT_PHY1)
13535 				actual_phy_idx = ELINK_EXT_PHY2;
13536 			else if (phy_index == ELINK_EXT_PHY2)
13537 				actual_phy_idx = ELINK_EXT_PHY1;
13538 		}
13539 		ELINK_DEBUG_P3(sc, "phy_config_swapped %x, phy_index %x,"
13540 			       " actual_phy_idx %x", phy_config_swapped,
13541 			   phy_index, actual_phy_idx);
13542 		phy = &params->phy[actual_phy_idx];
13543 		if (elink_populate_phy(sc, phy_index, params->shmem_base,
13544 				       params->shmem2_base, params->port,
13545 				       phy) != ELINK_STATUS_OK) {
13546 			params->num_phys = 0;
13547 			ELINK_DEBUG_P1(sc, "phy probe failed in phy index %d",
13548 				   phy_index);
13549 			for (phy_index = ELINK_INT_PHY;
13550 			      phy_index < ELINK_MAX_PHYS;
13551 			      phy_index++)
13552 				*phy = phy_null;
13553 			return ELINK_STATUS_ERROR;
13554 		}
13555 		if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
13556 			break;
13557 
13558 		if (params->feature_config_flags &
13559 		    ELINK_FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET)
13560 			phy->flags &= ~ELINK_FLAGS_TX_ERROR_CHECK;
13561 
13562 		if (!(params->feature_config_flags &
13563 		      ELINK_FEATURE_CONFIG_MT_SUPPORT))
13564 			phy->flags |= ELINK_FLAGS_MDC_MDIO_WA_G;
13565 
13566 		sync_offset = params->shmem_base +
13567 			offsetof(struct shmem_region,
13568 			dev_info.port_hw_config[params->port].media_type);
13569 		media_types = REG_RD(sc, sync_offset);
13570 
13571 		/* Update media type for non-PMF sync only for the first time
13572 		 * In case the media type changes afterwards, it will be updated
13573 		 * using the update_status function
13574 		 */
13575 		if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
13576 				    (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
13577 				     actual_phy_idx))) == 0) {
13578 			media_types |= ((phy->media_type &
13579 					PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
13580 				(PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
13581 				 actual_phy_idx));
13582 		}
13583 		REG_WR(sc, sync_offset, media_types);
13584 
13585 		elink_phy_def_cfg(params, phy, phy_index);
13586 		params->num_phys++;
13587 	}
13588 
13589 	ELINK_DEBUG_P1(sc, "End phy probe. #phys found %x", params->num_phys);
13590 	return ELINK_STATUS_OK;
13591 }
13592 
13593 #ifdef ELINK_INCLUDE_EMUL
elink_init_e3_emul_mac(struct elink_params * params,struct elink_vars * vars)13594 static elink_status_t elink_init_e3_emul_mac(struct elink_params *params,
13595 					     struct elink_vars *vars)
13596 {
13597 	struct bnx2x_softc *sc = params->sc;
13598 	vars->line_speed = params->req_line_speed[0];
13599 	/* In case link speed is auto, set speed the highest as possible */
13600 	if (params->req_line_speed[0] == ELINK_SPEED_AUTO_NEG) {
13601 		if (params->feature_config_flags &
13602 		    ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC)
13603 			vars->line_speed = ELINK_SPEED_2500;
13604 		else if (elink_is_4_port_mode(sc))
13605 			vars->line_speed = ELINK_SPEED_10000;
13606 		else
13607 			vars->line_speed = ELINK_SPEED_20000;
13608 	}
13609 	if (vars->line_speed < ELINK_SPEED_10000) {
13610 		if ((params->feature_config_flags &
13611 		     ELINK_FEATURE_CONFIG_EMUL_DISABLE_UMAC)) {
13612 			ELINK_DEBUG_P1(sc, "Invalid line speed %d while UMAC is"
13613 				   " disabled!", params->req_line_speed[0]);
13614 			return ELINK_STATUS_ERROR;
13615 		}
13616 		switch (vars->line_speed) {
13617 		case ELINK_SPEED_10:
13618 			vars->link_status = ELINK_LINK_10TFD;
13619 			break;
13620 		case ELINK_SPEED_100:
13621 			vars->link_status = ELINK_LINK_100TXFD;
13622 			break;
13623 		case ELINK_SPEED_1000:
13624 			vars->link_status = ELINK_LINK_1000TFD;
13625 			break;
13626 		case ELINK_SPEED_2500:
13627 			vars->link_status = ELINK_LINK_2500TFD;
13628 			break;
13629 		default:
13630 			ELINK_DEBUG_P1(sc, "Invalid line speed %d for UMAC",
13631 				   vars->line_speed);
13632 			return ELINK_STATUS_ERROR;
13633 		}
13634 		vars->link_status |= LINK_STATUS_LINK_UP;
13635 
13636 		if (params->loopback_mode == ELINK_LOOPBACK_UMAC)
13637 			elink_umac_enable(params, vars, 1);
13638 		else
13639 			elink_umac_enable(params, vars, 0);
13640 	} else {
13641 		/* Link speed >= 10000 requires XMAC enabled */
13642 		if (params->feature_config_flags &
13643 		    ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC) {
13644 			ELINK_DEBUG_P1(sc, "Invalid line speed %d while XMAC is"
13645 				   " disabled!", params->req_line_speed[0]);
13646 		return ELINK_STATUS_ERROR;
13647 	}
13648 		/* Check link speed */
13649 		switch (vars->line_speed) {
13650 		case ELINK_SPEED_10000:
13651 			vars->link_status = ELINK_LINK_10GTFD;
13652 			break;
13653 		case ELINK_SPEED_20000:
13654 			vars->link_status = ELINK_LINK_20GTFD;
13655 			break;
13656 		default:
13657 			ELINK_DEBUG_P1(sc, "Invalid line speed %d for XMAC",
13658 				   vars->line_speed);
13659 			return ELINK_STATUS_ERROR;
13660 		}
13661 		vars->link_status |= LINK_STATUS_LINK_UP;
13662 		if (params->loopback_mode == ELINK_LOOPBACK_XMAC)
13663 			elink_xmac_enable(params, vars, 1);
13664 		else
13665 			elink_xmac_enable(params, vars, 0);
13666 	}
13667 		return ELINK_STATUS_OK;
13668 }
13669 
elink_init_emul(struct elink_params * params,struct elink_vars * vars)13670 static elink_status_t elink_init_emul(struct elink_params *params,
13671 			    struct elink_vars *vars)
13672 {
13673 	struct bnx2x_softc *sc = params->sc;
13674 	if (CHIP_IS_E3(sc)) {
13675 		if (elink_init_e3_emul_mac(params, vars) !=
13676 		    ELINK_STATUS_OK)
13677 			return ELINK_STATUS_ERROR;
13678 	} else {
13679 		if (params->feature_config_flags &
13680 		    ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC) {
13681 			vars->line_speed = ELINK_SPEED_1000;
13682 			vars->link_status = (LINK_STATUS_LINK_UP |
13683 					     ELINK_LINK_1000XFD);
13684 			if (params->loopback_mode ==
13685 			    ELINK_LOOPBACK_EMAC)
13686 				elink_emac_enable(params, vars, 1);
13687 			else
13688 				elink_emac_enable(params, vars, 0);
13689 		} else {
13690 			vars->line_speed = ELINK_SPEED_10000;
13691 			vars->link_status = (LINK_STATUS_LINK_UP |
13692 					     ELINK_LINK_10GTFD);
13693 			if (params->loopback_mode ==
13694 			    ELINK_LOOPBACK_BMAC)
13695 				elink_bmac_enable(params, vars, 1, 1);
13696 			else
13697 				elink_bmac_enable(params, vars, 0, 1);
13698 		}
13699 	}
13700 	vars->link_up = 1;
13701 	vars->duplex = DUPLEX_FULL;
13702 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13703 
13704 		if (CHIP_IS_E1x(sc))
13705 			elink_pbf_update(params, vars->flow_ctrl,
13706 					 vars->line_speed);
13707 		/* Disable drain */
13708 		REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13709 
13710 		/* update shared memory */
13711 		elink_update_mng(params, vars->link_status);
13712 	return ELINK_STATUS_OK;
13713 }
13714 #endif
13715 #ifdef ELINK_INCLUDE_FPGA
elink_init_fpga(struct elink_params * params,struct elink_vars * vars)13716 static elink_status_t elink_init_fpga(struct elink_params *params,
13717 			    struct elink_vars *vars)
13718 {
13719 	/* Enable on E1.5 FPGA */
13720 	struct bnx2x_softc *sc = params->sc;
13721 	vars->duplex = DUPLEX_FULL;
13722 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13723 	if (!(CHIP_IS_E1(sc))) {
13724 		vars->flow_ctrl = (ELINK_FLOW_CTRL_TX |
13725 				   ELINK_FLOW_CTRL_RX);
13726 		vars->link_status |= (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
13727 				      LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
13728 	}
13729 	if (CHIP_IS_E3(sc)) {
13730 		vars->line_speed = params->req_line_speed[0];
13731 		switch (vars->line_speed) {
13732 		case ELINK_SPEED_AUTO_NEG:
13733 			vars->line_speed = ELINK_SPEED_2500;
13734 		case ELINK_SPEED_2500:
13735 			vars->link_status = ELINK_LINK_2500TFD;
13736 			break;
13737 		case ELINK_SPEED_1000:
13738 			vars->link_status = ELINK_LINK_1000XFD;
13739 			break;
13740 		case ELINK_SPEED_100:
13741 			vars->link_status = ELINK_LINK_100TXFD;
13742 			break;
13743 		case ELINK_SPEED_10:
13744 			vars->link_status = ELINK_LINK_10TFD;
13745 			break;
13746 		default:
13747 			ELINK_DEBUG_P1(sc, "Invalid link speed %d",
13748 				   params->req_line_speed[0]);
13749 			return ELINK_STATUS_ERROR;
13750 		}
13751 		vars->link_status |= LINK_STATUS_LINK_UP;
13752 		if (params->loopback_mode == ELINK_LOOPBACK_UMAC)
13753 			elink_umac_enable(params, vars, 1);
13754 		else
13755 			elink_umac_enable(params, vars, 0);
13756 	} else {
13757 		vars->line_speed = ELINK_SPEED_10000;
13758 		vars->link_status = (LINK_STATUS_LINK_UP | ELINK_LINK_10GTFD);
13759 		if (params->loopback_mode == ELINK_LOOPBACK_EMAC)
13760 			elink_emac_enable(params, vars, 1);
13761 		else
13762 			elink_emac_enable(params, vars, 0);
13763 	}
13764 	vars->link_up = 1;
13765 
13766 	if (CHIP_IS_E1x(sc))
13767 		elink_pbf_update(params, vars->flow_ctrl,
13768 				 vars->line_speed);
13769 	/* Disable drain */
13770 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13771 
13772 	/* Update shared memory */
13773 	elink_update_mng(params, vars->link_status);
13774 		return ELINK_STATUS_OK;
13775 }
13776 #endif
elink_init_bmac_loopback(struct elink_params * params,struct elink_vars * vars)13777 static void elink_init_bmac_loopback(struct elink_params *params,
13778 				     struct elink_vars *vars)
13779 {
13780 	struct bnx2x_softc *sc = params->sc;
13781 		vars->link_up = 1;
13782 		vars->line_speed = ELINK_SPEED_10000;
13783 		vars->duplex = DUPLEX_FULL;
13784 		vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13785 		vars->mac_type = ELINK_MAC_TYPE_BMAC;
13786 
13787 		vars->phy_flags = PHY_XGXS_FLAG;
13788 
13789 		elink_xgxs_deassert(params);
13790 
13791 		/* Set bmac loopback */
13792 		elink_bmac_enable(params, vars, 1, 1);
13793 
13794 		REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13795 }
13796 
elink_init_emac_loopback(struct elink_params * params,struct elink_vars * vars)13797 static void elink_init_emac_loopback(struct elink_params *params,
13798 				     struct elink_vars *vars)
13799 {
13800 	struct bnx2x_softc *sc = params->sc;
13801 		vars->link_up = 1;
13802 		vars->line_speed = ELINK_SPEED_1000;
13803 		vars->duplex = DUPLEX_FULL;
13804 		vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13805 		vars->mac_type = ELINK_MAC_TYPE_EMAC;
13806 
13807 		vars->phy_flags = PHY_XGXS_FLAG;
13808 
13809 		elink_xgxs_deassert(params);
13810 		/* Set bmac loopback */
13811 		elink_emac_enable(params, vars, 1);
13812 		elink_emac_program(params, vars);
13813 		REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13814 }
13815 
elink_init_xmac_loopback(struct elink_params * params,struct elink_vars * vars)13816 static void elink_init_xmac_loopback(struct elink_params *params,
13817 				     struct elink_vars *vars)
13818 {
13819 	struct bnx2x_softc *sc = params->sc;
13820 	vars->link_up = 1;
13821 	if (!params->req_line_speed[0])
13822 		vars->line_speed = ELINK_SPEED_10000;
13823 	else
13824 		vars->line_speed = params->req_line_speed[0];
13825 	vars->duplex = DUPLEX_FULL;
13826 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13827 	vars->mac_type = ELINK_MAC_TYPE_XMAC;
13828 	vars->phy_flags = PHY_XGXS_FLAG;
13829 	/* Set WC to loopback mode since link is required to provide clock
13830 	 * to the XMAC in 20G mode
13831 	 */
13832 	elink_set_aer_mmd(params, &params->phy[0]);
13833 	elink_warpcore_reset_lane(sc, &params->phy[0], 0);
13834 	params->phy[ELINK_INT_PHY].config_loopback(
13835 			&params->phy[ELINK_INT_PHY],
13836 			params);
13837 
13838 	elink_xmac_enable(params, vars, 1);
13839 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13840 }
13841 
elink_init_umac_loopback(struct elink_params * params,struct elink_vars * vars)13842 static void elink_init_umac_loopback(struct elink_params *params,
13843 				     struct elink_vars *vars)
13844 {
13845 	struct bnx2x_softc *sc = params->sc;
13846 	vars->link_up = 1;
13847 	vars->line_speed = ELINK_SPEED_1000;
13848 	vars->duplex = DUPLEX_FULL;
13849 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13850 	vars->mac_type = ELINK_MAC_TYPE_UMAC;
13851 	vars->phy_flags = PHY_XGXS_FLAG;
13852 	elink_umac_enable(params, vars, 1);
13853 
13854 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13855 }
13856 
elink_init_xgxs_loopback(struct elink_params * params,struct elink_vars * vars)13857 static void elink_init_xgxs_loopback(struct elink_params *params,
13858 				     struct elink_vars *vars)
13859 {
13860 	struct bnx2x_softc *sc = params->sc;
13861 	struct elink_phy *int_phy = &params->phy[ELINK_INT_PHY];
13862 	vars->link_up = 1;
13863 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13864 	vars->duplex = DUPLEX_FULL;
13865 	if (params->req_line_speed[0] == ELINK_SPEED_1000)
13866 		vars->line_speed = ELINK_SPEED_1000;
13867 	else if ((params->req_line_speed[0] == ELINK_SPEED_20000) ||
13868 		 (int_phy->flags & ELINK_FLAGS_WC_DUAL_MODE))
13869 		vars->line_speed = ELINK_SPEED_20000;
13870 	else
13871 		vars->line_speed = ELINK_SPEED_10000;
13872 
13873 	if (!USES_WARPCORE(sc))
13874 		elink_xgxs_deassert(params);
13875 	elink_link_initialize(params, vars);
13876 
13877 	if (params->req_line_speed[0] == ELINK_SPEED_1000) {
13878 		if (USES_WARPCORE(sc))
13879 			elink_umac_enable(params, vars, 0);
13880 		else {
13881 			elink_emac_program(params, vars);
13882 			elink_emac_enable(params, vars, 0);
13883 		}
13884 	} else {
13885 		if (USES_WARPCORE(sc))
13886 			elink_xmac_enable(params, vars, 0);
13887 		else
13888 			elink_bmac_enable(params, vars, 0, 1);
13889 	}
13890 
13891 	if (params->loopback_mode == ELINK_LOOPBACK_XGXS) {
13892 		/* Set 10G XGXS loopback */
13893 		int_phy->config_loopback(int_phy, params);
13894 	} else {
13895 		/* Set external phy loopback */
13896 		uint8_t phy_index;
13897 		for (phy_index = ELINK_EXT_PHY1;
13898 		      phy_index < params->num_phys; phy_index++)
13899 			if (params->phy[phy_index].config_loopback)
13900 				params->phy[phy_index].config_loopback(
13901 					&params->phy[phy_index],
13902 					params);
13903 	}
13904 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13905 
13906 	elink_set_led(params, vars, ELINK_LED_MODE_OPER, vars->line_speed);
13907 }
13908 
elink_set_rx_filter(struct elink_params * params,uint8_t en)13909 void elink_set_rx_filter(struct elink_params *params, uint8_t en)
13910 {
13911 	struct bnx2x_softc *sc = params->sc;
13912 	uint8_t val = en * 0x1F;
13913 
13914 	/* Open / close the gate between the NIG and the BRB */
13915 	if (!CHIP_IS_E1x(sc))
13916 		val |= en * 0x20;
13917 	REG_WR(sc, NIG_REG_LLH0_BRB1_DRV_MASK + params->port * 4, val);
13918 
13919 	if (!CHIP_IS_E1(sc)) {
13920 		REG_WR(sc, NIG_REG_LLH0_BRB1_DRV_MASK_MF + params->port * 4,
13921 		       en * 0x3);
13922 	}
13923 
13924 	REG_WR(sc, (params->port ? NIG_REG_LLH1_BRB1_NOT_MCP :
13925 		    NIG_REG_LLH0_BRB1_NOT_MCP), en);
13926 }
elink_avoid_link_flap(struct elink_params * params,struct elink_vars * vars)13927 static elink_status_t elink_avoid_link_flap(struct elink_params *params,
13928 					    struct elink_vars *vars)
13929 {
13930 	uint32_t phy_idx;
13931 	uint32_t dont_clear_stat, lfa_sts;
13932 	struct bnx2x_softc *sc = params->sc;
13933 
13934 	elink_set_mdio_emac_per_phy(sc, params);
13935 	/* Sync the link parameters */
13936 	elink_link_status_update(params, vars);
13937 
13938 	/*
13939 	 * The module verification was already done by previous link owner,
13940 	 * so this call is meant only to get warning message
13941 	 */
13942 
13943 	for (phy_idx = ELINK_INT_PHY; phy_idx < params->num_phys; phy_idx++) {
13944 		struct elink_phy *phy = &params->phy[phy_idx];
13945 		if (phy->phy_specific_func) {
13946 			ELINK_DEBUG_P0(sc, "Calling PHY specific func");
13947 			phy->phy_specific_func(phy, params, ELINK_PHY_INIT);
13948 		}
13949 		if ((phy->media_type == ELINK_ETH_PHY_SFPP_10G_FIBER) ||
13950 		    (phy->media_type == ELINK_ETH_PHY_SFP_1G_FIBER) ||
13951 		    (phy->media_type == ELINK_ETH_PHY_DA_TWINAX))
13952 			elink_verify_sfp_module(phy, params);
13953 	}
13954 	lfa_sts = REG_RD(sc, params->lfa_base +
13955 			 offsetof(struct shmem_lfa,
13956 				  lfa_sts));
13957 
13958 	dont_clear_stat = lfa_sts & SHMEM_LFA_DONT_CLEAR_STAT;
13959 
13960 	/* Re-enable the NIG/MAC */
13961 	if (CHIP_IS_E3(sc)) {
13962 		if (!dont_clear_stat) {
13963 			REG_WR(sc, GRCBASE_MISC +
13964 			       MISC_REGISTERS_RESET_REG_2_CLEAR,
13965 			       (MISC_REGISTERS_RESET_REG_2_MSTAT0 <<
13966 				params->port));
13967 			REG_WR(sc, GRCBASE_MISC +
13968 			       MISC_REGISTERS_RESET_REG_2_SET,
13969 			       (MISC_REGISTERS_RESET_REG_2_MSTAT0 <<
13970 				params->port));
13971 		}
13972 		if (vars->line_speed < ELINK_SPEED_10000)
13973 			elink_umac_enable(params, vars, 0);
13974 		else
13975 			elink_xmac_enable(params, vars, 0);
13976 	} else {
13977 		if (vars->line_speed < ELINK_SPEED_10000)
13978 			elink_emac_enable(params, vars, 0);
13979 		else
13980 			elink_bmac_enable(params, vars, 0, !dont_clear_stat);
13981 	}
13982 
13983 	/* Increment LFA count */
13984 	lfa_sts = ((lfa_sts & ~LINK_FLAP_AVOIDANCE_COUNT_MASK) |
13985 		   (((((lfa_sts & LINK_FLAP_AVOIDANCE_COUNT_MASK) >>
13986 		       LINK_FLAP_AVOIDANCE_COUNT_OFFSET) + 1) & 0xff)
13987 		    << LINK_FLAP_AVOIDANCE_COUNT_OFFSET));
13988 	/* Clear link flap reason */
13989 	lfa_sts &= ~LFA_LINK_FLAP_REASON_MASK;
13990 
13991 	REG_WR(sc, params->lfa_base +
13992 	       offsetof(struct shmem_lfa, lfa_sts), lfa_sts);
13993 
13994 	/* Disable NIG DRAIN */
13995 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13996 
13997 	/* Enable interrupts */
13998 	elink_link_int_enable(params);
13999 	return ELINK_STATUS_OK;
14000 }
14001 
elink_cannot_avoid_link_flap(struct elink_params * params,struct elink_vars * vars,int lfa_status)14002 static void elink_cannot_avoid_link_flap(struct elink_params *params,
14003 					 struct elink_vars *vars,
14004 					 int lfa_status)
14005 {
14006 	uint32_t lfa_sts, cfg_idx, tmp_val;
14007 	struct bnx2x_softc *sc = params->sc;
14008 
14009 	elink_link_reset(params, vars, 1);
14010 
14011 	if (!params->lfa_base)
14012 		return;
14013 	/* Store the new link parameters */
14014 	REG_WR(sc, params->lfa_base +
14015 	       offsetof(struct shmem_lfa, req_duplex),
14016 	       params->req_duplex[0] | (params->req_duplex[1] << 16));
14017 
14018 	REG_WR(sc, params->lfa_base +
14019 	       offsetof(struct shmem_lfa, req_flow_ctrl),
14020 	       params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16));
14021 
14022 	REG_WR(sc, params->lfa_base +
14023 	       offsetof(struct shmem_lfa, req_line_speed),
14024 	       params->req_line_speed[0] | (params->req_line_speed[1] << 16));
14025 
14026 	for (cfg_idx = 0; cfg_idx < SHMEM_LINK_CONFIG_SIZE; cfg_idx++) {
14027 		REG_WR(sc, params->lfa_base +
14028 		       offsetof(struct shmem_lfa,
14029 				speed_cap_mask[cfg_idx]),
14030 		       params->speed_cap_mask[cfg_idx]);
14031 	}
14032 
14033 	tmp_val = REG_RD(sc, params->lfa_base +
14034 			 offsetof(struct shmem_lfa, additional_config));
14035 	tmp_val &= ~REQ_FC_AUTO_ADV_MASK;
14036 	tmp_val |= params->req_fc_auto_adv;
14037 
14038 	REG_WR(sc, params->lfa_base +
14039 	       offsetof(struct shmem_lfa, additional_config), tmp_val);
14040 
14041 	lfa_sts = REG_RD(sc, params->lfa_base +
14042 			 offsetof(struct shmem_lfa, lfa_sts));
14043 
14044 	/* Clear the "Don't Clear Statistics" bit, and set reason */
14045 	lfa_sts &= ~SHMEM_LFA_DONT_CLEAR_STAT;
14046 
14047 	/* Set link flap reason */
14048 	lfa_sts &= ~LFA_LINK_FLAP_REASON_MASK;
14049 	lfa_sts |= ((lfa_status & LFA_LINK_FLAP_REASON_MASK) <<
14050 		    LFA_LINK_FLAP_REASON_OFFSET);
14051 
14052 	/* Increment link flap counter */
14053 	lfa_sts = ((lfa_sts & ~LINK_FLAP_COUNT_MASK) |
14054 		   (((((lfa_sts & LINK_FLAP_COUNT_MASK) >>
14055 		       LINK_FLAP_COUNT_OFFSET) + 1) & 0xff)
14056 		    << LINK_FLAP_COUNT_OFFSET));
14057 	REG_WR(sc, params->lfa_base +
14058 	       offsetof(struct shmem_lfa, lfa_sts), lfa_sts);
14059 	/* Proceed with regular link initialization */
14060 }
14061 
elink_phy_init(struct elink_params * params,struct elink_vars * vars)14062 elink_status_t elink_phy_init(struct elink_params *params,
14063 			      struct elink_vars *vars)
14064 {
14065 	int lfa_status;
14066 	struct bnx2x_softc *sc = params->sc;
14067 	ELINK_DEBUG_P0(sc, "Phy Initialization started");
14068 	ELINK_DEBUG_P2(sc, "(1) req_speed %d, req_flowctrl %d",
14069 		   params->req_line_speed[0], params->req_flow_ctrl[0]);
14070 	ELINK_DEBUG_P2(sc, "(2) req_speed %d, req_flowctrl %d",
14071 		   params->req_line_speed[1], params->req_flow_ctrl[1]);
14072 	ELINK_DEBUG_P1(sc, "req_adv_flow_ctrl 0x%x", params->req_fc_auto_adv);
14073 	vars->link_status = 0;
14074 	vars->phy_link_up = 0;
14075 	vars->link_up = 0;
14076 	vars->line_speed = 0;
14077 	vars->duplex = DUPLEX_FULL;
14078 	vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
14079 	vars->mac_type = ELINK_MAC_TYPE_NONE;
14080 	vars->phy_flags = 0;
14081 	vars->check_kr2_recovery_cnt = 0;
14082 	params->link_flags = ELINK_PHY_INITIALIZED;
14083 	/* Driver opens NIG-BRB filters */
14084 	elink_set_rx_filter(params, 1);
14085 	elink_chng_link_count(params, 1);
14086 	/* Check if link flap can be avoided */
14087 	lfa_status = elink_check_lfa(params);
14088 
14089 	ELINK_DEBUG_P3(sc, " params : port = %x, loopback_mode = %x req_duplex = %x",
14090 		       params->port, params->loopback_mode,
14091 		       params->req_duplex[0]);
14092 	ELINK_DEBUG_P3(sc, " params : switch_cfg = %x, lane_config = %x req_duplex[1] = %x",
14093 		       params->switch_cfg, params->lane_config,
14094 		       params->req_duplex[1]);
14095 	ELINK_DEBUG_P3(sc, " params : chip_id = %x, feature_config_flags = %x, num_phys = %x",
14096 		       params->chip_id, params->feature_config_flags,
14097 		       params->num_phys);
14098 	ELINK_DEBUG_P3(sc, " params : rsrv = %x, eee_mode = %x, hw_led_mode = %x",
14099 		       params->rsrv, params->eee_mode, params->hw_led_mode);
14100 	ELINK_DEBUG_P3(sc, " params : multi_phy = %x, req_fc_auto_adv = %x, link_flags = %x",
14101 		       params->multi_phy_config, params->req_fc_auto_adv,
14102 		       params->link_flags);
14103 	ELINK_DEBUG_P2(sc, " params : lfa_base = %x, link_attr = %x",
14104 		       params->lfa_base, params->link_attr_sync);
14105 	if (lfa_status == 0) {
14106 		ELINK_DEBUG_P0(sc, "Link Flap Avoidance in progress");
14107 		return elink_avoid_link_flap(params, vars);
14108 	}
14109 
14110 	ELINK_DEBUG_P1(sc, "Cannot avoid link flap lfa_sta=0x%x",
14111 		       lfa_status);
14112 	elink_cannot_avoid_link_flap(params, vars, lfa_status);
14113 
14114 	/* Disable attentions */
14115 	elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + params->port * 4,
14116 		       (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14117 			ELINK_NIG_MASK_XGXS0_LINK10G |
14118 			ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14119 			ELINK_NIG_MASK_MI_INT));
14120 #ifdef ELINK_INCLUDE_EMUL
14121 	if (!(params->feature_config_flags &
14122 	      ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC))
14123 #endif
14124 
14125 	elink_emac_init(params, vars);
14126 
14127 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
14128 		vars->link_status |= LINK_STATUS_PFC_ENABLED;
14129 
14130 	if ((params->num_phys == 0) &&
14131 	    !CHIP_REV_IS_SLOW(sc)) {
14132 		ELINK_DEBUG_P0(sc, "No phy found for initialization !!");
14133 		return ELINK_STATUS_ERROR;
14134 	}
14135 	set_phy_vars(params, vars);
14136 
14137 	ELINK_DEBUG_P1(sc, "Num of phys on board: %d", params->num_phys);
14138 #ifdef ELINK_INCLUDE_FPGA
14139 	if (CHIP_REV_IS_FPGA(sc)) {
14140 		return elink_init_fpga(params, vars);
14141 	} else
14142 #endif
14143 #ifdef ELINK_INCLUDE_EMUL
14144 	if (CHIP_REV_IS_EMUL(sc)) {
14145 		return elink_init_emul(params, vars);
14146 	} else
14147 #endif
14148 	switch (params->loopback_mode) {
14149 	case ELINK_LOOPBACK_BMAC:
14150 		elink_init_bmac_loopback(params, vars);
14151 		break;
14152 	case ELINK_LOOPBACK_EMAC:
14153 		elink_init_emac_loopback(params, vars);
14154 		break;
14155 	case ELINK_LOOPBACK_XMAC:
14156 		elink_init_xmac_loopback(params, vars);
14157 		break;
14158 	case ELINK_LOOPBACK_UMAC:
14159 		elink_init_umac_loopback(params, vars);
14160 		break;
14161 	case ELINK_LOOPBACK_XGXS:
14162 	case ELINK_LOOPBACK_EXT_PHY:
14163 		elink_init_xgxs_loopback(params, vars);
14164 		break;
14165 	default:
14166 		if (!CHIP_IS_E3(sc)) {
14167 			if (params->switch_cfg == ELINK_SWITCH_CFG_10G)
14168 				elink_xgxs_deassert(params);
14169 			else
14170 				elink_serdes_deassert(sc, params->port);
14171 		}
14172 		elink_link_initialize(params, vars);
14173 		DELAY(1000 * 30);
14174 		elink_link_int_enable(params);
14175 		break;
14176 	}
14177 	elink_update_mng(params, vars->link_status);
14178 
14179 	elink_update_mng_eee(params, vars->eee_status);
14180 	return ELINK_STATUS_OK;
14181 }
14182 
elink_link_reset(struct elink_params * params,struct elink_vars * vars,uint8_t reset_ext_phy)14183 elink_status_t elink_link_reset(struct elink_params *params,
14184 		     struct elink_vars *vars,
14185 		     uint8_t reset_ext_phy)
14186 {
14187 	struct bnx2x_softc *sc = params->sc;
14188 	uint8_t phy_index, port = params->port, clear_latch_ind = 0;
14189 	ELINK_DEBUG_P1(sc, "Resetting the link of port %d", port);
14190 	/* Disable attentions */
14191 	vars->link_status = 0;
14192 	elink_chng_link_count(params, 1);
14193 	elink_update_mng(params, vars->link_status);
14194 	vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
14195 			      SHMEM_EEE_ACTIVE_BIT);
14196 	elink_update_mng_eee(params, vars->eee_status);
14197 	elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port * 4,
14198 		       (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14199 			ELINK_NIG_MASK_XGXS0_LINK10G |
14200 			ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14201 			ELINK_NIG_MASK_MI_INT));
14202 
14203 	/* Activate nig drain */
14204 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port * 4, 1);
14205 
14206 	/* Disable nig egress interface */
14207 	if (!CHIP_IS_E3(sc)) {
14208 		REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port * 4, 0);
14209 		REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port * 4, 0);
14210 	}
14211 
14212 #ifdef ELINK_INCLUDE_EMUL
14213 	/* Stop BigMac rx */
14214 	if (!(params->feature_config_flags &
14215 	      ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC))
14216 #endif
14217 		if (!CHIP_IS_E3(sc))
14218 			elink_set_bmac_rx(sc, params->chip_id, port, 0);
14219 #ifdef ELINK_INCLUDE_EMUL
14220 	/* Stop XMAC/UMAC rx */
14221 	if (!(params->feature_config_flags &
14222 	      ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC))
14223 #endif
14224 		if (CHIP_IS_E3(sc) &&
14225 		!CHIP_REV_IS_FPGA(sc)) {
14226 			elink_set_xmac_rxtx(params, 0);
14227 			elink_set_umac_rxtx(params, 0);
14228 		}
14229 	/* Disable emac */
14230 	if (!CHIP_IS_E3(sc))
14231 		REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port * 4, 0);
14232 
14233 	DELAY(1000 * 10);
14234 	/* The PHY reset is controlled by GPIO 1
14235 	 * Hold it as vars low
14236 	 */
14237 	 /* Clear link led */
14238 	elink_set_mdio_emac_per_phy(sc, params);
14239 	elink_set_led(params, vars, ELINK_LED_MODE_OFF, 0);
14240 
14241 	if (reset_ext_phy && (!CHIP_REV_IS_SLOW(sc))) {
14242 		for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
14243 		      phy_index++) {
14244 			if (params->phy[phy_index].link_reset) {
14245 				elink_set_aer_mmd(params,
14246 						  &params->phy[phy_index]);
14247 				params->phy[phy_index].link_reset(
14248 					&params->phy[phy_index],
14249 					params);
14250 			}
14251 			if (params->phy[phy_index].flags &
14252 			    ELINK_FLAGS_REARM_LATCH_SIGNAL)
14253 				clear_latch_ind = 1;
14254 		}
14255 	}
14256 
14257 	if (clear_latch_ind) {
14258 		/* Clear latching indication */
14259 		elink_rearm_latch_signal(sc, port, 0);
14260 		elink_bits_dis(sc, NIG_REG_LATCH_BC_0 + port * 4,
14261 			       1 << ELINK_NIG_LATCH_BC_ENABLE_MI_INT);
14262 	}
14263 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
14264 	if (!CHIP_REV_IS_SLOW(sc))
14265 #endif
14266 	if (params->phy[ELINK_INT_PHY].link_reset)
14267 		params->phy[ELINK_INT_PHY].link_reset(
14268 			&params->phy[ELINK_INT_PHY], params);
14269 
14270 	/* Disable nig ingress interface */
14271 	if (!CHIP_IS_E3(sc)) {
14272 		/* Reset BigMac */
14273 		REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
14274 		       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
14275 		REG_WR(sc, NIG_REG_BMAC0_IN_EN + port * 4, 0);
14276 		REG_WR(sc, NIG_REG_EMAC0_IN_EN + port * 4, 0);
14277 	} else {
14278 		uint32_t xmac_base = (params->port) ? GRCBASE_XMAC1 :
14279 						      GRCBASE_XMAC0;
14280 		elink_set_xumac_nig(params, 0, 0);
14281 		if (REG_RD(sc, MISC_REG_RESET_REG_2) &
14282 		    MISC_REGISTERS_RESET_REG_2_XMAC)
14283 			REG_WR(sc, xmac_base + XMAC_REG_CTRL,
14284 			       XMAC_CTRL_REG_SOFT_RESET);
14285 	}
14286 	vars->link_up = 0;
14287 	vars->phy_flags = 0;
14288 	return ELINK_STATUS_OK;
14289 }
elink_lfa_reset(struct elink_params * params,struct elink_vars * vars)14290 elink_status_t elink_lfa_reset(struct elink_params *params,
14291 			       struct elink_vars *vars)
14292 {
14293 	struct bnx2x_softc *sc = params->sc;
14294 	vars->link_up = 0;
14295 	vars->phy_flags = 0;
14296 	params->link_flags &= ~ELINK_PHY_INITIALIZED;
14297 	if (!params->lfa_base)
14298 		return elink_link_reset(params, vars, 1);
14299 	/*
14300 	 * Activate NIG drain so that during this time the device won't send
14301 	 * anything while it is unable to response.
14302 	 */
14303 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 1);
14304 
14305 	/*
14306 	 * Close gracefully the gate from BMAC to NIG such that no half packets
14307 	 * are passed.
14308 	 */
14309 	if (!CHIP_IS_E3(sc))
14310 		elink_set_bmac_rx(sc, params->chip_id, params->port, 0);
14311 
14312 	if (CHIP_IS_E3(sc)) {
14313 		elink_set_xmac_rxtx(params, 0);
14314 		elink_set_umac_rxtx(params, 0);
14315 	}
14316 	/* Wait 10ms for the pipe to clean up*/
14317 	DELAY(1000 * 10);
14318 
14319 	/* Clean the NIG-BRB using the network filters in a way that will
14320 	 * not cut a packet in the middle.
14321 	 */
14322 	elink_set_rx_filter(params, 0);
14323 
14324 	/*
14325 	 * Re-open the gate between the BMAC and the NIG, after verifying the
14326 	 * gate to the BRB is closed, otherwise packets may arrive to the
14327 	 * firmware before driver had initialized it. The target is to achieve
14328 	 * minimum management protocol down time.
14329 	 */
14330 	if (!CHIP_IS_E3(sc))
14331 		elink_set_bmac_rx(sc, params->chip_id, params->port, 1);
14332 
14333 	if (CHIP_IS_E3(sc)) {
14334 		elink_set_xmac_rxtx(params, 1);
14335 		elink_set_umac_rxtx(params, 1);
14336 	}
14337 	/* Disable NIG drain */
14338 	REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
14339 	return ELINK_STATUS_OK;
14340 }
14341 
14342 /****************************************************************************/
14343 /*				Common function				    */
14344 /****************************************************************************/
elink_8073_common_init_phy(struct bnx2x_softc * sc,uint32_t shmem_base_path[],uint32_t shmem2_base_path[],uint8_t phy_index,__rte_unused uint32_t chip_id)14345 static elink_status_t elink_8073_common_init_phy(struct bnx2x_softc *sc,
14346 				      uint32_t shmem_base_path[],
14347 				      uint32_t shmem2_base_path[],
14348 				      uint8_t phy_index,
14349 				      __rte_unused uint32_t chip_id)
14350 {
14351 	struct elink_phy phy[PORT_MAX];
14352 	struct elink_phy *phy_blk[PORT_MAX];
14353 	uint16_t val;
14354 	int8_t port = 0;
14355 	int8_t port_of_path = 0;
14356 	uint32_t swap_val, swap_override;
14357 	swap_val = REG_RD(sc,  NIG_REG_PORT_SWAP);
14358 	swap_override = REG_RD(sc,  NIG_REG_STRAP_OVERRIDE);
14359 	port ^= (swap_val && swap_override);
14360 	elink_ext_phy_hw_reset(sc, port);
14361 	/* PART1 - Reset both phys */
14362 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14363 		uint32_t shmem_base, shmem2_base;
14364 		/* In E2, same phy is using for port0 of the two paths */
14365 		if (CHIP_IS_E1x(sc)) {
14366 			shmem_base = shmem_base_path[0];
14367 			shmem2_base = shmem2_base_path[0];
14368 			port_of_path = port;
14369 		} else {
14370 			shmem_base = shmem_base_path[port];
14371 			shmem2_base = shmem2_base_path[port];
14372 			port_of_path = 0;
14373 		}
14374 
14375 		/* Extract the ext phy address for the port */
14376 		if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14377 				       port_of_path, &phy[port]) !=
14378 		    ELINK_STATUS_OK) {
14379 			ELINK_DEBUG_P0(sc, "populate_phy failed");
14380 			return ELINK_STATUS_ERROR;
14381 		}
14382 		/* Disable attentions */
14383 		elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
14384 			       port_of_path * 4,
14385 			       (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14386 				ELINK_NIG_MASK_XGXS0_LINK10G |
14387 				ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14388 				ELINK_NIG_MASK_MI_INT));
14389 
14390 		/* Need to take the phy out of low power mode in order
14391 		 * to write to access its registers
14392 		 */
14393 		elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
14394 			       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
14395 			       port);
14396 
14397 		/* Reset the phy */
14398 		elink_cl45_write(sc, &phy[port],
14399 				 MDIO_PMA_DEVAD,
14400 				 MDIO_PMA_REG_CTRL,
14401 				 1 << 15);
14402 	}
14403 
14404 	/* Add delay of 150ms after reset */
14405 	DELAY(1000 * 150);
14406 
14407 	if (phy[PORT_0].addr & 0x1) {
14408 		phy_blk[PORT_0] = &(phy[PORT_1]);
14409 		phy_blk[PORT_1] = &(phy[PORT_0]);
14410 	} else {
14411 		phy_blk[PORT_0] = &(phy[PORT_0]);
14412 		phy_blk[PORT_1] = &(phy[PORT_1]);
14413 	}
14414 
14415 	/* PART2 - Download firmware to both phys */
14416 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14417 		if (CHIP_IS_E1x(sc))
14418 			port_of_path = port;
14419 		else
14420 			port_of_path = 0;
14421 
14422 		ELINK_DEBUG_P1(sc, "Loading spirom for phy address 0x%x",
14423 			   phy_blk[port]->addr);
14424 		if (elink_8073_8727_external_rom_boot(sc, phy_blk[port],
14425 						      port_of_path))
14426 			return ELINK_STATUS_ERROR;
14427 
14428 		/* Only set bit 10 = 1 (Tx power down) */
14429 		elink_cl45_read(sc, phy_blk[port],
14430 				MDIO_PMA_DEVAD,
14431 				MDIO_PMA_REG_TX_POWER_DOWN, &val);
14432 
14433 		/* Phase1 of TX_POWER_DOWN reset */
14434 		elink_cl45_write(sc, phy_blk[port],
14435 				 MDIO_PMA_DEVAD,
14436 				 MDIO_PMA_REG_TX_POWER_DOWN,
14437 				 (val | 1 << 10));
14438 	}
14439 
14440 	/* Toggle Transmitter: Power down and then up with 600ms delay
14441 	 * between
14442 	 */
14443 	DELAY(1000 * 600);
14444 
14445 	/* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
14446 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14447 		/* Phase2 of POWER_DOWN_RESET */
14448 		/* Release bit 10 (Release Tx power down) */
14449 		elink_cl45_read(sc, phy_blk[port],
14450 				MDIO_PMA_DEVAD,
14451 				MDIO_PMA_REG_TX_POWER_DOWN, &val);
14452 
14453 		elink_cl45_write(sc, phy_blk[port],
14454 				MDIO_PMA_DEVAD,
14455 				MDIO_PMA_REG_TX_POWER_DOWN,
14456 				(val & (~(1 << 10))));
14457 		DELAY(1000 * 15);
14458 
14459 		/* Read modify write the SPI-ROM version select register */
14460 		elink_cl45_read(sc, phy_blk[port],
14461 				MDIO_PMA_DEVAD,
14462 				MDIO_PMA_REG_EDC_FFE_MAIN, &val);
14463 		elink_cl45_write(sc, phy_blk[port],
14464 				 MDIO_PMA_DEVAD,
14465 				 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1 << 12)));
14466 
14467 		/* set GPIO2 back to LOW */
14468 		elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
14469 			       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
14470 	}
14471 	return ELINK_STATUS_OK;
14472 }
elink_8726_common_init_phy(struct bnx2x_softc * sc,uint32_t shmem_base_path[],uint32_t shmem2_base_path[],uint8_t phy_index,__rte_unused uint32_t chip_id)14473 static elink_status_t elink_8726_common_init_phy(struct bnx2x_softc *sc,
14474 				      uint32_t shmem_base_path[],
14475 				      uint32_t shmem2_base_path[],
14476 				      uint8_t phy_index,
14477 				      __rte_unused uint32_t chip_id)
14478 {
14479 	uint32_t val;
14480 	int8_t port;
14481 	struct elink_phy phy;
14482 	/* Use port1 because of the static port-swap */
14483 	/* Enable the module detection interrupt */
14484 	val = REG_RD(sc, MISC_REG_GPIO_EVENT_EN);
14485 	val |= ((1 << MISC_REGISTERS_GPIO_3) |
14486 		(1 << (MISC_REGISTERS_GPIO_3 +
14487 		 MISC_REGISTERS_GPIO_PORT_SHIFT)));
14488 	REG_WR(sc, MISC_REG_GPIO_EVENT_EN, val);
14489 
14490 	elink_ext_phy_hw_reset(sc, 0);
14491 	DELAY(1000 * 5);
14492 	for (port = 0; port < PORT_MAX; port++) {
14493 		uint32_t shmem_base, shmem2_base;
14494 
14495 		/* In E2, same phy is using for port0 of the two paths */
14496 		if (CHIP_IS_E1x(sc)) {
14497 			shmem_base = shmem_base_path[0];
14498 			shmem2_base = shmem2_base_path[0];
14499 		} else {
14500 			shmem_base = shmem_base_path[port];
14501 			shmem2_base = shmem2_base_path[port];
14502 		}
14503 		/* Extract the ext phy address for the port */
14504 		if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14505 				       port, &phy) !=
14506 		    ELINK_STATUS_OK) {
14507 			ELINK_DEBUG_P0(sc, "populate phy failed");
14508 			return ELINK_STATUS_ERROR;
14509 		}
14510 
14511 		/* Reset phy*/
14512 		elink_cl45_write(sc, &phy,
14513 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
14514 
14515 
14516 		/* Set fault module detected LED on */
14517 		elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_0,
14518 			       MISC_REGISTERS_GPIO_HIGH,
14519 			       port);
14520 	}
14521 
14522 	return ELINK_STATUS_OK;
14523 }
elink_get_ext_phy_reset_gpio(struct bnx2x_softc * sc,uint32_t shmem_base,uint8_t * io_gpio,uint8_t * io_port)14524 static void elink_get_ext_phy_reset_gpio(struct bnx2x_softc *sc,
14525 					 uint32_t shmem_base,
14526 					 uint8_t *io_gpio, uint8_t *io_port)
14527 {
14528 
14529 	uint32_t phy_gpio_reset = REG_RD(sc, shmem_base +
14530 					  offsetof(struct shmem_region,
14531 				dev_info.port_hw_config[PORT_0].default_cfg));
14532 	switch (phy_gpio_reset) {
14533 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
14534 		*io_gpio = 0;
14535 		*io_port = 0;
14536 		break;
14537 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
14538 		*io_gpio = 1;
14539 		*io_port = 0;
14540 		break;
14541 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
14542 		*io_gpio = 2;
14543 		*io_port = 0;
14544 		break;
14545 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
14546 		*io_gpio = 3;
14547 		*io_port = 0;
14548 		break;
14549 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
14550 		*io_gpio = 0;
14551 		*io_port = 1;
14552 		break;
14553 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
14554 		*io_gpio = 1;
14555 		*io_port = 1;
14556 		break;
14557 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
14558 		*io_gpio = 2;
14559 		*io_port = 1;
14560 		break;
14561 	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
14562 		*io_gpio = 3;
14563 		*io_port = 1;
14564 		break;
14565 	default:
14566 		/* Don't override the io_gpio and io_port */
14567 		break;
14568 	}
14569 }
14570 
elink_8727_common_init_phy(struct bnx2x_softc * sc,uint32_t shmem_base_path[],uint32_t shmem2_base_path[],uint8_t phy_index,__rte_unused uint32_t chip_id)14571 static elink_status_t elink_8727_common_init_phy(struct bnx2x_softc *sc,
14572 				      uint32_t shmem_base_path[],
14573 				      uint32_t shmem2_base_path[],
14574 				      uint8_t phy_index,
14575 				      __rte_unused uint32_t chip_id)
14576 {
14577 	int8_t port, reset_gpio;
14578 	uint32_t swap_val, swap_override;
14579 	struct elink_phy phy[PORT_MAX];
14580 	struct elink_phy *phy_blk[PORT_MAX];
14581 	int8_t port_of_path;
14582 	swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
14583 	swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
14584 
14585 	reset_gpio = MISC_REGISTERS_GPIO_1;
14586 	port = 1;
14587 
14588 	/* Retrieve the reset gpio/port which control the reset.
14589 	 * Default is GPIO1, PORT1
14590 	 */
14591 	elink_get_ext_phy_reset_gpio(sc, shmem_base_path[0],
14592 				     (uint8_t *)&reset_gpio, (uint8_t *)&port);
14593 
14594 	/* Calculate the port based on port swap */
14595 	port ^= (swap_val && swap_override);
14596 
14597 	/* Initiate PHY reset*/
14598 	elink_cb_gpio_write(sc, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
14599 		       port);
14600 	DELAY(1000 * 1);
14601 	elink_cb_gpio_write(sc, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
14602 		       port);
14603 
14604 	DELAY(1000 * 5);
14605 
14606 	/* PART1 - Reset both phys */
14607 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14608 		uint32_t shmem_base, shmem2_base;
14609 
14610 		/* In E2, same phy is using for port0 of the two paths */
14611 		if (CHIP_IS_E1x(sc)) {
14612 			shmem_base = shmem_base_path[0];
14613 			shmem2_base = shmem2_base_path[0];
14614 			port_of_path = port;
14615 		} else {
14616 			shmem_base = shmem_base_path[port];
14617 			shmem2_base = shmem2_base_path[port];
14618 			port_of_path = 0;
14619 		}
14620 
14621 		/* Extract the ext phy address for the port */
14622 		if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14623 				       port_of_path, &phy[port]) !=
14624 				       ELINK_STATUS_OK) {
14625 			ELINK_DEBUG_P0(sc, "populate phy failed");
14626 			return ELINK_STATUS_ERROR;
14627 		}
14628 		/* disable attentions */
14629 		elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
14630 			       port_of_path * 4,
14631 			       (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14632 				ELINK_NIG_MASK_XGXS0_LINK10G |
14633 				ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14634 				ELINK_NIG_MASK_MI_INT));
14635 
14636 
14637 		/* Reset the phy */
14638 		elink_cl45_write(sc, &phy[port],
14639 				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1 << 15);
14640 	}
14641 
14642 	/* Add delay of 150ms after reset */
14643 	DELAY(1000 * 150);
14644 	if (phy[PORT_0].addr & 0x1) {
14645 		phy_blk[PORT_0] = &(phy[PORT_1]);
14646 		phy_blk[PORT_1] = &(phy[PORT_0]);
14647 	} else {
14648 		phy_blk[PORT_0] = &(phy[PORT_0]);
14649 		phy_blk[PORT_1] = &(phy[PORT_1]);
14650 	}
14651 	/* PART2 - Download firmware to both phys */
14652 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14653 		if (CHIP_IS_E1x(sc))
14654 			port_of_path = port;
14655 		else
14656 			port_of_path = 0;
14657 		ELINK_DEBUG_P1(sc, "Loading spirom for phy address 0x%x",
14658 			   phy_blk[port]->addr);
14659 		if (elink_8073_8727_external_rom_boot(sc, phy_blk[port],
14660 						      port_of_path))
14661 			return ELINK_STATUS_ERROR;
14662 		/* Disable PHY transmitter output */
14663 		elink_cl45_write(sc, phy_blk[port],
14664 				 MDIO_PMA_DEVAD,
14665 				 MDIO_PMA_REG_TX_DISABLE, 1);
14666 
14667 	}
14668 	return ELINK_STATUS_OK;
14669 }
14670 
elink_84833_common_init_phy(struct bnx2x_softc * sc,uint32_t shmem_base_path[],__rte_unused uint32_t shmem2_base_path[],__rte_unused uint8_t phy_index,uint32_t chip_id)14671 static elink_status_t elink_84833_common_init_phy(struct bnx2x_softc *sc,
14672 				uint32_t shmem_base_path[],
14673 				__rte_unused uint32_t shmem2_base_path[],
14674 				__rte_unused uint8_t phy_index,
14675 				uint32_t chip_id)
14676 {
14677 	uint8_t reset_gpios;
14678 	reset_gpios = elink_84833_get_reset_gpios(sc, shmem_base_path, chip_id);
14679 	elink_cb_gpio_mult_write(sc, reset_gpios,
14680 				 MISC_REGISTERS_GPIO_OUTPUT_LOW);
14681 	DELAY(10);
14682 	elink_cb_gpio_mult_write(sc, reset_gpios,
14683 				 MISC_REGISTERS_GPIO_OUTPUT_HIGH);
14684 	ELINK_DEBUG_P1(sc, "84833 reset pulse on pin values 0x%x",
14685 		reset_gpios);
14686 	return ELINK_STATUS_OK;
14687 }
elink_ext_phy_common_init(struct bnx2x_softc * sc,uint32_t shmem_base_path[],uint32_t shmem2_base_path[],uint8_t phy_index,uint32_t ext_phy_type,uint32_t chip_id)14688 static elink_status_t elink_ext_phy_common_init(struct bnx2x_softc *sc,
14689 				     uint32_t shmem_base_path[],
14690 				     uint32_t shmem2_base_path[],
14691 				     uint8_t phy_index,
14692 				     uint32_t ext_phy_type, uint32_t chip_id)
14693 {
14694 	elink_status_t rc = ELINK_STATUS_OK;
14695 
14696 	switch (ext_phy_type) {
14697 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8073:
14698 		rc = elink_8073_common_init_phy(sc, shmem_base_path,
14699 						shmem2_base_path,
14700 						phy_index, chip_id);
14701 		break;
14702 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
14703 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
14704 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727_NOC:
14705 		rc = elink_8727_common_init_phy(sc, shmem_base_path,
14706 						shmem2_base_path,
14707 						phy_index, chip_id);
14708 		break;
14709 
14710 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726:
14711 		/* GPIO1 affects both ports, so there's need to pull
14712 		 * it for single port alone
14713 		 */
14714 		rc = elink_8726_common_init_phy(sc, shmem_base_path,
14715 						shmem2_base_path,
14716 						phy_index, chip_id);
14717 		break;
14718 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84833:
14719 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834:
14720 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858:
14721 		/* GPIO3's are linked, and so both need to be toggled
14722 		 * to obtain required 2us pulse.
14723 		 */
14724 		rc = elink_84833_common_init_phy(sc, shmem_base_path,
14725 						shmem2_base_path,
14726 						phy_index, chip_id);
14727 		break;
14728 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
14729 		rc = ELINK_STATUS_ERROR;
14730 		break;
14731 	default:
14732 		ELINK_DEBUG_P1(sc,
14733 			   "ext_phy 0x%x common init not required",
14734 			   ext_phy_type);
14735 		break;
14736 	}
14737 
14738 	if (rc != ELINK_STATUS_OK)
14739 		elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED, 0);
14740 				     /* "Warning: PHY was not initialized,"
14741 				      * " Port %d",
14742 				      */
14743 
14744 	return rc;
14745 }
14746 
elink_common_init_phy(struct bnx2x_softc * sc,uint32_t shmem_base_path[],uint32_t shmem2_base_path[],uint32_t chip_id,__rte_unused uint8_t one_port_enabled)14747 elink_status_t elink_common_init_phy(struct bnx2x_softc *sc,
14748 			  uint32_t shmem_base_path[],
14749 			  uint32_t shmem2_base_path[], uint32_t chip_id,
14750 			  __rte_unused uint8_t one_port_enabled)
14751 {
14752 	elink_status_t rc = ELINK_STATUS_OK;
14753 	uint32_t phy_ver, val;
14754 	uint8_t phy_index = 0;
14755 	uint32_t ext_phy_type, ext_phy_config;
14756 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
14757 	if (CHIP_REV_IS_EMUL(sc) || CHIP_REV_IS_FPGA(sc))
14758 		return ELINK_STATUS_OK;
14759 #endif
14760 
14761 	elink_set_mdio_clk(sc, chip_id, GRCBASE_EMAC0);
14762 	elink_set_mdio_clk(sc, chip_id, GRCBASE_EMAC1);
14763 	ELINK_DEBUG_P0(sc, "Begin common phy init");
14764 	if (CHIP_IS_E3(sc)) {
14765 		/* Enable EPIO */
14766 		val = REG_RD(sc, MISC_REG_GEN_PURP_HWG);
14767 		REG_WR(sc, MISC_REG_GEN_PURP_HWG, val | 1);
14768 	}
14769 	/* Check if common init was already done */
14770 	phy_ver = REG_RD(sc, shmem_base_path[0] +
14771 			 offsetof(struct shmem_region,
14772 				  port_mb[PORT_0].ext_phy_fw_version));
14773 	if (phy_ver) {
14774 		ELINK_DEBUG_P1(sc, "Not doing common init; phy ver is 0x%x",
14775 			       phy_ver);
14776 		return ELINK_STATUS_OK;
14777 	}
14778 
14779 	/* Read the ext_phy_type for arbitrary port(0) */
14780 	for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
14781 	      phy_index++) {
14782 		ext_phy_config = elink_get_ext_phy_config(sc,
14783 							  shmem_base_path[0],
14784 							  phy_index, 0);
14785 		ext_phy_type = ELINK_XGXS_EXT_PHY_TYPE(ext_phy_config);
14786 		rc |= elink_ext_phy_common_init(sc, shmem_base_path,
14787 						shmem2_base_path,
14788 						phy_index, ext_phy_type,
14789 						chip_id);
14790 	}
14791 	return rc;
14792 }
14793 
elink_check_over_curr(struct elink_params * params,struct elink_vars * vars)14794 static void elink_check_over_curr(struct elink_params *params,
14795 				  struct elink_vars *vars)
14796 {
14797 	struct bnx2x_softc *sc = params->sc;
14798 	uint32_t cfg_pin;
14799 	uint8_t port = params->port;
14800 	uint32_t pin_val;
14801 
14802 	cfg_pin = (REG_RD(sc, params->shmem_base +
14803 			  offsetof(struct shmem_region,
14804 			       dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) &
14805 		   PORT_HW_CFG_E3_OVER_CURRENT_MASK) >>
14806 		PORT_HW_CFG_E3_OVER_CURRENT_SHIFT;
14807 
14808 	/* Ignore check if no external input PIN available */
14809 	if (elink_get_cfg_pin(sc, cfg_pin, &pin_val) != ELINK_STATUS_OK)
14810 		return;
14811 
14812 	if (!pin_val) {
14813 		if ((vars->phy_flags & PHY_OVER_CURRENT_FLAG) == 0) {
14814 			elink_cb_event_log(sc, ELINK_LOG_ID_OVER_CURRENT,
14815 					   params->port);
14816 					/* "Error:  Power fault on Port %d has"
14817 					 *  " been detected and the power to "
14818 					 *  "that SFP+ module has been removed"
14819 					 *  " to prevent failure of the card."
14820 					 *  " Please remove the SFP+ module and"
14821 					 *  " restart the system to clear this"
14822 					 *  " error.",
14823 					 */
14824 			vars->phy_flags |= PHY_OVER_CURRENT_FLAG;
14825 			elink_warpcore_power_module(params, 0);
14826 		}
14827 	} else
14828 		vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG;
14829 }
14830 
14831 /* Returns 0 if no change occurred since last check; 1 otherwise. */
elink_analyze_link_error(struct elink_params * params,struct elink_vars * vars,uint32_t status,uint32_t phy_flag,uint32_t link_flag,uint8_t notify)14832 static uint8_t elink_analyze_link_error(struct elink_params *params,
14833 				    struct elink_vars *vars, uint32_t status,
14834 				    uint32_t phy_flag, uint32_t link_flag,
14835 				    uint8_t notify)
14836 {
14837 	struct bnx2x_softc *sc = params->sc;
14838 	/* Compare new value with previous value */
14839 	uint8_t led_mode;
14840 	uint32_t old_status = (vars->phy_flags & phy_flag) ? 1 : 0;
14841 
14842 	if ((status ^ old_status) == 0)
14843 		return 0;
14844 
14845 	/* If values differ */
14846 	switch (phy_flag) {
14847 	case PHY_HALF_OPEN_CONN_FLAG:
14848 		ELINK_DEBUG_P0(sc, "Analyze Remote Fault");
14849 		break;
14850 	case PHY_SFP_TX_FAULT_FLAG:
14851 		ELINK_DEBUG_P0(sc, "Analyze TX Fault");
14852 		break;
14853 	default:
14854 		ELINK_DEBUG_P0(sc, "Analyze UNKNOWN");
14855 	}
14856 	ELINK_DEBUG_P3(sc, "Link changed:[%x %x]->%x", vars->link_up,
14857 	   old_status, status);
14858 
14859 	/* Do not touch the link in case physical link down */
14860 	if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0)
14861 		return 1;
14862 
14863 	/* a. Update shmem->link_status accordingly
14864 	 * b. Update elink_vars->link_up
14865 	 */
14866 	if (status) {
14867 		vars->link_status &= ~LINK_STATUS_LINK_UP;
14868 		vars->link_status |= link_flag;
14869 		vars->link_up = 0;
14870 		vars->phy_flags |= phy_flag;
14871 
14872 		/* activate nig drain */
14873 		REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 1);
14874 		/* Set LED mode to off since the PHY doesn't know about these
14875 		 * errors
14876 		 */
14877 		led_mode = ELINK_LED_MODE_OFF;
14878 	} else {
14879 		vars->link_status |= LINK_STATUS_LINK_UP;
14880 		vars->link_status &= ~link_flag;
14881 		vars->link_up = 1;
14882 		vars->phy_flags &= ~phy_flag;
14883 		led_mode = ELINK_LED_MODE_OPER;
14884 
14885 		/* Clear nig drain */
14886 		REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
14887 	}
14888 	elink_sync_link(params, vars);
14889 	/* Update the LED according to the link state */
14890 	elink_set_led(params, vars, led_mode, ELINK_SPEED_10000);
14891 
14892 	/* Update link status in the shared memory */
14893 	elink_update_mng(params, vars->link_status);
14894 
14895 	/* C. Trigger General Attention */
14896 	vars->periodic_flags |= ELINK_PERIODIC_FLAGS_LINK_EVENT;
14897 	if (notify)
14898 		elink_cb_notify_link_changed(sc);
14899 
14900 	return 1;
14901 }
14902 
14903 /******************************************************************************
14904  * Description:
14905  *	This function checks for half opened connection change indication.
14906  *	When such change occurs, it calls the elink_analyze_link_error
14907  *	to check if Remote Fault is set or cleared. Reception of remote fault
14908  *	status message in the MAC indicates that the peer's MAC has detected
14909  *	a fault, for example, due to break in the TX side of fiber.
14910  *
14911  ******************************************************************************/
14912 static
elink_check_half_open_conn(struct elink_params * params,struct elink_vars * vars,uint8_t notify)14913 elink_status_t elink_check_half_open_conn(struct elink_params *params,
14914 				struct elink_vars *vars,
14915 				uint8_t notify)
14916 {
14917 	struct bnx2x_softc *sc = params->sc;
14918 	uint32_t lss_status = 0;
14919 	uint32_t mac_base;
14920 	/* In case link status is physically up @ 10G do */
14921 	if (((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0) ||
14922 	    (REG_RD(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port * 4)))
14923 		return ELINK_STATUS_OK;
14924 
14925 	if (CHIP_IS_E3(sc) &&
14926 	    (REG_RD(sc, MISC_REG_RESET_REG_2) &
14927 	      (MISC_REGISTERS_RESET_REG_2_XMAC))) {
14928 		/* Check E3 XMAC */
14929 		/* Note that link speed cannot be queried here, since it may be
14930 		 * zero while link is down. In case UMAC is active, LSS will
14931 		 * simply not be set
14932 		 */
14933 		mac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
14934 
14935 		/* Clear stick bits (Requires rising edge) */
14936 		REG_WR(sc, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
14937 		REG_WR(sc, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
14938 		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
14939 		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
14940 		if (REG_RD(sc, mac_base + XMAC_REG_RX_LSS_STATUS))
14941 			lss_status = 1;
14942 
14943 		elink_analyze_link_error(params, vars, lss_status,
14944 					 PHY_HALF_OPEN_CONN_FLAG,
14945 					 LINK_STATUS_NONE, notify);
14946 	} else if (REG_RD(sc, MISC_REG_RESET_REG_2) &
14947 		   (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) {
14948 		/* Check E1X / E2 BMAC */
14949 		uint32_t lss_status_reg;
14950 		uint32_t wb_data[2];
14951 		mac_base = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
14952 			NIG_REG_INGRESS_BMAC0_MEM;
14953 		/*  Read BIGMAC_REGISTER_RX_LSS_STATUS */
14954 		if (CHIP_IS_E2(sc))
14955 			lss_status_reg = BIGMAC2_REGISTER_RX_LSS_STAT;
14956 		else
14957 			lss_status_reg = BIGMAC_REGISTER_RX_LSS_STATUS;
14958 
14959 		REG_RD_DMAE(sc, mac_base + lss_status_reg, wb_data, 2);
14960 		lss_status = (wb_data[0] > 0);
14961 
14962 		elink_analyze_link_error(params, vars, lss_status,
14963 					 PHY_HALF_OPEN_CONN_FLAG,
14964 					 LINK_STATUS_NONE, notify);
14965 	}
14966 	return ELINK_STATUS_OK;
14967 }
elink_sfp_tx_fault_detection(struct elink_phy * phy,struct elink_params * params,struct elink_vars * vars)14968 static void elink_sfp_tx_fault_detection(struct elink_phy *phy,
14969 					 struct elink_params *params,
14970 					 struct elink_vars *vars)
14971 {
14972 	struct bnx2x_softc *sc = params->sc;
14973 	uint32_t cfg_pin, value = 0;
14974 	uint8_t led_change, port = params->port;
14975 
14976 	/* Get The SFP+ TX_Fault controlling pin ([eg]pio) */
14977 	cfg_pin = (REG_RD(sc, params->shmem_base + offsetof(struct shmem_region,
14978 			  dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
14979 		   PORT_HW_CFG_E3_TX_FAULT_MASK) >>
14980 		  PORT_HW_CFG_E3_TX_FAULT_SHIFT;
14981 
14982 	if (elink_get_cfg_pin(sc, cfg_pin, &value)) {
14983 		ELINK_DEBUG_P1(sc, "Failed to read pin 0x%02x", cfg_pin);
14984 		return;
14985 	}
14986 
14987 	led_change = elink_analyze_link_error(params, vars, value,
14988 					      PHY_SFP_TX_FAULT_FLAG,
14989 					      LINK_STATUS_SFP_TX_FAULT, 1);
14990 
14991 	if (led_change) {
14992 		/* Change TX_Fault led, set link status for further syncs */
14993 		uint8_t led_mode;
14994 
14995 		if (vars->phy_flags & PHY_SFP_TX_FAULT_FLAG) {
14996 			led_mode = MISC_REGISTERS_GPIO_HIGH;
14997 			vars->link_status |= LINK_STATUS_SFP_TX_FAULT;
14998 		} else {
14999 			led_mode = MISC_REGISTERS_GPIO_LOW;
15000 			vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT;
15001 		}
15002 
15003 		/* If module is unapproved, led should be on regardless */
15004 		if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED)) {
15005 			ELINK_DEBUG_P1(sc, "Change TX_Fault LED: ->%x",
15006 			   led_mode);
15007 			elink_set_e3_module_fault_led(params, led_mode);
15008 		}
15009 	}
15010 }
elink_kr2_recovery(struct elink_params * params,struct elink_vars * vars,struct elink_phy * phy)15011 static void elink_kr2_recovery(struct elink_params *params,
15012 			       struct elink_vars *vars,
15013 			       struct elink_phy *phy)
15014 {
15015 	struct bnx2x_softc *sc = params->sc;
15016 	ELINK_DEBUG_P0(sc, "KR2 recovery");
15017 	elink_warpcore_enable_AN_KR2(phy, params, vars);
15018 	elink_warpcore_restart_AN_KR(phy, params);
15019 }
15020 
elink_check_kr2_wa(struct elink_params * params,struct elink_vars * vars,struct elink_phy * phy)15021 static void elink_check_kr2_wa(struct elink_params *params,
15022 			       struct elink_vars *vars,
15023 			       struct elink_phy *phy)
15024 {
15025 	struct bnx2x_softc *sc = params->sc;
15026 	uint16_t base_page, next_page, not_kr2_device, lane;
15027 	int sigdet;
15028 
15029 	/* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery
15030 	 * Since some switches tend to reinit the AN process and clear the
15031 	 * advertised BP/NP after ~2 seconds causing the KR2 to be disabled
15032 	 * and recovered many times
15033 	 */
15034 	if (vars->check_kr2_recovery_cnt > 0) {
15035 		vars->check_kr2_recovery_cnt--;
15036 		return;
15037 	}
15038 
15039 	sigdet = elink_warpcore_get_sigdet(phy, params);
15040 	if (!sigdet) {
15041 		if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
15042 			elink_kr2_recovery(params, vars, phy);
15043 			ELINK_DEBUG_P0(sc, "No sigdet");
15044 		}
15045 		return;
15046 	}
15047 
15048 	lane = elink_get_warpcore_lane(phy, params);
15049 	CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
15050 			  MDIO_AER_BLOCK_AER_REG, lane);
15051 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
15052 			MDIO_AN_REG_LP_AUTO_NEG, &base_page);
15053 	elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
15054 			MDIO_AN_REG_LP_AUTO_NEG2, &next_page);
15055 	elink_set_aer_mmd(params, phy);
15056 
15057 	/* CL73 has not begun yet */
15058 	if (base_page == 0) {
15059 		if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
15060 			elink_kr2_recovery(params, vars, phy);
15061 			ELINK_DEBUG_P0(sc, "No BP");
15062 		}
15063 		return;
15064 	}
15065 
15066 	/* In case NP bit is not set in the BasePage, or it is set,
15067 	 * but only KX is advertised, declare this link partner as non-KR2
15068 	 * device.
15069 	 */
15070 	not_kr2_device = (((base_page & 0x8000) == 0) ||
15071 			  (((base_page & 0x8000) &&
15072 			    ((next_page & 0xe0) == 0x20))));
15073 
15074 	/* In case KR2 is already disabled, check if we need to re-enable it */
15075 	if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
15076 		if (!not_kr2_device) {
15077 			ELINK_DEBUG_P2(sc, "BP=0x%x, NP=0x%x", base_page,
15078 			   next_page);
15079 			elink_kr2_recovery(params, vars, phy);
15080 		}
15081 		return;
15082 	}
15083 	/* KR2 is enabled, but not KR2 device */
15084 	if (not_kr2_device) {
15085 		/* Disable KR2 on both lanes */
15086 		ELINK_DEBUG_P2(sc, "BP=0x%x, NP=0x%x", base_page, next_page);
15087 		elink_disable_kr2(params, vars, phy);
15088 		/* Restart AN on leading lane */
15089 		elink_warpcore_restart_AN_KR(phy, params);
15090 		return;
15091 	}
15092 }
15093 
elink_period_func(struct elink_params * params,struct elink_vars * vars)15094 void elink_period_func(struct elink_params *params, struct elink_vars *vars)
15095 {
15096 	uint16_t phy_idx;
15097 	struct bnx2x_softc *sc = params->sc;
15098 	for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
15099 		if (params->phy[phy_idx].flags & ELINK_FLAGS_TX_ERROR_CHECK) {
15100 			elink_set_aer_mmd(params, &params->phy[phy_idx]);
15101 			if (elink_check_half_open_conn(params, vars, 1) !=
15102 			    ELINK_STATUS_OK)
15103 				ELINK_DEBUG_P0(sc, "Fault detection failed");
15104 			break;
15105 		}
15106 	}
15107 
15108 	if (CHIP_IS_E3(sc)) {
15109 		struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
15110 		elink_set_aer_mmd(params, phy);
15111 		if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
15112 		     (phy->speed_cap_mask &
15113 		      PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) ||
15114 		    (phy->req_line_speed == ELINK_SPEED_20000))
15115 			elink_check_kr2_wa(params, vars, phy);
15116 		elink_check_over_curr(params, vars);
15117 		if (vars->rx_tx_asic_rst)
15118 			elink_warpcore_config_runtime(phy, params, vars);
15119 
15120 		if ((REG_RD(sc, params->shmem_base +
15121 			    offsetof(struct shmem_region, dev_info.
15122 				port_hw_config[params->port].default_cfg))
15123 		    & PORT_HW_CFG_NET_SERDES_IF_MASK) ==
15124 		    PORT_HW_CFG_NET_SERDES_IF_SFI) {
15125 			if (elink_is_sfp_module_plugged(phy, params)) {
15126 				elink_sfp_tx_fault_detection(phy, params, vars);
15127 			} else if (vars->link_status &
15128 				LINK_STATUS_SFP_TX_FAULT) {
15129 				/* Clean trail, interrupt corrects the leds */
15130 				vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT;
15131 				vars->phy_flags &= ~PHY_SFP_TX_FAULT_FLAG;
15132 				/* Update link status in the shared memory */
15133 				elink_update_mng(params, vars->link_status);
15134 			}
15135 		}
15136 	}
15137 }
15138 
elink_fan_failure_det_req(struct bnx2x_softc * sc,uint32_t shmem_base,uint32_t shmem2_base,uint8_t port)15139 uint8_t elink_fan_failure_det_req(struct bnx2x_softc *sc,
15140 			     uint32_t shmem_base,
15141 			     uint32_t shmem2_base,
15142 			     uint8_t port)
15143 {
15144 	uint8_t phy_index, fan_failure_det_req = 0;
15145 	struct elink_phy phy;
15146 	for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
15147 	      phy_index++) {
15148 		if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
15149 				       port, &phy)
15150 		    != ELINK_STATUS_OK) {
15151 			ELINK_DEBUG_P0(sc, "populate phy failed");
15152 			return 0;
15153 		}
15154 		fan_failure_det_req |= (phy.flags &
15155 					ELINK_FLAGS_FAN_FAILURE_DET_REQ);
15156 	}
15157 	return fan_failure_det_req;
15158 }
15159 
elink_hw_reset_phy(struct elink_params * params)15160 void elink_hw_reset_phy(struct elink_params *params)
15161 {
15162 	uint8_t phy_index;
15163 	struct bnx2x_softc *sc = params->sc;
15164 	elink_update_mng(params, 0);
15165 	elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + params->port * 4,
15166 		       (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
15167 			ELINK_NIG_MASK_XGXS0_LINK10G |
15168 			ELINK_NIG_MASK_SERDES0_LINK_STATUS |
15169 			ELINK_NIG_MASK_MI_INT));
15170 
15171 	for (phy_index = ELINK_INT_PHY; phy_index < ELINK_MAX_PHYS;
15172 	      phy_index++) {
15173 		if (params->phy[phy_index].hw_reset) {
15174 			params->phy[phy_index].hw_reset(
15175 				&params->phy[phy_index],
15176 				params);
15177 			params->phy[phy_index] = phy_null;
15178 		}
15179 	}
15180 }
15181 
elink_init_mod_abs_int(struct bnx2x_softc * sc,struct elink_vars * vars,uint32_t chip_id,uint32_t shmem_base,uint32_t shmem2_base,uint8_t port)15182 void elink_init_mod_abs_int(struct bnx2x_softc *sc, struct elink_vars *vars,
15183 			    uint32_t chip_id, uint32_t shmem_base,
15184 			    uint32_t shmem2_base,
15185 			    uint8_t port)
15186 {
15187 	uint8_t gpio_num = 0xff, gpio_port = 0xff, phy_index;
15188 	uint32_t val;
15189 	uint32_t offset, aeu_mask, swap_val, swap_override, sync_offset;
15190 	if (CHIP_IS_E3(sc)) {
15191 		if (elink_get_mod_abs_int_cfg(sc, chip_id,
15192 					      shmem_base,
15193 					      port,
15194 					      &gpio_num,
15195 					      &gpio_port) != ELINK_STATUS_OK)
15196 			return;
15197 	} else {
15198 		struct elink_phy phy;
15199 		for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
15200 		      phy_index++) {
15201 			if (elink_populate_phy(sc, phy_index, shmem_base,
15202 					       shmem2_base, port, &phy)
15203 			    != ELINK_STATUS_OK) {
15204 				ELINK_DEBUG_P0(sc, "populate phy failed");
15205 				return;
15206 			}
15207 			if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726) {
15208 				gpio_num = MISC_REGISTERS_GPIO_3;
15209 				gpio_port = port;
15210 				break;
15211 			}
15212 		}
15213 	}
15214 
15215 	if (gpio_num == 0xff)
15216 		return;
15217 
15218 	/* Set GPIO3 to trigger SFP+ module insertion/removal */
15219 	elink_cb_gpio_write(sc, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z,
15220 			    gpio_port);
15221 
15222 	swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
15223 	swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
15224 	gpio_port ^= (swap_val && swap_override);
15225 
15226 	vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 <<
15227 		(gpio_num + (gpio_port << 2));
15228 
15229 	sync_offset = shmem_base +
15230 		offsetof(struct shmem_region,
15231 			 dev_info.port_hw_config[port].aeu_int_mask);
15232 	REG_WR(sc, sync_offset, vars->aeu_int_mask);
15233 
15234 	ELINK_DEBUG_P3(sc, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x",
15235 		       gpio_num, gpio_port, vars->aeu_int_mask);
15236 
15237 	if (port == 0)
15238 		offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
15239 	else
15240 		offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
15241 
15242 	/* Open appropriate AEU for interrupts */
15243 	aeu_mask = REG_RD(sc, offset);
15244 	aeu_mask |= vars->aeu_int_mask;
15245 	REG_WR(sc, offset, aeu_mask);
15246 
15247 	/* Enable the GPIO to trigger interrupt */
15248 	val = REG_RD(sc, MISC_REG_GPIO_EVENT_EN);
15249 	val |= 1 << (gpio_num + (gpio_port << 2));
15250 	REG_WR(sc, MISC_REG_GPIO_EVENT_EN, val);
15251 }
15252