net/mlx5: implement tunnel offload
[dpdk.git] / drivers / net / bnx2x / elink.c
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_LC        0x7
871         #define ELINK_SFP_EEPROM_CON_TYPE_VAL_COPPER    0x21
872         #define ELINK_SFP_EEPROM_CON_TYPE_VAL_RJ45      0x22
873
874
875 #define ELINK_SFP_EEPROM_10G_COMP_CODE_ADDR             0x3
876         #define ELINK_SFP_EEPROM_10G_COMP_CODE_SR_MASK  (1 << 4)
877         #define ELINK_SFP_EEPROM_10G_COMP_CODE_LR_MASK  (1 << 5)
878         #define ELINK_SFP_EEPROM_10G_COMP_CODE_LRM_MASK (1 << 6)
879
880 #define ELINK_SFP_EEPROM_1G_COMP_CODE_ADDR              0x6
881         #define ELINK_SFP_EEPROM_1G_COMP_CODE_SX        (1 << 0)
882         #define ELINK_SFP_EEPROM_1G_COMP_CODE_LX        (1 << 1)
883         #define ELINK_SFP_EEPROM_1G_COMP_CODE_CX        (1 << 2)
884         #define ELINK_SFP_EEPROM_1G_COMP_CODE_BASE_T    (1 << 3)
885
886 #define ELINK_SFP_EEPROM_FC_TX_TECH_ADDR                0x8
887         #define ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
888         #define ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE  0x8
889
890 #define ELINK_SFP_EEPROM_OPTIONS_ADDR                   0x40
891         #define ELINK_SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
892 #define ELINK_SFP_EEPROM_OPTIONS_SIZE                   2
893
894 #define ELINK_EDC_MODE_LINEAR                           0x0022
895 #define ELINK_EDC_MODE_LIMITING                         0x0044
896 #define ELINK_EDC_MODE_PASSIVE_DAC                      0x0055
897 #define ELINK_EDC_MODE_ACTIVE_DAC                       0x0066
898
899 /* ETS defines*/
900 #define DCBX_INVALID_COS                                        (0xFF)
901
902 #define ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND           (0x5000)
903 #define ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT                (0x5000)
904 #define ELINK_ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS               (1360)
905 #define ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS                     (2720)
906 #define ELINK_ETS_E3B0_PBF_MIN_W_VAL                            (10000)
907
908 #define ELINK_MAX_PACKET_SIZE                                   (9700)
909 #define MAX_KR_LINK_RETRY                               4
910 #define DEFAULT_TX_DRV_BRDCT            2
911 #define DEFAULT_TX_DRV_IFIR             0
912 #define DEFAULT_TX_DRV_POST2            3
913 #define DEFAULT_TX_DRV_IPRE_DRIVER      6
914
915 /**********************************************************/
916 /*                     INTERFACE                          */
917 /**********************************************************/
918
919 #define CL22_WR_OVER_CL45(_sc, _phy, _bank, _addr, _val) \
920         elink_cl45_write(_sc, _phy, \
921                 (_phy)->def_md_devad, \
922                 (_bank + (_addr & 0xf)), \
923                 _val)
924
925 #define CL22_RD_OVER_CL45(_sc, _phy, _bank, _addr, _val) \
926         elink_cl45_read(_sc, _phy, \
927                 (_phy)->def_md_devad, \
928                 (_bank + (_addr & 0xf)), \
929                 _val)
930
931 static elink_status_t elink_check_half_open_conn(struct elink_params *params,
932                                       struct elink_vars *vars, uint8_t notify);
933 static elink_status_t elink_sfp_module_detection(struct elink_phy *phy,
934                                       struct elink_params *params);
935
936 static uint32_t elink_bits_en(struct bnx2x_softc *sc, uint32_t reg, uint32_t bits)
937 {
938         uint32_t val = REG_RD(sc, reg);
939
940         val |= bits;
941         REG_WR(sc, reg, val);
942         return val;
943 }
944
945 static uint32_t elink_bits_dis(struct bnx2x_softc *sc, uint32_t reg,
946                                uint32_t bits)
947 {
948         uint32_t val = REG_RD(sc, reg);
949
950         val &= ~bits;
951         REG_WR(sc, reg, val);
952         return val;
953 }
954
955 /*
956  * elink_check_lfa - This function checks if link reinitialization is required,
957  *                   or link flap can be avoided.
958  *
959  * @params:     link parameters
960  * Returns 0 if Link Flap Avoidance conditions are met otherwise, the failed
961  *         condition code.
962  */
963 static int elink_check_lfa(struct elink_params *params)
964 {
965         uint32_t link_status, cfg_idx, lfa_mask, cfg_size;
966         uint32_t cur_speed_cap_mask, cur_req_fc_auto_adv, additional_config;
967         uint32_t saved_val, req_val, eee_status;
968         struct bnx2x_softc *sc = params->sc;
969
970         additional_config =
971                 REG_RD(sc, params->lfa_base +
972                            offsetof(struct shmem_lfa, additional_config));
973
974         /* NOTE: must be first condition checked -
975         * to verify DCC bit is cleared in any case!
976         */
977         if (additional_config & NO_LFA_DUE_TO_DCC_MASK) {
978                 ELINK_DEBUG_P0(sc, "No LFA due to DCC flap after clp exit");
979                 REG_WR(sc, params->lfa_base +
980                            offsetof(struct shmem_lfa, additional_config),
981                        additional_config & ~NO_LFA_DUE_TO_DCC_MASK);
982                 return LFA_DCC_LFA_DISABLED;
983         }
984
985         /* Verify that link is up */
986         link_status = REG_RD(sc, params->shmem_base +
987                              offsetof(struct shmem_region,
988                                       port_mb[params->port].link_status));
989         if (!(link_status & LINK_STATUS_LINK_UP))
990                 return LFA_LINK_DOWN;
991
992         /* if loaded after BOOT from SAN, don't flap the link in any case and
993          * rely on link set by preboot driver
994          */
995         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_BOOT_FROM_SAN)
996                 return 0;
997
998         /* Verify that loopback mode is not set */
999         if (params->loopback_mode)
1000                 return LFA_LOOPBACK_ENABLED;
1001
1002         /* Verify that MFW supports LFA */
1003         if (!params->lfa_base)
1004                 return LFA_MFW_IS_TOO_OLD;
1005
1006         if (params->num_phys == 3) {
1007                 cfg_size = 2;
1008                 lfa_mask = 0xffffffff;
1009         } else {
1010                 cfg_size = 1;
1011                 lfa_mask = 0xffff;
1012         }
1013
1014         /* Compare Duplex */
1015         saved_val = REG_RD(sc, params->lfa_base +
1016                            offsetof(struct shmem_lfa, req_duplex));
1017         req_val = params->req_duplex[0] | (params->req_duplex[1] << 16);
1018         if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
1019                 ELINK_DEBUG_P2(sc, "Duplex mismatch %x vs. %x",
1020                                (saved_val & lfa_mask), (req_val & lfa_mask));
1021                 return LFA_DUPLEX_MISMATCH;
1022         }
1023         /* Compare Flow Control */
1024         saved_val = REG_RD(sc, params->lfa_base +
1025                            offsetof(struct shmem_lfa, req_flow_ctrl));
1026         req_val = params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16);
1027         if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
1028                 ELINK_DEBUG_P2(sc, "Flow control mismatch %x vs. %x",
1029                                (saved_val & lfa_mask), (req_val & lfa_mask));
1030                 return LFA_FLOW_CTRL_MISMATCH;
1031         }
1032         /* Compare Link Speed */
1033         saved_val = REG_RD(sc, params->lfa_base +
1034                            offsetof(struct shmem_lfa, req_line_speed));
1035         req_val = params->req_line_speed[0] | (params->req_line_speed[1] << 16);
1036         if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
1037                 ELINK_DEBUG_P2(sc, "Link speed mismatch %x vs. %x",
1038                                (saved_val & lfa_mask), (req_val & lfa_mask));
1039                 return LFA_LINK_SPEED_MISMATCH;
1040         }
1041
1042         for (cfg_idx = 0; cfg_idx < cfg_size; cfg_idx++) {
1043                 cur_speed_cap_mask = REG_RD(sc, params->lfa_base +
1044                                             offsetof(struct shmem_lfa,
1045                                                      speed_cap_mask[cfg_idx]));
1046
1047                 if (cur_speed_cap_mask != params->speed_cap_mask[cfg_idx]) {
1048                         ELINK_DEBUG_P2(sc, "Speed Cap mismatch %x vs. %x",
1049                                        cur_speed_cap_mask,
1050                                        params->speed_cap_mask[cfg_idx]);
1051                         return LFA_SPEED_CAP_MISMATCH;
1052                 }
1053         }
1054
1055         cur_req_fc_auto_adv =
1056                 REG_RD(sc, params->lfa_base +
1057                        offsetof(struct shmem_lfa, additional_config)) &
1058                 REQ_FC_AUTO_ADV_MASK;
1059
1060         if ((uint16_t)cur_req_fc_auto_adv != params->req_fc_auto_adv) {
1061                 ELINK_DEBUG_P2(sc, "Flow Ctrl AN mismatch %x vs. %x",
1062                                cur_req_fc_auto_adv, params->req_fc_auto_adv);
1063                 return LFA_FLOW_CTRL_MISMATCH;
1064         }
1065
1066         eee_status = REG_RD(sc, params->shmem2_base +
1067                             offsetof(struct shmem2_region,
1068                                      eee_status[params->port]));
1069
1070         if (((eee_status & SHMEM_EEE_LPI_REQUESTED_BIT) ^
1071              (params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)) ||
1072             ((eee_status & SHMEM_EEE_REQUESTED_BIT) ^
1073              (params->eee_mode & ELINK_EEE_MODE_ADV_LPI))) {
1074                 ELINK_DEBUG_P2(sc, "EEE mismatch %x vs. %x", params->eee_mode,
1075                                eee_status);
1076                 return LFA_EEE_MISMATCH;
1077         }
1078
1079         /* LFA conditions are met */
1080         return 0;
1081 }
1082 /******************************************************************/
1083 /*                      EPIO/GPIO section                         */
1084 /******************************************************************/
1085 static void elink_get_epio(struct bnx2x_softc *sc, uint32_t epio_pin,
1086                            uint32_t *en)
1087 {
1088         uint32_t epio_mask, gp_oenable;
1089         *en = 0;
1090         /* Sanity check */
1091         if (epio_pin > 31) {
1092                 ELINK_DEBUG_P1(sc, "Invalid EPIO pin %d to get", epio_pin);
1093                 return;
1094         }
1095
1096         epio_mask = 1 << epio_pin;
1097         /* Set this EPIO to output */
1098         gp_oenable = REG_RD(sc, MCP_REG_MCPR_GP_OENABLE);
1099         REG_WR(sc, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask);
1100
1101         *en = (REG_RD(sc, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin;
1102 }
1103 static void elink_set_epio(struct bnx2x_softc *sc, uint32_t epio_pin, uint32_t en)
1104 {
1105         uint32_t epio_mask, gp_output, gp_oenable;
1106
1107         /* Sanity check */
1108         if (epio_pin > 31) {
1109                 ELINK_DEBUG_P1(sc, "Invalid EPIO pin %d to set", epio_pin);
1110                 return;
1111         }
1112         ELINK_DEBUG_P2(sc, "Setting EPIO pin %d to %d", epio_pin, en);
1113         epio_mask = 1 << epio_pin;
1114         /* Set this EPIO to output */
1115         gp_output = REG_RD(sc, MCP_REG_MCPR_GP_OUTPUTS);
1116         if (en)
1117                 gp_output |= epio_mask;
1118         else
1119                 gp_output &= ~epio_mask;
1120
1121         REG_WR(sc, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
1122
1123         /* Set the value for this EPIO */
1124         gp_oenable = REG_RD(sc, MCP_REG_MCPR_GP_OENABLE);
1125         REG_WR(sc, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
1126 }
1127
1128 static void elink_set_cfg_pin(struct bnx2x_softc *sc, uint32_t pin_cfg,
1129                               uint32_t val)
1130 {
1131         if (pin_cfg == PIN_CFG_NA)
1132                 return;
1133         if (pin_cfg >= PIN_CFG_EPIO0) {
1134                 elink_set_epio(sc, pin_cfg - PIN_CFG_EPIO0, val);
1135         } else {
1136                 uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
1137                 uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
1138                 elink_cb_gpio_write(sc, gpio_num, (uint8_t)val, gpio_port);
1139         }
1140 }
1141
1142 static uint32_t elink_get_cfg_pin(struct bnx2x_softc *sc, uint32_t pin_cfg,
1143                                   uint32_t *val)
1144 {
1145         if (pin_cfg == PIN_CFG_NA)
1146                 return ELINK_STATUS_ERROR;
1147         if (pin_cfg >= PIN_CFG_EPIO0) {
1148                 elink_get_epio(sc, pin_cfg - PIN_CFG_EPIO0, val);
1149         } else {
1150                 uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
1151                 uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
1152                 *val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
1153         }
1154         return ELINK_STATUS_OK;
1155 }
1156
1157 /******************************************************************/
1158 /*                              ETS section                       */
1159 /******************************************************************/
1160 static void elink_ets_e2e3a0_disabled(struct elink_params *params)
1161 {
1162         /* ETS disabled configuration*/
1163         struct bnx2x_softc *sc = params->sc;
1164
1165         ELINK_DEBUG_P0(sc, "ETS E2E3 disabled configuration");
1166
1167         /* mapping between entry  priority to client number (0,1,2 -debug and
1168          * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
1169          * 3bits client num.
1170          *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1171          * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
1172          */
1173
1174         REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
1175         /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1176          * as strict.  Bits 0,1,2 - debug and management entries, 3 -
1177          * COS0 entry, 4 - COS1 entry.
1178          * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
1179          * bit4   bit3    bit2   bit1     bit0
1180          * MCP and debug are strict
1181          */
1182
1183         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
1184         /* defines which entries (clients) are subjected to WFQ arbitration */
1185         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
1186         /* For strict priority entries defines the number of consecutive
1187          * slots for the highest priority.
1188          */
1189         REG_WR(sc, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1190         /* mapping between the CREDIT_WEIGHT registers and actual client
1191          * numbers
1192          */
1193         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
1194         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
1195         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
1196
1197         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
1198         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
1199         REG_WR(sc, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
1200         /* ETS mode disable */
1201         REG_WR(sc, PBF_REG_ETS_ENABLED, 0);
1202         /* If ETS mode is enabled (there is no strict priority) defines a WFQ
1203          * weight for COS0/COS1.
1204          */
1205         REG_WR(sc, PBF_REG_COS0_WEIGHT, 0x2710);
1206         REG_WR(sc, PBF_REG_COS1_WEIGHT, 0x2710);
1207         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
1208         REG_WR(sc, PBF_REG_COS0_UPPER_BOUND, 0x989680);
1209         REG_WR(sc, PBF_REG_COS1_UPPER_BOUND, 0x989680);
1210         /* Defines the number of consecutive slots for the strict priority */
1211         REG_WR(sc, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1212 }
1213 /******************************************************************************
1214  * Description:
1215  *      Getting min_w_val will be set according to line speed .
1216  *.
1217  ******************************************************************************/
1218 static uint32_t elink_ets_get_min_w_val_nig(const struct elink_vars *vars)
1219 {
1220         uint32_t min_w_val = 0;
1221         /* Calculate min_w_val.*/
1222         if (vars->link_up) {
1223                 if (vars->line_speed == ELINK_SPEED_20000)
1224                         min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
1225                 else
1226                         min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS;
1227         } else {
1228                 min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
1229         }
1230         /* If the link isn't up (static configuration for example ) The
1231          * link will be according to 20GBPS.
1232          */
1233         return min_w_val;
1234 }
1235 /******************************************************************************
1236  * Description:
1237  *      Getting credit upper bound form min_w_val.
1238  *.
1239  ******************************************************************************/
1240 static uint32_t elink_ets_get_credit_upper_bound(const uint32_t min_w_val)
1241 {
1242         const uint32_t credit_upper_bound = (uint32_t)
1243                                                 ELINK_MAXVAL((150 * min_w_val),
1244                                                         ELINK_MAX_PACKET_SIZE);
1245         return credit_upper_bound;
1246 }
1247 /******************************************************************************
1248  * Description:
1249  *      Set credit upper bound for NIG.
1250  *.
1251  ******************************************************************************/
1252 static void elink_ets_e3b0_set_credit_upper_bound_nig(
1253         const struct elink_params *params,
1254         const uint32_t min_w_val)
1255 {
1256         struct bnx2x_softc *sc = params->sc;
1257         const uint8_t port = params->port;
1258         const uint32_t credit_upper_bound =
1259             elink_ets_get_credit_upper_bound(min_w_val);
1260
1261         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 :
1262                 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound);
1263         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 :
1264                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound);
1265         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 :
1266                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound);
1267         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 :
1268                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound);
1269         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 :
1270                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound);
1271         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 :
1272                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound);
1273
1274         if (!port) {
1275                 REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6,
1276                         credit_upper_bound);
1277                 REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7,
1278                         credit_upper_bound);
1279                 REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8,
1280                         credit_upper_bound);
1281         }
1282 }
1283 /******************************************************************************
1284  * Description:
1285  *      Will return the NIG ETS registers to init values.Except
1286  *      credit_upper_bound.
1287  *      That isn't used in this configuration (No WFQ is enabled) and will be
1288  *      configured according to spec
1289  *.
1290  ******************************************************************************/
1291 static void elink_ets_e3b0_nig_disabled(const struct elink_params *params,
1292                                         const struct elink_vars *vars)
1293 {
1294         struct bnx2x_softc *sc = params->sc;
1295         const uint8_t port = params->port;
1296         const uint32_t min_w_val = elink_ets_get_min_w_val_nig(vars);
1297         /* Mapping between entry  priority to client number (0,1,2 -debug and
1298          * management clients, 3 - COS0 client, 4 - COS1, ... 8 -
1299          * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
1300          * reset value or init tool
1301          */
1302         if (port) {
1303                 REG_WR(sc, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210);
1304                 REG_WR(sc, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0);
1305         } else {
1306                 REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210);
1307                 REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8);
1308         }
1309         /* For strict priority entries defines the number of consecutive
1310          * slots for the highest priority.
1311          */
1312         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
1313                    NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1314         /* Mapping between the CREDIT_WEIGHT registers and actual client
1315          * numbers
1316          */
1317         if (port) {
1318                 /*Port 1 has 6 COS*/
1319                 REG_WR(sc, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543);
1320                 REG_WR(sc, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0);
1321         } else {
1322                 /*Port 0 has 9 COS*/
1323                 REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB,
1324                        0x43210876);
1325                 REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5);
1326         }
1327
1328         /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1329          * as strict.  Bits 0,1,2 - debug and management entries, 3 -
1330          * COS0 entry, 4 - COS1 entry.
1331          * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
1332          * bit4   bit3    bit2   bit1     bit0
1333          * MCP and debug are strict
1334          */
1335         if (port)
1336                 REG_WR(sc, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f);
1337         else
1338                 REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff);
1339         /* defines which entries (clients) are subjected to WFQ arbitration */
1340         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
1341                    NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
1342
1343         /* Please notice the register address are note continuous and a
1344          * for here is note appropriate.In 2 port mode port0 only COS0-5
1345          * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
1346          * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
1347          * are never used for WFQ
1348          */
1349         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
1350                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0);
1351         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
1352                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0);
1353         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
1354                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0);
1355         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 :
1356                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0);
1357         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 :
1358                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0);
1359         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 :
1360                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0);
1361         if (!port) {
1362                 REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0);
1363                 REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0);
1364                 REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0);
1365         }
1366
1367         elink_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val);
1368 }
1369 /******************************************************************************
1370  * Description:
1371  *      Set credit upper bound for PBF.
1372  *.
1373  ******************************************************************************/
1374 static void elink_ets_e3b0_set_credit_upper_bound_pbf(
1375         const struct elink_params *params,
1376         const uint32_t min_w_val)
1377 {
1378         struct bnx2x_softc *sc = params->sc;
1379         const uint32_t credit_upper_bound =
1380             elink_ets_get_credit_upper_bound(min_w_val);
1381         const uint8_t port = params->port;
1382         uint32_t base_upper_bound = 0;
1383         uint8_t max_cos = 0;
1384         uint8_t i = 0;
1385         /* In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
1386          * port mode port1 has COS0-2 that can be used for WFQ.
1387          */
1388         if (!port) {
1389                 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0;
1390                 max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1391         } else {
1392                 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1;
1393                 max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1;
1394         }
1395
1396         for (i = 0; i < max_cos; i++)
1397                 REG_WR(sc, base_upper_bound + (i << 2), credit_upper_bound);
1398 }
1399
1400 /******************************************************************************
1401  * Description:
1402  *      Will return the PBF ETS registers to init values.Except
1403  *      credit_upper_bound.
1404  *      That isn't used in this configuration (No WFQ is enabled) and will be
1405  *      configured according to spec
1406  *.
1407  ******************************************************************************/
1408 static void elink_ets_e3b0_pbf_disabled(const struct elink_params *params)
1409 {
1410         struct bnx2x_softc *sc = params->sc;
1411         const uint8_t port = params->port;
1412         const uint32_t min_w_val_pbf = ELINK_ETS_E3B0_PBF_MIN_W_VAL;
1413         uint8_t i = 0;
1414         uint32_t base_weight = 0;
1415         uint8_t max_cos = 0;
1416
1417         /* Mapping between entry  priority to client number 0 - COS0
1418          * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
1419          * TODO_ETS - Should be done by reset value or init tool
1420          */
1421         if (port)
1422                 /*  0x688 (|011|0 10|00 1|000) */
1423                 REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1, 0x688);
1424         else
1425                 /*  (10 1|100 |011|0 10|00 1|000) */
1426                 REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0, 0x2C688);
1427
1428         /* TODO_ETS - Should be done by reset value or init tool */
1429         if (port)
1430                 /* 0x688 (|011|0 10|00 1|000)*/
1431                 REG_WR(sc, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688);
1432         else
1433         /* 0x2C688 (10 1|100 |011|0 10|00 1|000) */
1434         REG_WR(sc, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688);
1435
1436         REG_WR(sc, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 :
1437                    PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0, 0x100);
1438
1439
1440         REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
1441                    PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0, 0);
1442
1443         REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
1444                    PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0, 0);
1445         /* In 2 port mode port0 has COS0-5 that can be used for WFQ.
1446          * In 4 port mode port1 has COS0-2 that can be used for WFQ.
1447          */
1448         if (!port) {
1449                 base_weight = PBF_REG_COS0_WEIGHT_P0;
1450                 max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1451         } else {
1452                 base_weight = PBF_REG_COS0_WEIGHT_P1;
1453                 max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1;
1454         }
1455
1456         for (i = 0; i < max_cos; i++)
1457                 REG_WR(sc, base_weight + (0x4 * i), 0);
1458
1459         elink_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1460 }
1461 /******************************************************************************
1462  * Description:
1463  *      E3B0 disable will return basicly the values to init values.
1464  *.
1465  ******************************************************************************/
1466 static elink_status_t elink_ets_e3b0_disabled(const struct elink_params *params,
1467                                    const struct elink_vars *vars)
1468 {
1469         struct bnx2x_softc *sc = params->sc;
1470
1471         if (!CHIP_IS_E3B0(sc)) {
1472                 ELINK_DEBUG_P0(sc,
1473                    "elink_ets_e3b0_disabled the chip isn't E3B0");
1474                 return ELINK_STATUS_ERROR;
1475         }
1476
1477         elink_ets_e3b0_nig_disabled(params, vars);
1478
1479         elink_ets_e3b0_pbf_disabled(params);
1480
1481         return ELINK_STATUS_OK;
1482 }
1483
1484 /******************************************************************************
1485  * Description:
1486  *      Disable will return basicly the values to init values.
1487  *
1488  ******************************************************************************/
1489 elink_status_t elink_ets_disabled(struct elink_params *params,
1490                       struct elink_vars *vars)
1491 {
1492         struct bnx2x_softc *sc = params->sc;
1493         elink_status_t elink_status = ELINK_STATUS_OK;
1494
1495         if ((CHIP_IS_E2(sc)) || (CHIP_IS_E3A0(sc))) {
1496                 elink_ets_e2e3a0_disabled(params);
1497         } else if (CHIP_IS_E3B0(sc)) {
1498                 elink_status = elink_ets_e3b0_disabled(params, vars);
1499         } else {
1500                 ELINK_DEBUG_P0(sc, "elink_ets_disabled - chip not supported");
1501                 return ELINK_STATUS_ERROR;
1502         }
1503
1504         return elink_status;
1505 }
1506
1507 /******************************************************************************
1508  * Description
1509  *      Set the COS mappimg to SP and BW until this point all the COS are not
1510  *      set as SP or BW.
1511  ******************************************************************************/
1512 static elink_status_t elink_ets_e3b0_cli_map(const struct elink_params *params,
1513                   __rte_unused const struct elink_ets_params *ets_params,
1514                   const uint8_t cos_sp_bitmap,
1515                   const uint8_t cos_bw_bitmap)
1516 {
1517         struct bnx2x_softc *sc = params->sc;
1518         const uint8_t port = params->port;
1519         const uint8_t nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3);
1520         const uint8_t pbf_cli_sp_bitmap = cos_sp_bitmap;
1521         const uint8_t nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3;
1522         const uint8_t pbf_cli_subject2wfq_bitmap = cos_bw_bitmap;
1523
1524         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT :
1525                NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap);
1526
1527         REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
1528                PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0, pbf_cli_sp_bitmap);
1529
1530         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
1531                NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ,
1532                nig_cli_subject2wfq_bitmap);
1533
1534         REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
1535                PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0,
1536                pbf_cli_subject2wfq_bitmap);
1537
1538         return ELINK_STATUS_OK;
1539 }
1540
1541 /******************************************************************************
1542  * Description:
1543  *      This function is needed because NIG ARB_CREDIT_WEIGHT_X are
1544  *      not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
1545  ******************************************************************************/
1546 static elink_status_t elink_ets_e3b0_set_cos_bw(struct bnx2x_softc *sc,
1547                                      const uint8_t cos_entry,
1548                                      const uint32_t min_w_val_nig,
1549                                      const uint32_t min_w_val_pbf,
1550                                      const uint16_t total_bw,
1551                                      const uint8_t bw,
1552                                      const uint8_t port)
1553 {
1554         uint32_t nig_reg_address_crd_weight = 0;
1555         uint32_t pbf_reg_address_crd_weight = 0;
1556         /* Calculate and set BW for this COS - use 1 instead of 0 for BW */
1557         const uint32_t cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw;
1558         const uint32_t cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw;
1559
1560         switch (cos_entry) {
1561         case 0:
1562             nig_reg_address_crd_weight =
1563                  (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
1564                      NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0;
1565              pbf_reg_address_crd_weight = (port) ?
1566                  PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0;
1567                 break;
1568         case 1:
1569              nig_reg_address_crd_weight = (port) ?
1570                  NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
1571                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1;
1572              pbf_reg_address_crd_weight = (port) ?
1573                  PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0;
1574                 break;
1575         case 2:
1576              nig_reg_address_crd_weight = (port) ?
1577                  NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
1578                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2;
1579
1580                  pbf_reg_address_crd_weight = (port) ?
1581                      PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0;
1582                 break;
1583         case 3:
1584                 if (port)
1585                         return ELINK_STATUS_ERROR;
1586                 nig_reg_address_crd_weight =
1587                         NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3;
1588                 pbf_reg_address_crd_weight =
1589                         PBF_REG_COS3_WEIGHT_P0;
1590                 break;
1591         case 4:
1592                 if (port)
1593                 return ELINK_STATUS_ERROR;
1594              nig_reg_address_crd_weight =
1595                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4;
1596              pbf_reg_address_crd_weight = PBF_REG_COS4_WEIGHT_P0;
1597                 break;
1598         case 5:
1599                 if (port)
1600                 return ELINK_STATUS_ERROR;
1601              nig_reg_address_crd_weight =
1602                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5;
1603              pbf_reg_address_crd_weight = PBF_REG_COS5_WEIGHT_P0;
1604                 break;
1605         }
1606
1607         REG_WR(sc, nig_reg_address_crd_weight, cos_bw_nig);
1608
1609         REG_WR(sc, pbf_reg_address_crd_weight, cos_bw_pbf);
1610
1611         return ELINK_STATUS_OK;
1612 }
1613 /******************************************************************************
1614  * Description:
1615  *      Calculate the total BW.A value of 0 isn't legal.
1616  *
1617  ******************************************************************************/
1618 static elink_status_t elink_ets_e3b0_get_total_bw(
1619         const struct elink_params *params,
1620         struct elink_ets_params *ets_params,
1621         uint16_t *total_bw)
1622 {
1623         struct bnx2x_softc *sc = params->sc;
1624         uint8_t cos_idx = 0;
1625         uint8_t is_bw_cos_exist = 0;
1626
1627         *total_bw = 0;
1628         /* Calculate total BW requested */
1629         for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
1630                 if (ets_params->cos[cos_idx].state == elink_cos_state_bw) {
1631                         is_bw_cos_exist = 1;
1632                         if (!ets_params->cos[cos_idx].params.bw_params.bw) {
1633                                 ELINK_DEBUG_P0(sc, "elink_ets_E3B0_config BW"
1634                                                    " was set to 0");
1635                                 /* This is to prevent a state when ramrods
1636                                  * can't be sent
1637                                  */
1638                                 ets_params->cos[cos_idx].params.bw_params.bw
1639                                          = 1;
1640                         }
1641                         *total_bw +=
1642                                 ets_params->cos[cos_idx].params.bw_params.bw;
1643                 }
1644         }
1645
1646         /* Check total BW is valid */
1647         if ((is_bw_cos_exist == 1) && (*total_bw != 100)) {
1648                 if (*total_bw == 0) {
1649                         ELINK_DEBUG_P0(sc,
1650                            "elink_ets_E3B0_config total BW shouldn't be 0");
1651                         return ELINK_STATUS_ERROR;
1652                 }
1653                 ELINK_DEBUG_P0(sc,
1654                    "elink_ets_E3B0_config total BW should be 100");
1655                 /* We can handle a case whre the BW isn't 100 this can happen
1656                  * if the TC are joined.
1657                  */
1658         }
1659         return ELINK_STATUS_OK;
1660 }
1661
1662 /******************************************************************************
1663  * Description:
1664  *      Invalidate all the sp_pri_to_cos.
1665  *
1666  ******************************************************************************/
1667 static void elink_ets_e3b0_sp_pri_to_cos_init(uint8_t *sp_pri_to_cos)
1668 {
1669         uint8_t pri = 0;
1670         for (pri = 0; pri < ELINK_DCBX_MAX_NUM_COS; pri++)
1671                 sp_pri_to_cos[pri] = DCBX_INVALID_COS;
1672 }
1673 /******************************************************************************
1674  * Description:
1675  *      Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1676  *      according to sp_pri_to_cos.
1677  *
1678  ******************************************************************************/
1679 static elink_status_t elink_ets_e3b0_sp_pri_to_cos_set(
1680                                             const struct elink_params *params,
1681                                             uint8_t *sp_pri_to_cos,
1682                                             const uint8_t pri,
1683                                             const uint8_t cos_entry)
1684 {
1685         struct bnx2x_softc *sc = params->sc;
1686         const uint8_t port = params->port;
1687         const uint8_t max_num_of_cos = (port) ?
1688                 ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1689                 ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1690
1691         if (pri >= max_num_of_cos) {
1692                 ELINK_DEBUG_P0(sc, "elink_ets_e3b0_sp_pri_to_cos_set invalid "
1693                    "parameter Illegal strict priority");
1694                 return ELINK_STATUS_ERROR;
1695         }
1696
1697         if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {
1698                 ELINK_DEBUG_P0(sc, "elink_ets_e3b0_sp_pri_to_cos_set invalid "
1699                                    "parameter There can't be two COS's with "
1700                                    "the same strict pri");
1701                 return ELINK_STATUS_ERROR;
1702         }
1703
1704         sp_pri_to_cos[pri] = cos_entry;
1705         return ELINK_STATUS_OK;
1706 }
1707
1708 /******************************************************************************
1709  * Description:
1710  *      Returns the correct value according to COS and priority in
1711  *      the sp_pri_cli register.
1712  *
1713  ******************************************************************************/
1714 static uint64_t elink_e3b0_sp_get_pri_cli_reg(const uint8_t cos,
1715                                          const uint8_t cos_offset,
1716                                          const uint8_t pri_set,
1717                                          const uint8_t pri_offset,
1718                                          const uint8_t entry_size)
1719 {
1720         uint64_t pri_cli_nig = 0;
1721         pri_cli_nig = ((uint64_t)(cos + cos_offset)) << (entry_size *
1722                                                     (pri_set + pri_offset));
1723
1724         return pri_cli_nig;
1725 }
1726 /******************************************************************************
1727  * Description:
1728  *      Returns the correct value according to COS and priority in the
1729  *      sp_pri_cli register for NIG.
1730  *
1731  ******************************************************************************/
1732 static uint64_t elink_e3b0_sp_get_pri_cli_reg_nig(const uint8_t cos,
1733                                                   const uint8_t pri_set)
1734 {
1735         /* MCP Dbg0 and dbg1 are always with higher strict pri*/
1736         const uint8_t nig_cos_offset = 3;
1737         const uint8_t nig_pri_offset = 3;
1738
1739         return elink_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set,
1740                 nig_pri_offset, 4);
1741 }
1742
1743 /******************************************************************************
1744  * Description:
1745  *      Returns the correct value according to COS and priority in the
1746  *      sp_pri_cli register for PBF.
1747  *
1748  ******************************************************************************/
1749 static uint64_t elink_e3b0_sp_get_pri_cli_reg_pbf(const uint8_t cos,
1750                                                   const uint8_t pri_set)
1751 {
1752         const uint8_t pbf_cos_offset = 0;
1753         const uint8_t pbf_pri_offset = 0;
1754
1755         return elink_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set,
1756                 pbf_pri_offset, 3);
1757 }
1758
1759 /******************************************************************************
1760  * Description:
1761  *      Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1762  *      according to sp_pri_to_cos.(which COS has higher priority)
1763  *
1764  ******************************************************************************/
1765 static elink_status_t elink_ets_e3b0_sp_set_pri_cli_reg(
1766                                              const struct elink_params *params,
1767                                              uint8_t *sp_pri_to_cos)
1768 {
1769         struct bnx2x_softc *sc = params->sc;
1770         uint8_t i = 0;
1771         const uint8_t port = params->port;
1772         /* MCP Dbg0 and dbg1 are always with higher strict pri*/
1773         uint64_t pri_cli_nig = 0x210;
1774         uint32_t pri_cli_pbf = 0x0;
1775         uint8_t pri_set = 0;
1776         uint8_t pri_bitmask = 0;
1777         const uint8_t max_num_of_cos = (port) ?
1778                 ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1779                 ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1780
1781         uint8_t cos_bit_to_set = (1 << max_num_of_cos) - 1;
1782
1783         /* Set all the strict priority first */
1784         for (i = 0; i < max_num_of_cos; i++) {
1785                 if (sp_pri_to_cos[i] != DCBX_INVALID_COS) {
1786                         if (sp_pri_to_cos[i] >= ELINK_DCBX_MAX_NUM_COS) {
1787                                 ELINK_DEBUG_P0(sc,
1788                                            "elink_ets_e3b0_sp_set_pri_cli_reg "
1789                                            "invalid cos entry");
1790                                 return ELINK_STATUS_ERROR;
1791                         }
1792
1793                         pri_cli_nig |= elink_e3b0_sp_get_pri_cli_reg_nig(
1794                             sp_pri_to_cos[i], pri_set);
1795
1796                         pri_cli_pbf |= elink_e3b0_sp_get_pri_cli_reg_pbf(
1797                             sp_pri_to_cos[i], pri_set);
1798                         pri_bitmask = 1 << sp_pri_to_cos[i];
1799                         /* COS is used remove it from bitmap.*/
1800                         if (!(pri_bitmask & cos_bit_to_set)) {
1801                                 ELINK_DEBUG_P0(sc,
1802                                         "elink_ets_e3b0_sp_set_pri_cli_reg "
1803                                         "invalid There can't be two COS's with"
1804                                         " the same strict pri");
1805                                 return ELINK_STATUS_ERROR;
1806                         }
1807                         cos_bit_to_set &= ~pri_bitmask;
1808                         pri_set++;
1809                 }
1810         }
1811
1812         /* Set all the Non strict priority i= COS*/
1813         for (i = 0; i < max_num_of_cos; i++) {
1814                 pri_bitmask = 1 << i;
1815                 /* Check if COS was already used for SP */
1816                 if (pri_bitmask & cos_bit_to_set) {
1817                         /* COS wasn't used for SP */
1818                         pri_cli_nig |= elink_e3b0_sp_get_pri_cli_reg_nig(
1819                             i, pri_set);
1820
1821                         pri_cli_pbf |= elink_e3b0_sp_get_pri_cli_reg_pbf(
1822                             i, pri_set);
1823                         /* COS is used remove it from bitmap.*/
1824                         cos_bit_to_set &= ~pri_bitmask;
1825                         pri_set++;
1826                 }
1827         }
1828
1829         if (pri_set != max_num_of_cos) {
1830                 ELINK_DEBUG_P0(sc, "elink_ets_e3b0_sp_set_pri_cli_reg not all "
1831                                    "entries were set");
1832                 return ELINK_STATUS_ERROR;
1833         }
1834
1835         if (port) {
1836                 /* Only 6 usable clients*/
1837                 REG_WR(sc, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB,
1838                        (uint32_t)pri_cli_nig);
1839
1840                 REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1, pri_cli_pbf);
1841         } else {
1842                 /* Only 9 usable clients*/
1843                 const uint32_t pri_cli_nig_lsb = (uint32_t)(pri_cli_nig);
1844                 const uint32_t pri_cli_nig_msb = (uint32_t)
1845                                                 ((pri_cli_nig >> 32) & 0xF);
1846
1847                 REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB,
1848                        pri_cli_nig_lsb);
1849                 REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB,
1850                        pri_cli_nig_msb);
1851
1852                 REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0, pri_cli_pbf);
1853         }
1854         return ELINK_STATUS_OK;
1855 }
1856
1857 /******************************************************************************
1858  * Description:
1859  *      Configure the COS to ETS according to BW and SP settings.
1860  ******************************************************************************/
1861 elink_status_t elink_ets_e3b0_config(const struct elink_params *params,
1862                          const struct elink_vars *vars,
1863                          struct elink_ets_params *ets_params)
1864 {
1865         struct bnx2x_softc *sc = params->sc;
1866         elink_status_t elink_status = ELINK_STATUS_OK;
1867         const uint8_t port = params->port;
1868         uint16_t total_bw = 0;
1869         const uint32_t min_w_val_nig = elink_ets_get_min_w_val_nig(vars);
1870         const uint32_t min_w_val_pbf = ELINK_ETS_E3B0_PBF_MIN_W_VAL;
1871         uint8_t cos_bw_bitmap = 0;
1872         uint8_t cos_sp_bitmap = 0;
1873         uint8_t sp_pri_to_cos[ELINK_DCBX_MAX_NUM_COS] = {0};
1874         const uint8_t max_num_of_cos = (port) ?
1875                 ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1876                 ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1877         uint8_t cos_entry = 0;
1878
1879         if (!CHIP_IS_E3B0(sc)) {
1880                 ELINK_DEBUG_P0(sc,
1881                    "elink_ets_e3b0_disabled the chip isn't E3B0");
1882                 return ELINK_STATUS_ERROR;
1883         }
1884
1885         if (ets_params->num_of_cos > max_num_of_cos) {
1886                 ELINK_DEBUG_P0(sc, "elink_ets_E3B0_config the number of COS "
1887                                    "isn't supported");
1888                 return ELINK_STATUS_ERROR;
1889         }
1890
1891         /* Prepare sp strict priority parameters*/
1892         elink_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos);
1893
1894         /* Prepare BW parameters*/
1895         elink_status = elink_ets_e3b0_get_total_bw(params, ets_params,
1896                                                    &total_bw);
1897         if (elink_status != ELINK_STATUS_OK) {
1898                 ELINK_DEBUG_P0(sc,
1899                    "elink_ets_E3B0_config get_total_bw failed");
1900                 return ELINK_STATUS_ERROR;
1901         }
1902
1903         /* Upper bound is set according to current link speed (min_w_val
1904          * should be the same for upper bound and COS credit val).
1905          */
1906         elink_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
1907         elink_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1908
1909
1910         for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) {
1911                 if (elink_cos_state_bw == ets_params->cos[cos_entry].state) {
1912                         cos_bw_bitmap |= (1 << cos_entry);
1913                         /* The function also sets the BW in HW(not the mappin
1914                          * yet)
1915                          */
1916                         elink_status = elink_ets_e3b0_set_cos_bw(
1917                                 sc, cos_entry, min_w_val_nig, min_w_val_pbf,
1918                                 total_bw,
1919                                 ets_params->cos[cos_entry].params.bw_params.bw,
1920                                  port);
1921                 } else if (elink_cos_state_strict ==
1922                         ets_params->cos[cos_entry].state){
1923                         cos_sp_bitmap |= (1 << cos_entry);
1924
1925                         elink_status = elink_ets_e3b0_sp_pri_to_cos_set(
1926                                 params,
1927                                 sp_pri_to_cos,
1928                                 ets_params->cos[cos_entry].params.sp_params.pri,
1929                                 cos_entry);
1930
1931                 } else {
1932                         ELINK_DEBUG_P0(sc,
1933                            "elink_ets_e3b0_config cos state not valid");
1934                         return ELINK_STATUS_ERROR;
1935                 }
1936                 if (elink_status != ELINK_STATUS_OK) {
1937                         ELINK_DEBUG_P0(sc,
1938                            "elink_ets_e3b0_config set cos bw failed");
1939                         return elink_status;
1940                 }
1941         }
1942
1943         /* Set SP register (which COS has higher priority) */
1944         elink_status = elink_ets_e3b0_sp_set_pri_cli_reg(params,
1945                                                          sp_pri_to_cos);
1946
1947         if (elink_status != ELINK_STATUS_OK) {
1948                 ELINK_DEBUG_P0(sc,
1949                    "elink_ets_E3B0_config set_pri_cli_reg failed");
1950                 return elink_status;
1951         }
1952
1953         /* Set client mapping of BW and strict */
1954         elink_status = elink_ets_e3b0_cli_map(params, ets_params,
1955                                               cos_sp_bitmap,
1956                                               cos_bw_bitmap);
1957
1958         if (elink_status != ELINK_STATUS_OK) {
1959                 ELINK_DEBUG_P0(sc, "elink_ets_E3B0_config SP failed");
1960                 return elink_status;
1961         }
1962         return ELINK_STATUS_OK;
1963 }
1964 static void elink_ets_bw_limit_common(const struct elink_params *params)
1965 {
1966         /* ETS disabled configuration */
1967         struct bnx2x_softc *sc = params->sc;
1968         ELINK_DEBUG_P0(sc, "ETS enabled BW limit configuration");
1969         /* Defines which entries (clients) are subjected to WFQ arbitration
1970          * COS0 0x8
1971          * COS1 0x10
1972          */
1973         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
1974         /* Mapping between the ARB_CREDIT_WEIGHT registers and actual
1975          * client numbers (WEIGHT_0 does not actually have to represent
1976          * client 0)
1977          *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1978          *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
1979          */
1980         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
1981
1982         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
1983                ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1984         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
1985                ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1986
1987         /* ETS mode enabled*/
1988         REG_WR(sc, PBF_REG_ETS_ENABLED, 1);
1989
1990         /* Defines the number of consecutive slots for the strict priority */
1991         REG_WR(sc, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1992         /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1993          * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
1994          * entry, 4 - COS1 entry.
1995          * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1996          * bit4   bit3    bit2     bit1    bit0
1997          * MCP and debug are strict
1998          */
1999         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
2000
2001         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
2002         REG_WR(sc, PBF_REG_COS0_UPPER_BOUND,
2003                ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
2004         REG_WR(sc, PBF_REG_COS1_UPPER_BOUND,
2005                ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
2006 }
2007
2008 void elink_ets_bw_limit(const struct elink_params *params,
2009                         const uint32_t cos0_bw,
2010                         const uint32_t cos1_bw)
2011 {
2012         /* ETS disabled configuration*/
2013         struct bnx2x_softc *sc = params->sc;
2014         const uint32_t total_bw = cos0_bw + cos1_bw;
2015         uint32_t cos0_credit_weight = 0;
2016         uint32_t cos1_credit_weight = 0;
2017
2018         ELINK_DEBUG_P0(sc, "ETS enabled BW limit configuration");
2019
2020         if ((!total_bw) ||
2021             (!cos0_bw) ||
2022             (!cos1_bw)) {
2023                 ELINK_DEBUG_P0(sc, "Total BW can't be zero");
2024                 return;
2025         }
2026
2027         cos0_credit_weight = (cos0_bw * ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT) /
2028                 total_bw;
2029         cos1_credit_weight = (cos1_bw * ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT) /
2030                 total_bw;
2031
2032         elink_ets_bw_limit_common(params);
2033
2034         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
2035         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
2036
2037         REG_WR(sc, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
2038         REG_WR(sc, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
2039 }
2040
2041 elink_status_t elink_ets_strict(const struct elink_params *params,
2042                                 const uint8_t strict_cos)
2043 {
2044         /* ETS disabled configuration*/
2045         struct bnx2x_softc *sc = params->sc;
2046         uint32_t val    = 0;
2047
2048         ELINK_DEBUG_P0(sc, "ETS enabled strict configuration");
2049         /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
2050          * as strict.  Bits 0,1,2 - debug and management entries,
2051          * 3 - COS0 entry, 4 - COS1 entry.
2052          *  COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
2053          *  bit4   bit3   bit2      bit1     bit0
2054          * MCP and debug are strict
2055          */
2056         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
2057         /* For strict priority entries defines the number of consecutive slots
2058          * for the highest priority.
2059          */
2060         REG_WR(sc, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
2061         /* ETS mode disable */
2062         REG_WR(sc, PBF_REG_ETS_ENABLED, 0);
2063         /* Defines the number of consecutive slots for the strict priority */
2064         REG_WR(sc, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
2065
2066         /* Defines the number of consecutive slots for the strict priority */
2067         REG_WR(sc, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
2068
2069         /* Mapping between entry  priority to client number (0,1,2 -debug and
2070          * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
2071          * 3bits client num.
2072          *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
2073          * dbg0-010     dbg1-001     cos1-100     cos0-011     MCP-000
2074          * dbg0-010     dbg1-001     cos0-011     cos1-100     MCP-000
2075          */
2076         val = (!strict_cos) ? 0x2318 : 0x22E0;
2077         REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
2078
2079         return ELINK_STATUS_OK;
2080 }
2081
2082 /******************************************************************/
2083 /*                      PFC section                               */
2084 /******************************************************************/
2085 static void elink_update_pfc_xmac(struct elink_params *params,
2086                                   struct elink_vars *vars,
2087                                   __rte_unused uint8_t is_lb)
2088 {
2089         struct bnx2x_softc *sc = params->sc;
2090         uint32_t xmac_base;
2091         uint32_t pause_val, pfc0_val, pfc1_val;
2092
2093         /* XMAC base adrr */
2094         xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
2095
2096         /* Initialize pause and pfc registers */
2097         pause_val = 0x18000;
2098         pfc0_val = 0xFFFF8000;
2099         pfc1_val = 0x2;
2100
2101         /* No PFC support */
2102         if (!(params->feature_config_flags &
2103               ELINK_FEATURE_CONFIG_PFC_ENABLED)) {
2104
2105                 /* RX flow control - Process pause frame in receive direction
2106                  */
2107                 if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
2108                         pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
2109
2110                 /* TX flow control - Send pause packet when buffer is full */
2111                 if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
2112                         pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
2113         } else {/* PFC support */
2114                 pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
2115                         XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
2116                         XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
2117                         XMAC_PFC_CTRL_HI_REG_TX_PFC_EN |
2118                         XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
2119                 /* Write pause and PFC registers */
2120                 REG_WR(sc, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
2121                 REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
2122                 REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
2123                 pfc1_val &= ~XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
2124
2125         }
2126
2127         /* Write pause and PFC registers */
2128         REG_WR(sc, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
2129         REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
2130         REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
2131
2132
2133         /* Set MAC address for source TX Pause/PFC frames */
2134         REG_WR(sc, xmac_base + XMAC_REG_CTRL_SA_LO,
2135                ((params->mac_addr[2] << 24) |
2136                 (params->mac_addr[3] << 16) |
2137                 (params->mac_addr[4] << 8) |
2138                 (params->mac_addr[5])));
2139         REG_WR(sc, xmac_base + XMAC_REG_CTRL_SA_HI,
2140                ((params->mac_addr[0] << 8) |
2141                 (params->mac_addr[1])));
2142
2143         DELAY(30);
2144 }
2145
2146 static void elink_emac_get_pfc_stat(struct elink_params *params,
2147                                     uint32_t pfc_frames_sent[2],
2148                                     uint32_t pfc_frames_received[2])
2149 {
2150         /* Read pfc statistic */
2151         struct bnx2x_softc *sc = params->sc;
2152         uint32_t emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2153         uint32_t val_xon = 0;
2154         uint32_t val_xoff = 0;
2155
2156         ELINK_DEBUG_P0(sc, "pfc statistic read from EMAC");
2157
2158         /* PFC received frames */
2159         val_xoff = REG_RD(sc, emac_base +
2160                                 EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
2161         val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
2162         val_xon = REG_RD(sc, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
2163         val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
2164
2165         pfc_frames_received[0] = val_xon + val_xoff;
2166
2167         /* PFC received sent */
2168         val_xoff = REG_RD(sc, emac_base +
2169                                 EMAC_REG_RX_PFC_STATS_XOFF_SENT);
2170         val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
2171         val_xon = REG_RD(sc, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
2172         val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
2173
2174         pfc_frames_sent[0] = val_xon + val_xoff;
2175 }
2176
2177 /* Read pfc statistic*/
2178 void elink_pfc_statistic(struct elink_params *params, struct elink_vars *vars,
2179                          uint32_t pfc_frames_sent[2],
2180                          uint32_t pfc_frames_received[2])
2181 {
2182         /* Read pfc statistic */
2183         struct bnx2x_softc *sc = params->sc;
2184
2185         ELINK_DEBUG_P0(sc, "pfc statistic");
2186
2187         if (!vars->link_up)
2188                 return;
2189
2190         if (vars->mac_type == ELINK_MAC_TYPE_EMAC) {
2191                 ELINK_DEBUG_P0(sc, "About to read PFC stats from EMAC");
2192                 elink_emac_get_pfc_stat(params, pfc_frames_sent,
2193                                         pfc_frames_received);
2194         }
2195 }
2196 /******************************************************************/
2197 /*                      MAC/PBF section                           */
2198 /******************************************************************/
2199 static void elink_set_mdio_clk(struct bnx2x_softc *sc,
2200                                __rte_unused uint32_t chip_id,
2201                                uint32_t emac_base)
2202 {
2203         uint32_t new_mode, cur_mode;
2204         uint32_t clc_cnt;
2205         /* Set clause 45 mode, slow down the MDIO clock to 2.5MHz
2206          * (a value of 49==0x31) and make sure that the AUTO poll is off
2207          */
2208         cur_mode = REG_RD(sc, emac_base + EMAC_REG_EMAC_MDIO_MODE);
2209
2210         if (USES_WARPCORE(sc))
2211                 clc_cnt = 74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
2212         else
2213                 clc_cnt = 49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
2214
2215         if (((cur_mode & EMAC_MDIO_MODE_CLOCK_CNT) == clc_cnt) &&
2216             (cur_mode & (EMAC_MDIO_MODE_CLAUSE_45)))
2217                 return;
2218
2219         new_mode = cur_mode &
2220                 ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
2221         new_mode |= clc_cnt;
2222         new_mode |= (EMAC_MDIO_MODE_CLAUSE_45);
2223
2224         ELINK_DEBUG_P2(sc, "Changing emac_mode from 0x%x to 0x%x",
2225            cur_mode, new_mode);
2226         REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_MODE, new_mode);
2227         DELAY(40);
2228 }
2229
2230 static uint8_t elink_is_4_port_mode(struct bnx2x_softc *sc)
2231 {
2232         uint32_t port4mode_ovwr_val;
2233         /* Check 4-port override enabled */
2234         port4mode_ovwr_val = REG_RD(sc, MISC_REG_PORT4MODE_EN_OVWR);
2235         if (port4mode_ovwr_val & (1 << 0)) {
2236                 /* Return 4-port mode override value */
2237                 return ((port4mode_ovwr_val & (1 << 1)) == (1 << 1));
2238         }
2239         /* Return 4-port mode from input pin */
2240         return (uint8_t)REG_RD(sc, MISC_REG_PORT4MODE_EN);
2241 }
2242
2243 static void elink_set_mdio_emac_per_phy(struct bnx2x_softc *sc,
2244                                         struct elink_params *params)
2245 {
2246         uint8_t phy_index;
2247
2248         /* Set mdio clock per phy */
2249         for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
2250               phy_index++)
2251                 elink_set_mdio_clk(sc, params->chip_id,
2252                                    params->phy[phy_index].mdio_ctrl);
2253 }
2254
2255 static void elink_emac_init(struct elink_params *params,
2256                             __rte_unused struct elink_vars *vars)
2257 {
2258         /* reset and unreset the emac core */
2259         struct bnx2x_softc *sc = params->sc;
2260         uint8_t port = params->port;
2261         uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2262         uint32_t val;
2263         uint16_t timeout;
2264
2265         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2266                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
2267         DELAY(5);
2268         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2269                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
2270
2271         /* init emac - use read-modify-write */
2272         /* self clear reset */
2273         val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2274         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE,
2275                            (val | EMAC_MODE_RESET));
2276
2277         timeout = 200;
2278         do {
2279                 val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2280                 ELINK_DEBUG_P1(sc, "EMAC reset reg is %u", val);
2281                 if (!timeout) {
2282                         ELINK_DEBUG_P0(sc, "EMAC timeout!");
2283                         return;
2284                 }
2285                 timeout--;
2286         } while (val & EMAC_MODE_RESET);
2287
2288         elink_set_mdio_emac_per_phy(sc, params);
2289         /* Set mac address */
2290         val = ((params->mac_addr[0] << 8) |
2291                 params->mac_addr[1]);
2292         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MAC_MATCH, val);
2293
2294         val = ((params->mac_addr[2] << 24) |
2295                (params->mac_addr[3] << 16) |
2296                (params->mac_addr[4] << 8) |
2297                 params->mac_addr[5]);
2298         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MAC_MATCH + 4, val);
2299 }
2300
2301 static void elink_set_xumac_nig(struct elink_params *params,
2302                                 uint16_t tx_pause_en,
2303                                 uint8_t enable)
2304 {
2305         struct bnx2x_softc *sc = params->sc;
2306
2307         REG_WR(sc, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
2308                enable);
2309         REG_WR(sc, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
2310                enable);
2311         REG_WR(sc, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
2312                NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
2313 }
2314
2315 static void elink_set_umac_rxtx(struct elink_params *params, uint8_t en)
2316 {
2317         uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
2318         uint32_t val;
2319         struct bnx2x_softc *sc = params->sc;
2320         if (!(REG_RD(sc, MISC_REG_RESET_REG_2) &
2321                    (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)))
2322                 return;
2323         val = REG_RD(sc, umac_base + UMAC_REG_COMMAND_CONFIG);
2324         if (en)
2325                 val |= (UMAC_COMMAND_CONFIG_REG_TX_ENA |
2326                         UMAC_COMMAND_CONFIG_REG_RX_ENA);
2327         else
2328                 val &= ~(UMAC_COMMAND_CONFIG_REG_TX_ENA |
2329                          UMAC_COMMAND_CONFIG_REG_RX_ENA);
2330         /* Disable RX and TX */
2331         REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2332 }
2333
2334 static void elink_umac_enable(struct elink_params *params,
2335                             struct elink_vars *vars, uint8_t lb)
2336 {
2337         uint32_t val;
2338         uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
2339         struct bnx2x_softc *sc = params->sc;
2340         /* Reset UMAC */
2341         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2342                (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
2343         DELAY(1000 * 1);
2344
2345         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2346                (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
2347
2348         ELINK_DEBUG_P0(sc, "enabling UMAC");
2349
2350         /* This register opens the gate for the UMAC despite its name */
2351         REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port * 4, 1);
2352
2353         val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
2354                 UMAC_COMMAND_CONFIG_REG_PAD_EN |
2355                 UMAC_COMMAND_CONFIG_REG_SW_RESET |
2356                 UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
2357         switch (vars->line_speed) {
2358         case ELINK_SPEED_10:
2359                 val |= (0 << 2);
2360                 break;
2361         case ELINK_SPEED_100:
2362                 val |= (1 << 2);
2363                 break;
2364         case ELINK_SPEED_1000:
2365                 val |= (2 << 2);
2366                 break;
2367         case ELINK_SPEED_2500:
2368                 val |= (3 << 2);
2369                 break;
2370         default:
2371                 ELINK_DEBUG_P1(sc, "Invalid speed for UMAC %d",
2372                                vars->line_speed);
2373                 break;
2374         }
2375         if (!(vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2376                 val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE;
2377
2378         if (!(vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2379                 val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
2380
2381         if (vars->duplex == DUPLEX_HALF)
2382                 val |= UMAC_COMMAND_CONFIG_REG_HD_ENA;
2383
2384         REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2385         DELAY(50);
2386
2387         /* Configure UMAC for EEE */
2388         if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
2389                 ELINK_DEBUG_P0(sc, "configured UMAC for EEE");
2390                 REG_WR(sc, umac_base + UMAC_REG_UMAC_EEE_CTRL,
2391                        UMAC_UMAC_EEE_CTRL_REG_EEE_EN);
2392                 REG_WR(sc, umac_base + UMAC_REG_EEE_WAKE_TIMER, 0x11);
2393         } else {
2394                 REG_WR(sc, umac_base + UMAC_REG_UMAC_EEE_CTRL, 0x0);
2395         }
2396
2397         /* Set MAC address for source TX Pause/PFC frames (under SW reset) */
2398         REG_WR(sc, umac_base + UMAC_REG_MAC_ADDR0,
2399                ((params->mac_addr[2] << 24) |
2400                 (params->mac_addr[3] << 16) |
2401                 (params->mac_addr[4] << 8) |
2402                 (params->mac_addr[5])));
2403         REG_WR(sc, umac_base + UMAC_REG_MAC_ADDR1,
2404                ((params->mac_addr[0] << 8) |
2405                 (params->mac_addr[1])));
2406
2407         /* Enable RX and TX */
2408         val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
2409         val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
2410                 UMAC_COMMAND_CONFIG_REG_RX_ENA;
2411         REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2412         DELAY(50);
2413
2414         /* Remove SW Reset */
2415         val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
2416
2417         /* Check loopback mode */
2418         if (lb)
2419                 val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
2420         REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2421
2422         /* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
2423          * length used by the MAC receive logic to check frames.
2424          */
2425         REG_WR(sc, umac_base + UMAC_REG_MAXFR, 0x2710);
2426         elink_set_xumac_nig(params,
2427                             ((vars->flow_ctrl & ELINK_FLOW_CTRL_TX) != 0), 1);
2428         vars->mac_type = ELINK_MAC_TYPE_UMAC;
2429
2430 }
2431
2432 /* Define the XMAC mode */
2433 static void elink_xmac_init(struct elink_params *params, uint32_t max_speed)
2434 {
2435         struct bnx2x_softc *sc = params->sc;
2436         uint32_t is_port4mode = elink_is_4_port_mode(sc);
2437
2438         /* In 4-port mode, need to set the mode only once, so if XMAC is
2439          * already out of reset, it means the mode has already been set,
2440          * and it must not* reset the XMAC again, since it controls both
2441          * ports of the path
2442          */
2443
2444         if (((CHIP_NUM(sc) == CHIP_NUM_57840_4_10) ||
2445              (CHIP_NUM(sc) == CHIP_NUM_57840_2_20) ||
2446              (CHIP_NUM(sc) == CHIP_NUM_57840_OBS)) &&
2447             is_port4mode &&
2448             (REG_RD(sc, MISC_REG_RESET_REG_2) &
2449              MISC_REGISTERS_RESET_REG_2_XMAC)) {
2450                 ELINK_DEBUG_P0(sc,
2451                    "XMAC already out of reset in 4-port mode");
2452                 return;
2453         }
2454
2455         /* Hard reset */
2456         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2457                MISC_REGISTERS_RESET_REG_2_XMAC);
2458         DELAY(1000 * 1);
2459
2460         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2461                MISC_REGISTERS_RESET_REG_2_XMAC);
2462         if (is_port4mode) {
2463                 ELINK_DEBUG_P0(sc, "Init XMAC to 2 ports x 10G per path");
2464
2465                 /* Set the number of ports on the system side to up to 2 */
2466                 REG_WR(sc, MISC_REG_XMAC_CORE_PORT_MODE, 1);
2467
2468                 /* Set the number of ports on the Warp Core to 10G */
2469                 REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 3);
2470         } else {
2471                 /* Set the number of ports on the system side to 1 */
2472                 REG_WR(sc, MISC_REG_XMAC_CORE_PORT_MODE, 0);
2473                 if (max_speed == ELINK_SPEED_10000) {
2474                         ELINK_DEBUG_P0(sc,
2475                            "Init XMAC to 10G x 1 port per path");
2476                         /* Set the number of ports on the Warp Core to 10G */
2477                         REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 3);
2478                 } else {
2479                         ELINK_DEBUG_P0(sc,
2480                            "Init XMAC to 20G x 2 ports per path");
2481                         /* Set the number of ports on the Warp Core to 20G */
2482                         REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 1);
2483                 }
2484         }
2485         /* Soft reset */
2486         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2487                MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
2488         DELAY(1000 * 1);
2489
2490         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2491                MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
2492
2493 }
2494
2495 static void elink_set_xmac_rxtx(struct elink_params *params, uint8_t en)
2496 {
2497         uint8_t port = params->port;
2498         struct bnx2x_softc *sc = params->sc;
2499         uint32_t pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
2500         uint32_t val;
2501
2502         if (REG_RD(sc, MISC_REG_RESET_REG_2) &
2503             MISC_REGISTERS_RESET_REG_2_XMAC) {
2504                 /* Send an indication to change the state in the NIG back to XON
2505                  * Clearing this bit enables the next set of this bit to get
2506                  * rising edge
2507                  */
2508                 pfc_ctrl = REG_RD(sc, xmac_base + XMAC_REG_PFC_CTRL_HI);
2509                 REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI,
2510                        (pfc_ctrl & ~(1 << 1)));
2511                 REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI,
2512                        (pfc_ctrl | (1 << 1)));
2513                 ELINK_DEBUG_P1(sc, "Disable XMAC on port %x", port);
2514                 val = REG_RD(sc, xmac_base + XMAC_REG_CTRL);
2515                 if (en)
2516                         val |= (XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
2517                 else
2518                         val &= ~(XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
2519                 REG_WR(sc, xmac_base + XMAC_REG_CTRL, val);
2520         }
2521 }
2522
2523 static elink_status_t elink_xmac_enable(struct elink_params *params,
2524                              struct elink_vars *vars, uint8_t lb)
2525 {
2526         uint32_t val, xmac_base;
2527         struct bnx2x_softc *sc = params->sc;
2528         ELINK_DEBUG_P0(sc, "enabling XMAC");
2529
2530         xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
2531
2532         elink_xmac_init(params, vars->line_speed);
2533
2534         /* This register determines on which events the MAC will assert
2535          * error on the i/f to the NIG along w/ EOP.
2536          */
2537
2538         /* This register tells the NIG whether to send traffic to UMAC
2539          * or XMAC
2540          */
2541         REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port * 4, 0);
2542
2543         /* When XMAC is in XLGMII mode, disable sending idles for fault
2544          * detection.
2545          */
2546         if (!(params->phy[ELINK_INT_PHY].flags & ELINK_FLAGS_TX_ERROR_CHECK)) {
2547                 REG_WR(sc, xmac_base + XMAC_REG_RX_LSS_CTRL,
2548                        (XMAC_RX_LSS_CTRL_REG_LOCAL_FAULT_DISABLE |
2549                         XMAC_RX_LSS_CTRL_REG_REMOTE_FAULT_DISABLE));
2550                 REG_WR(sc, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
2551                 REG_WR(sc, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
2552                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
2553                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
2554         }
2555         /* Set Max packet size */
2556         REG_WR(sc, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
2557
2558         /* CRC append for Tx packets */
2559         REG_WR(sc, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
2560
2561         /* update PFC */
2562         elink_update_pfc_xmac(params, vars, 0);
2563
2564         if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
2565                 ELINK_DEBUG_P0(sc, "Setting XMAC for EEE");
2566                 REG_WR(sc, xmac_base + XMAC_REG_EEE_TIMERS_HI, 0x1380008);
2567                 REG_WR(sc, xmac_base + XMAC_REG_EEE_CTRL, 0x1);
2568         } else {
2569                 REG_WR(sc, xmac_base + XMAC_REG_EEE_CTRL, 0x0);
2570         }
2571
2572         /* Enable TX and RX */
2573         val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
2574
2575         /* Set MAC in XLGMII mode for dual-mode */
2576         if ((vars->line_speed == ELINK_SPEED_20000) &&
2577             (params->phy[ELINK_INT_PHY].supported &
2578              ELINK_SUPPORTED_20000baseKR2_Full))
2579                 val |= XMAC_CTRL_REG_XLGMII_ALIGN_ENB;
2580
2581         /* Check loopback mode */
2582         if (lb)
2583                 val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK;
2584         REG_WR(sc, xmac_base + XMAC_REG_CTRL, val);
2585         elink_set_xumac_nig(params,
2586                             ((vars->flow_ctrl & ELINK_FLOW_CTRL_TX) != 0), 1);
2587
2588         vars->mac_type = ELINK_MAC_TYPE_XMAC;
2589
2590         return ELINK_STATUS_OK;
2591 }
2592
2593 static elink_status_t elink_emac_enable(struct elink_params *params,
2594                              struct elink_vars *vars, uint8_t lb)
2595 {
2596         struct bnx2x_softc *sc = params->sc;
2597         uint8_t port = params->port;
2598         uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2599         uint32_t val;
2600
2601         ELINK_DEBUG_P0(sc, "enabling EMAC");
2602
2603         /* Disable BMAC */
2604         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2605                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2606
2607         /* enable emac and not bmac */
2608         REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + port * 4, 1);
2609
2610 #ifdef ELINK_INCLUDE_EMUL
2611         /* for paladium */
2612         if (CHIP_REV_IS_EMUL(sc)) {
2613                 /* Use lane 1 (of lanes 0-3) */
2614                 REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, 1);
2615                 REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 1);
2616         }
2617         /* for fpga */
2618         else
2619 #endif
2620 #ifdef ELINK_INCLUDE_FPGA
2621         if (CHIP_REV_IS_FPGA(sc)) {
2622                 /* Use lane 1 (of lanes 0-3) */
2623                 ELINK_DEBUG_P0(sc, "elink_emac_enable: Setting FPGA");
2624
2625                 REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, 1);
2626                 REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 0);
2627         } else
2628 #endif
2629         /* ASIC */
2630         if (vars->phy_flags & PHY_XGXS_FLAG) {
2631                 uint32_t ser_lane = ((params->lane_config &
2632                                  PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
2633                                 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
2634
2635                 ELINK_DEBUG_P0(sc, "XGXS");
2636                 /* select the master lanes (out of 0-3) */
2637                 REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, ser_lane);
2638                 /* select XGXS */
2639                 REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 1);
2640
2641         } else { /* SerDes */
2642                 ELINK_DEBUG_P0(sc, "SerDes");
2643                 /* select SerDes */
2644                 REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 0);
2645         }
2646
2647         elink_bits_en(sc, emac_base + EMAC_REG_EMAC_RX_MODE,
2648                       EMAC_RX_MODE_RESET);
2649         elink_bits_en(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
2650                       EMAC_TX_MODE_RESET);
2651
2652 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
2653         if (CHIP_REV_IS_SLOW(sc)) {
2654                 /* config GMII mode */
2655                 val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2656                 elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE,
2657                                    (val | EMAC_MODE_PORT_GMII));
2658         } else { /* ASIC */
2659 #endif
2660                 /* pause enable/disable */
2661                 elink_bits_dis(sc, emac_base + EMAC_REG_EMAC_RX_MODE,
2662                                EMAC_RX_MODE_FLOW_EN);
2663
2664                 elink_bits_dis(sc,  emac_base + EMAC_REG_EMAC_TX_MODE,
2665                                (EMAC_TX_MODE_EXT_PAUSE_EN |
2666                                 EMAC_TX_MODE_FLOW_EN));
2667                 if (!(params->feature_config_flags &
2668                       ELINK_FEATURE_CONFIG_PFC_ENABLED)) {
2669                         if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
2670                                 elink_bits_en(sc, emac_base +
2671                                               EMAC_REG_EMAC_RX_MODE,
2672                                               EMAC_RX_MODE_FLOW_EN);
2673
2674                         if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
2675                                 elink_bits_en(sc, emac_base +
2676                                               EMAC_REG_EMAC_TX_MODE,
2677                                               (EMAC_TX_MODE_EXT_PAUSE_EN |
2678                                                EMAC_TX_MODE_FLOW_EN));
2679                 } else
2680                         elink_bits_en(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
2681                                       EMAC_TX_MODE_FLOW_EN);
2682 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
2683         }
2684 #endif
2685
2686         /* KEEP_VLAN_TAG, promiscuous */
2687         val = REG_RD(sc, emac_base + EMAC_REG_EMAC_RX_MODE);
2688         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
2689
2690         /* Setting this bit causes MAC control frames (except for pause
2691          * frames) to be passed on for processing. This setting has no
2692          * affect on the operation of the pause frames. This bit effects
2693          * all packets regardless of RX Parser packet sorting logic.
2694          * Turn the PFC off to make sure we are in Xon state before
2695          * enabling it.
2696          */
2697         elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_MODE, 0);
2698         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED) {
2699                 ELINK_DEBUG_P0(sc, "PFC is enabled");
2700                 /* Enable PFC again */
2701                 elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_MODE,
2702                         EMAC_REG_RX_PFC_MODE_RX_EN |
2703                         EMAC_REG_RX_PFC_MODE_TX_EN |
2704                         EMAC_REG_RX_PFC_MODE_PRIORITIES);
2705
2706                 elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_PARAM,
2707                         ((0x0101 <<
2708                           EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
2709                          (0x00ff <<
2710                           EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
2711                 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
2712         }
2713         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_RX_MODE, val);
2714
2715         /* Set Loopback */
2716         val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2717         if (lb)
2718                 val |= 0x810;
2719         else
2720                 val &= ~0x810;
2721         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE, val);
2722
2723         /* Enable emac */
2724         REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port * 4, 1);
2725
2726         /* Enable emac for jumbo packets */
2727         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_RX_MTU_SIZE,
2728                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
2729                  (ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD)));
2730
2731         /* Strip CRC */
2732         REG_WR(sc, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port * 4, 0x1);
2733
2734         /* Disable the NIG in/out to the bmac */
2735         REG_WR(sc, NIG_REG_BMAC0_IN_EN + port * 4, 0x0);
2736         REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + port * 4, 0x0);
2737         REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port * 4, 0x0);
2738
2739         /* Enable the NIG in/out to the emac */
2740         REG_WR(sc, NIG_REG_EMAC0_IN_EN + port * 4, 0x1);
2741         val = 0;
2742         if ((params->feature_config_flags &
2743               ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
2744             (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2745                 val = 1;
2746
2747         REG_WR(sc, NIG_REG_EMAC0_PAUSE_OUT_EN + port * 4, val);
2748         REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port * 4, 0x1);
2749
2750 #ifdef ELINK_INCLUDE_EMUL
2751         if (CHIP_REV_IS_EMUL(sc)) {
2752                 /* Take the BigMac out of reset */
2753                 REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2754                        (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2755
2756                 /* Enable access for bmac registers */
2757                 REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port * 4, 0x1);
2758         } else
2759 #endif
2760         REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port * 4, 0x0);
2761
2762         vars->mac_type = ELINK_MAC_TYPE_EMAC;
2763         return ELINK_STATUS_OK;
2764 }
2765
2766 static void elink_update_pfc_bmac1(struct elink_params *params,
2767                                    struct elink_vars *vars)
2768 {
2769         uint32_t wb_data[2];
2770         struct bnx2x_softc *sc = params->sc;
2771         uint32_t bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
2772                 NIG_REG_INGRESS_BMAC0_MEM;
2773
2774         uint32_t val = 0x14;
2775         if ((!(params->feature_config_flags &
2776               ELINK_FEATURE_CONFIG_PFC_ENABLED)) &&
2777                 (vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2778                 /* Enable BigMAC to react on received Pause packets */
2779                 val |= (1 << 5);
2780         wb_data[0] = val;
2781         wb_data[1] = 0;
2782         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
2783
2784         /* TX control */
2785         val = 0xc0;
2786         if (!(params->feature_config_flags &
2787               ELINK_FEATURE_CONFIG_PFC_ENABLED) &&
2788                 (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2789                 val |= 0x800000;
2790         wb_data[0] = val;
2791         wb_data[1] = 0;
2792         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
2793 }
2794
2795 static void elink_update_pfc_bmac2(struct elink_params *params,
2796                                    struct elink_vars *vars,
2797                                    uint8_t is_lb)
2798 {
2799         /* Set rx control: Strip CRC and enable BigMAC to relay
2800          * control packets to the system as well
2801          */
2802         uint32_t wb_data[2];
2803         struct bnx2x_softc *sc = params->sc;
2804         uint32_t bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
2805                 NIG_REG_INGRESS_BMAC0_MEM;
2806         uint32_t val = 0x14;
2807
2808         if ((!(params->feature_config_flags &
2809               ELINK_FEATURE_CONFIG_PFC_ENABLED)) &&
2810                 (vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2811                 /* Enable BigMAC to react on received Pause packets */
2812                 val |= (1 << 5);
2813         wb_data[0] = val;
2814         wb_data[1] = 0;
2815         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
2816         DELAY(30);
2817
2818         /* Tx control */
2819         val = 0xc0;
2820         if (!(params->feature_config_flags &
2821                                 ELINK_FEATURE_CONFIG_PFC_ENABLED) &&
2822             (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2823                 val |= 0x800000;
2824         wb_data[0] = val;
2825         wb_data[1] = 0;
2826         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
2827
2828         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED) {
2829                 ELINK_DEBUG_P0(sc, "PFC is enabled");
2830                 /* Enable PFC RX & TX & STATS and set 8 COS  */
2831                 wb_data[0] = 0x0;
2832                 wb_data[0] |= (1 << 0);  /* RX */
2833                 wb_data[0] |= (1 << 1);  /* TX */
2834                 wb_data[0] |= (1 << 2);  /* Force initial Xon */
2835                 wb_data[0] |= (1 << 3);  /* 8 cos */
2836                 wb_data[0] |= (1 << 5);  /* STATS */
2837                 wb_data[1] = 0;
2838                 REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
2839                             wb_data, 2);
2840                 /* Clear the force Xon */
2841                 wb_data[0] &= ~(1 << 2);
2842         } else {
2843                 ELINK_DEBUG_P0(sc, "PFC is disabled");
2844                 /* Disable PFC RX & TX & STATS and set 8 COS */
2845                 wb_data[0] = 0x8;
2846                 wb_data[1] = 0;
2847         }
2848
2849         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
2850
2851         /* Set Time (based unit is 512 bit time) between automatic
2852          * re-sending of PP packets amd enable automatic re-send of
2853          * Per-Priroity Packet as long as pp_gen is asserted and
2854          * pp_disable is low.
2855          */
2856         val = 0x8000;
2857         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
2858                 val |= (1 << 16); /* enable automatic re-send */
2859
2860         wb_data[0] = val;
2861         wb_data[1] = 0;
2862         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
2863                     wb_data, 2);
2864
2865         /* mac control */
2866         val = 0x3; /* Enable RX and TX */
2867         if (is_lb) {
2868                 val |= 0x4; /* Local loopback */
2869                 ELINK_DEBUG_P0(sc, "enable bmac loopback");
2870         }
2871         /* When PFC enabled, Pass pause frames towards the NIG. */
2872         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
2873                 val |= ((1 << 6) | (1 << 5));
2874
2875         wb_data[0] = val;
2876         wb_data[1] = 0;
2877         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2878 }
2879
2880 /******************************************************************************
2881  * Description:
2882  *  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2883  *  not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2884  ******************************************************************************/
2885 static elink_status_t elink_pfc_nig_rx_priority_mask(struct bnx2x_softc *sc,
2886                                            uint8_t cos_entry,
2887                                            uint32_t priority_mask, uint8_t port)
2888 {
2889         uint32_t nig_reg_rx_priority_mask_add = 0;
2890
2891         switch (cos_entry) {
2892         case 0:
2893              nig_reg_rx_priority_mask_add = (port) ?
2894                  NIG_REG_P1_RX_COS0_PRIORITY_MASK :
2895                  NIG_REG_P0_RX_COS0_PRIORITY_MASK;
2896                 break;
2897         case 1:
2898             nig_reg_rx_priority_mask_add = (port) ?
2899                 NIG_REG_P1_RX_COS1_PRIORITY_MASK :
2900                 NIG_REG_P0_RX_COS1_PRIORITY_MASK;
2901                 break;
2902         case 2:
2903             nig_reg_rx_priority_mask_add = (port) ?
2904                 NIG_REG_P1_RX_COS2_PRIORITY_MASK :
2905                 NIG_REG_P0_RX_COS2_PRIORITY_MASK;
2906                 break;
2907         case 3:
2908                 if (port)
2909                 return ELINK_STATUS_ERROR;
2910             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
2911                 break;
2912         case 4:
2913                 if (port)
2914                 return ELINK_STATUS_ERROR;
2915             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
2916                 break;
2917         case 5:
2918                 if (port)
2919                 return ELINK_STATUS_ERROR;
2920             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
2921                 break;
2922         }
2923
2924         REG_WR(sc, nig_reg_rx_priority_mask_add, priority_mask);
2925
2926         return ELINK_STATUS_OK;
2927 }
2928 static void elink_update_mng(struct elink_params *params, uint32_t link_status)
2929 {
2930         struct bnx2x_softc *sc = params->sc;
2931
2932         REG_WR(sc, params->shmem_base +
2933                offsetof(struct shmem_region,
2934                         port_mb[params->port].link_status), link_status);
2935 }
2936
2937 static void elink_update_pfc_nig(struct elink_params *params,
2938                 __rte_unused struct elink_vars *vars,
2939                 struct elink_nig_brb_pfc_port_params *nig_params)
2940 {
2941         uint32_t xcm_mask = 0, ppp_enable = 0, pause_enable = 0;
2942         uint32_t llfc_out_en = 0;
2943         uint32_t llfc_enable = 0, xcm_out_en = 0, hwpfc_enable = 0;
2944         uint32_t pkt_priority_to_cos = 0;
2945         struct bnx2x_softc *sc = params->sc;
2946         uint8_t port = params->port;
2947
2948         int set_pfc = params->feature_config_flags &
2949                 ELINK_FEATURE_CONFIG_PFC_ENABLED;
2950         ELINK_DEBUG_P0(sc, "updating pfc nig parameters");
2951
2952         /* When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2953          * MAC control frames (that are not pause packets)
2954          * will be forwarded to the XCM.
2955          */
2956         xcm_mask = REG_RD(sc, port ? NIG_REG_LLH1_XCM_MASK :
2957                           NIG_REG_LLH0_XCM_MASK);
2958         /* NIG params will override non PFC params, since it's possible to
2959          * do transition from PFC to SAFC
2960          */
2961         if (set_pfc) {
2962                 pause_enable = 0;
2963                 llfc_out_en = 0;
2964                 llfc_enable = 0;
2965                 if (CHIP_IS_E3(sc))
2966                         ppp_enable = 0;
2967                 else
2968                         ppp_enable = 1;
2969                 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2970                                      NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2971                 xcm_out_en = 0;
2972                 hwpfc_enable = 1;
2973         } else  {
2974                 if (nig_params) {
2975                         llfc_out_en = nig_params->llfc_out_en;
2976                         llfc_enable = nig_params->llfc_enable;
2977                         pause_enable = nig_params->pause_enable;
2978                 } else  /* Default non PFC mode - PAUSE */
2979                         pause_enable = 1;
2980
2981                 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2982                         NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2983                 xcm_out_en = 1;
2984         }
2985
2986         if (CHIP_IS_E3(sc))
2987                 REG_WR(sc, port ? NIG_REG_BRB1_PAUSE_IN_EN :
2988                        NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
2989         REG_WR(sc, port ? NIG_REG_LLFC_OUT_EN_1 :
2990                NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
2991         REG_WR(sc, port ? NIG_REG_LLFC_ENABLE_1 :
2992                NIG_REG_LLFC_ENABLE_0, llfc_enable);
2993         REG_WR(sc, port ? NIG_REG_PAUSE_ENABLE_1 :
2994                NIG_REG_PAUSE_ENABLE_0, pause_enable);
2995
2996         REG_WR(sc, port ? NIG_REG_PPP_ENABLE_1 :
2997                NIG_REG_PPP_ENABLE_0, ppp_enable);
2998
2999         REG_WR(sc, port ? NIG_REG_LLH1_XCM_MASK :
3000                NIG_REG_LLH0_XCM_MASK, xcm_mask);
3001
3002         REG_WR(sc, port ? NIG_REG_LLFC_EGRESS_SRC_ENABLE_1 :
3003                NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
3004
3005         /* Output enable for RX_XCM # IF */
3006         REG_WR(sc, port ? NIG_REG_XCM1_OUT_EN :
3007                NIG_REG_XCM0_OUT_EN, xcm_out_en);
3008
3009         /* HW PFC TX enable */
3010         REG_WR(sc, port ? NIG_REG_P1_HWPFC_ENABLE :
3011                NIG_REG_P0_HWPFC_ENABLE, hwpfc_enable);
3012
3013         if (nig_params) {
3014                 uint8_t i = 0;
3015                 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
3016
3017                 for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
3018                         elink_pfc_nig_rx_priority_mask(sc, i,
3019                 nig_params->rx_cos_priority_mask[i], port);
3020
3021                 REG_WR(sc, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
3022                        NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
3023                        nig_params->llfc_high_priority_classes);
3024
3025                 REG_WR(sc, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
3026                        NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
3027                        nig_params->llfc_low_priority_classes);
3028         }
3029         REG_WR(sc, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
3030                NIG_REG_P0_PKT_PRIORITY_TO_COS,
3031                pkt_priority_to_cos);
3032 }
3033
3034 elink_status_t elink_update_pfc(struct elink_params *params,
3035                       struct elink_vars *vars,
3036                       struct elink_nig_brb_pfc_port_params *pfc_params)
3037 {
3038         /* The PFC and pause are orthogonal to one another, meaning when
3039          * PFC is enabled, the pause are disabled, and when PFC is
3040          * disabled, pause are set according to the pause result.
3041          */
3042         uint32_t val;
3043         struct bnx2x_softc *sc = params->sc;
3044         uint8_t bmac_loopback = (params->loopback_mode == ELINK_LOOPBACK_BMAC);
3045
3046         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
3047                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
3048         else
3049                 vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
3050
3051         elink_update_mng(params, vars->link_status);
3052
3053         /* Update NIG params */
3054         elink_update_pfc_nig(params, vars, pfc_params);
3055
3056         if (!vars->link_up)
3057                 return ELINK_STATUS_OK;
3058
3059         ELINK_DEBUG_P0(sc, "About to update PFC in BMAC");
3060
3061         if (CHIP_IS_E3(sc)) {
3062                 if (vars->mac_type == ELINK_MAC_TYPE_XMAC)
3063                         elink_update_pfc_xmac(params, vars, 0);
3064         } else {
3065                 val = REG_RD(sc, MISC_REG_RESET_REG_2);
3066                 if ((val &
3067                      (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
3068                     == 0) {
3069                         ELINK_DEBUG_P0(sc, "About to update PFC in EMAC");
3070                         elink_emac_enable(params, vars, 0);
3071                         return ELINK_STATUS_OK;
3072                 }
3073                 if (CHIP_IS_E2(sc))
3074                         elink_update_pfc_bmac2(params, vars, bmac_loopback);
3075                 else
3076                         elink_update_pfc_bmac1(params, vars);
3077
3078                 val = 0;
3079                 if ((params->feature_config_flags &
3080                      ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
3081                     (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
3082                         val = 1;
3083                 REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port * 4, val);
3084         }
3085         return ELINK_STATUS_OK;
3086 }
3087
3088 static elink_status_t elink_bmac1_enable(struct elink_params *params,
3089                               struct elink_vars *vars,
3090                               uint8_t is_lb)
3091 {
3092         struct bnx2x_softc *sc = params->sc;
3093         uint8_t port = params->port;
3094         uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
3095                                NIG_REG_INGRESS_BMAC0_MEM;
3096         uint32_t wb_data[2];
3097         uint32_t val;
3098
3099         ELINK_DEBUG_P0(sc, "Enabling BigMAC1");
3100
3101         /* XGXS control */
3102         wb_data[0] = 0x3c;
3103         wb_data[1] = 0;
3104         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
3105                     wb_data, 2);
3106
3107         /* TX MAC SA */
3108         wb_data[0] = ((params->mac_addr[2] << 24) |
3109                        (params->mac_addr[3] << 16) |
3110                        (params->mac_addr[4] << 8) |
3111                         params->mac_addr[5]);
3112         wb_data[1] = ((params->mac_addr[0] << 8) |
3113                         params->mac_addr[1]);
3114         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
3115
3116         /* MAC control */
3117         val = 0x3;
3118         if (is_lb) {
3119                 val |= 0x4;
3120                 ELINK_DEBUG_P0(sc,  "enable bmac loopback");
3121         }
3122         wb_data[0] = val;
3123         wb_data[1] = 0;
3124         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
3125
3126         /* Set rx mtu */
3127         wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3128         wb_data[1] = 0;
3129         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
3130
3131         elink_update_pfc_bmac1(params, vars);
3132
3133         /* Set tx mtu */
3134         wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3135         wb_data[1] = 0;
3136         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
3137
3138         /* Set cnt max size */
3139         wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3140         wb_data[1] = 0;
3141         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
3142
3143         /* Configure SAFC */
3144         wb_data[0] = 0x1000200;
3145         wb_data[1] = 0;
3146         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
3147                     wb_data, 2);
3148 #ifdef ELINK_INCLUDE_EMUL
3149         /* Fix for emulation */
3150         if (CHIP_REV_IS_EMUL(sc)) {
3151                 wb_data[0] = 0xf000;
3152                 wb_data[1] = 0;
3153                 REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
3154                             wb_data, 2);
3155         }
3156 #endif
3157
3158         return ELINK_STATUS_OK;
3159 }
3160
3161 static elink_status_t elink_bmac2_enable(struct elink_params *params,
3162                               struct elink_vars *vars,
3163                               uint8_t is_lb)
3164 {
3165         struct bnx2x_softc *sc = params->sc;
3166         uint8_t port = params->port;
3167         uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
3168                                NIG_REG_INGRESS_BMAC0_MEM;
3169         uint32_t wb_data[2];
3170
3171         ELINK_DEBUG_P0(sc, "Enabling BigMAC2");
3172
3173         wb_data[0] = 0;
3174         wb_data[1] = 0;
3175         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
3176         DELAY(30);
3177
3178         /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
3179         wb_data[0] = 0x3c;
3180         wb_data[1] = 0;
3181         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
3182                     wb_data, 2);
3183
3184         DELAY(30);
3185
3186         /* TX MAC SA */
3187         wb_data[0] = ((params->mac_addr[2] << 24) |
3188                        (params->mac_addr[3] << 16) |
3189                        (params->mac_addr[4] << 8) |
3190                         params->mac_addr[5]);
3191         wb_data[1] = ((params->mac_addr[0] << 8) |
3192                         params->mac_addr[1]);
3193         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
3194                     wb_data, 2);
3195
3196         DELAY(30);
3197
3198         /* Configure SAFC */
3199         wb_data[0] = 0x1000200;
3200         wb_data[1] = 0;
3201         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
3202                     wb_data, 2);
3203         DELAY(30);
3204
3205         /* Set RX MTU */
3206         wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3207         wb_data[1] = 0;
3208         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
3209         DELAY(30);
3210
3211         /* Set TX MTU */
3212         wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3213         wb_data[1] = 0;
3214         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
3215         DELAY(30);
3216         /* Set cnt max size */
3217         wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD - 2;
3218         wb_data[1] = 0;
3219         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
3220         DELAY(30);
3221         elink_update_pfc_bmac2(params, vars, is_lb);
3222
3223         return ELINK_STATUS_OK;
3224 }
3225
3226 static elink_status_t elink_bmac_enable(struct elink_params *params,
3227                              struct elink_vars *vars,
3228                              uint8_t is_lb, uint8_t reset_bmac)
3229 {
3230         elink_status_t rc = ELINK_STATUS_OK;
3231         uint8_t port = params->port;
3232         struct bnx2x_softc *sc = params->sc;
3233         uint32_t val;
3234         /* Reset and unreset the BigMac */
3235         if (reset_bmac) {
3236                 REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
3237                        (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
3238                 DELAY(1000 * 1);
3239         }
3240
3241         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
3242                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
3243
3244         /* Enable access for bmac registers */
3245         REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port * 4, 0x1);
3246
3247         /* Enable BMAC according to BMAC type*/
3248         if (CHIP_IS_E2(sc))
3249                 rc = elink_bmac2_enable(params, vars, is_lb);
3250         else
3251                 rc = elink_bmac1_enable(params, vars, is_lb);
3252         REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 0x1);
3253         REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, 0x0);
3254         REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + port * 4, 0x0);
3255         val = 0;
3256         if ((params->feature_config_flags &
3257               ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
3258             (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
3259                 val = 1;
3260         REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + port * 4, val);
3261         REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port * 4, 0x0);
3262         REG_WR(sc, NIG_REG_EMAC0_IN_EN + port * 4, 0x0);
3263         REG_WR(sc, NIG_REG_EMAC0_PAUSE_OUT_EN + port * 4, 0x0);
3264         REG_WR(sc, NIG_REG_BMAC0_IN_EN + port * 4, 0x1);
3265         REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port * 4, 0x1);
3266
3267         vars->mac_type = ELINK_MAC_TYPE_BMAC;
3268         return rc;
3269 }
3270
3271 static void elink_set_bmac_rx(struct bnx2x_softc *sc,
3272                               __rte_unused uint32_t chip_id,
3273                               uint8_t port, uint8_t en)
3274 {
3275         uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
3276                         NIG_REG_INGRESS_BMAC0_MEM;
3277         uint32_t wb_data[2];
3278         uint32_t nig_bmac_enable = REG_RD(sc, NIG_REG_BMAC0_REGS_OUT_EN +
3279                                           port * 4);
3280
3281         if (CHIP_IS_E2(sc))
3282                 bmac_addr += BIGMAC2_REGISTER_BMAC_CONTROL;
3283         else
3284                 bmac_addr += BIGMAC_REGISTER_BMAC_CONTROL;
3285         /* Only if the bmac is out of reset */
3286         if (REG_RD(sc, MISC_REG_RESET_REG_2) &
3287                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
3288             nig_bmac_enable) {
3289                 /* Clear Rx Enable bit in BMAC_CONTROL register */
3290                 REG_RD_DMAE(sc, bmac_addr, wb_data, 2);
3291                 if (en)
3292                         wb_data[0] |= ELINK_BMAC_CONTROL_RX_ENABLE;
3293                 else
3294                         wb_data[0] &= ~ELINK_BMAC_CONTROL_RX_ENABLE;
3295                 REG_WR_DMAE(sc, bmac_addr, wb_data, 2);
3296                 DELAY(1000 * 1);
3297         }
3298 }
3299
3300 static elink_status_t elink_pbf_update(struct elink_params *params,
3301                             uint32_t flow_ctrl,
3302                             uint32_t line_speed)
3303 {
3304         struct bnx2x_softc *sc = params->sc;
3305         uint8_t port = params->port;
3306         uint32_t init_crd, crd;
3307         uint32_t count = 1000;
3308
3309         /* Disable port */
3310         REG_WR(sc, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port * 4, 0x1);
3311
3312         /* Wait for init credit */
3313         init_crd = REG_RD(sc, PBF_REG_P0_INIT_CRD + port * 4);
3314         crd = REG_RD(sc, PBF_REG_P0_CREDIT + port * 8);
3315         ELINK_DEBUG_P2(sc, "init_crd 0x%x  crd 0x%x", init_crd, crd);
3316
3317         while ((init_crd != crd) && count) {
3318                 DELAY(1000 * 5);
3319                 crd = REG_RD(sc, PBF_REG_P0_CREDIT + port * 8);
3320                 count--;
3321         }
3322         crd = REG_RD(sc, PBF_REG_P0_CREDIT + port * 8);
3323         if (init_crd != crd) {
3324                 ELINK_DEBUG_P2(sc, "BUG! init_crd 0x%x != crd 0x%x",
3325                           init_crd, crd);
3326                 return ELINK_STATUS_ERROR;
3327         }
3328
3329         if (flow_ctrl & ELINK_FLOW_CTRL_RX ||
3330             line_speed == ELINK_SPEED_10 ||
3331             line_speed == ELINK_SPEED_100 ||
3332             line_speed == ELINK_SPEED_1000 ||
3333             line_speed == ELINK_SPEED_2500) {
3334                 REG_WR(sc, PBF_REG_P0_PAUSE_ENABLE + port * 4, 1);
3335                 /* Update threshold */
3336                 REG_WR(sc, PBF_REG_P0_ARB_THRSH + port * 4, 0);
3337                 /* Update init credit */
3338                 init_crd = 778;         /* (800-18-4) */
3339
3340         } else {
3341                 uint32_t thresh = (ELINK_ETH_MAX_JUMBO_PACKET_SIZE +
3342                               ELINK_ETH_OVREHEAD) / 16;
3343                 REG_WR(sc, PBF_REG_P0_PAUSE_ENABLE + port * 4, 0);
3344                 /* Update threshold */
3345                 REG_WR(sc, PBF_REG_P0_ARB_THRSH + port * 4, thresh);
3346                 /* Update init credit */
3347                 switch (line_speed) {
3348                 case ELINK_SPEED_10000:
3349                         init_crd = thresh + 553 - 22;
3350                         break;
3351                 default:
3352                         ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x",
3353                                   line_speed);
3354                         return ELINK_STATUS_ERROR;
3355                 }
3356         }
3357         REG_WR(sc, PBF_REG_P0_INIT_CRD + port * 4, init_crd);
3358         ELINK_DEBUG_P2(sc, "PBF updated to speed %d credit %d",
3359                  line_speed, init_crd);
3360
3361         /* Probe the credit changes */
3362         REG_WR(sc, PBF_REG_INIT_P0 + port * 4, 0x1);
3363         DELAY(1000 * 5);
3364         REG_WR(sc, PBF_REG_INIT_P0 + port * 4, 0x0);
3365
3366         /* Enable port */
3367         REG_WR(sc, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port * 4, 0x0);
3368         return ELINK_STATUS_OK;
3369 }
3370
3371 /**
3372  * elink_get_emac_base - retrive emac base address
3373  *
3374  * @bp:                 driver handle
3375  * @mdc_mdio_access:    access type
3376  * @port:               port id
3377  *
3378  * This function selects the MDC/MDIO access (through emac0 or
3379  * emac1) depend on the mdc_mdio_access, port, port swapped. Each
3380  * phy has a default access mode, which could also be overridden
3381  * by nvram configuration. This parameter, whether this is the
3382  * default phy configuration, or the nvram overrun
3383  * configuration, is passed here as mdc_mdio_access and selects
3384  * the emac_base for the CL45 read/writes operations
3385  */
3386 static uint32_t elink_get_emac_base(struct bnx2x_softc *sc,
3387                                uint32_t mdc_mdio_access, uint8_t port)
3388 {
3389         uint32_t emac_base = 0;
3390         switch (mdc_mdio_access) {
3391         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
3392                 break;
3393         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
3394                 if (REG_RD(sc, NIG_REG_PORT_SWAP))
3395                         emac_base = GRCBASE_EMAC1;
3396                 else
3397                         emac_base = GRCBASE_EMAC0;
3398                 break;
3399         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
3400                 if (REG_RD(sc, NIG_REG_PORT_SWAP))
3401                         emac_base = GRCBASE_EMAC0;
3402                 else
3403                         emac_base = GRCBASE_EMAC1;
3404                 break;
3405         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
3406                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3407                 break;
3408         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
3409                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
3410                 break;
3411         default:
3412                 break;
3413         }
3414         return emac_base;
3415
3416 }
3417
3418 /******************************************************************/
3419 /*                      CL22 access functions                     */
3420 /******************************************************************/
3421 static elink_status_t elink_cl22_write(struct bnx2x_softc *sc,
3422                                        struct elink_phy *phy,
3423                                        uint16_t reg, uint16_t val)
3424 {
3425         uint32_t tmp, mode;
3426         uint8_t i;
3427         elink_status_t rc = ELINK_STATUS_OK;
3428         /* Switch to CL22 */
3429         mode = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
3430         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
3431                mode & ~EMAC_MDIO_MODE_CLAUSE_45);
3432
3433         /* Address */
3434         tmp = ((phy->addr << 21) | (reg << 16) | val |
3435                EMAC_MDIO_COMM_COMMAND_WRITE_22 |
3436                EMAC_MDIO_COMM_START_BUSY);
3437         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3438
3439         for (i = 0; i < 50; i++) {
3440                 DELAY(10);
3441
3442                 tmp = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3443                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3444                         DELAY(5);
3445                         break;
3446                 }
3447         }
3448         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3449                 ELINK_DEBUG_P0(sc, "write phy register failed");
3450                 rc = ELINK_STATUS_TIMEOUT;
3451         }
3452         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
3453         return rc;
3454 }
3455
3456 static elink_status_t elink_cl22_read(struct bnx2x_softc *sc,
3457                                       struct elink_phy *phy,
3458                                       uint16_t reg, uint16_t *ret_val)
3459 {
3460         uint32_t val, mode;
3461         uint16_t i;
3462         elink_status_t rc = ELINK_STATUS_OK;
3463
3464         /* Switch to CL22 */
3465         mode = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
3466         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
3467                mode & ~EMAC_MDIO_MODE_CLAUSE_45);
3468
3469         /* Address */
3470         val = ((phy->addr << 21) | (reg << 16) |
3471                EMAC_MDIO_COMM_COMMAND_READ_22 |
3472                EMAC_MDIO_COMM_START_BUSY);
3473         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3474
3475         for (i = 0; i < 50; i++) {
3476                 DELAY(10);
3477
3478                 val = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3479                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3480                         *ret_val = (uint16_t)(val & EMAC_MDIO_COMM_DATA);
3481                         DELAY(5);
3482                         break;
3483                 }
3484         }
3485         if (val & EMAC_MDIO_COMM_START_BUSY) {
3486                 ELINK_DEBUG_P0(sc, "read phy register failed");
3487
3488                 *ret_val = 0;
3489                 rc = ELINK_STATUS_TIMEOUT;
3490         }
3491         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
3492         return rc;
3493 }
3494
3495 /******************************************************************/
3496 /*                      CL45 access functions                     */
3497 /******************************************************************/
3498 static elink_status_t elink_cl45_read(struct bnx2x_softc *sc,
3499                            struct elink_phy *phy,
3500                            uint8_t devad, uint16_t reg, uint16_t *ret_val)
3501 {
3502         uint32_t val;
3503         uint16_t i;
3504         elink_status_t rc = ELINK_STATUS_OK;
3505         uint32_t chip_id;
3506         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_G) {
3507                 chip_id = (REG_RD(sc, MISC_REG_CHIP_NUM) << 16) |
3508                           ((REG_RD(sc, MISC_REG_CHIP_REV) & 0xf) << 12);
3509                 elink_set_mdio_clk(sc, chip_id, phy->mdio_ctrl);
3510         }
3511
3512         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3513                 elink_bits_en(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3514                               EMAC_MDIO_STATUS_10MB);
3515         /* Address */
3516         val = ((phy->addr << 21) | (devad << 16) | reg |
3517                EMAC_MDIO_COMM_COMMAND_ADDRESS |
3518                EMAC_MDIO_COMM_START_BUSY);
3519         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3520
3521         for (i = 0; i < 50; i++) {
3522                 DELAY(10);
3523
3524                 val = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3525                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3526                         DELAY(5);
3527                         break;
3528                 }
3529         }
3530         if (val & EMAC_MDIO_COMM_START_BUSY) {
3531                 ELINK_DEBUG_P0(sc, "read phy register failed");
3532                 elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT);
3533                 /* "MDC/MDIO access timeout" */
3534
3535                 *ret_val = 0;
3536                 rc = ELINK_STATUS_TIMEOUT;
3537         } else {
3538                 /* Data */
3539                 val = ((phy->addr << 21) | (devad << 16) |
3540                        EMAC_MDIO_COMM_COMMAND_READ_45 |
3541                        EMAC_MDIO_COMM_START_BUSY);
3542                 REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3543
3544                 for (i = 0; i < 50; i++) {
3545                         DELAY(10);
3546
3547                         val = REG_RD(sc, phy->mdio_ctrl +
3548                                      EMAC_REG_EMAC_MDIO_COMM);
3549                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3550                                 *ret_val = (uint16_t)
3551                                                 (val & EMAC_MDIO_COMM_DATA);
3552                                 break;
3553                         }
3554                 }
3555                 if (val & EMAC_MDIO_COMM_START_BUSY) {
3556                         ELINK_DEBUG_P0(sc, "read phy register failed");
3557                         elink_cb_event_log(sc,
3558                                            ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT);
3559                         /* "MDC/MDIO access timeout" */
3560
3561                         *ret_val = 0;
3562                         rc = ELINK_STATUS_TIMEOUT;
3563                 }
3564         }
3565         /* Work around for E3 A0 */
3566         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA) {
3567                 phy->flags ^= ELINK_FLAGS_DUMMY_READ;
3568                 if (phy->flags & ELINK_FLAGS_DUMMY_READ) {
3569                         uint16_t temp_val;
3570                         elink_cl45_read(sc, phy, devad, 0xf, &temp_val);
3571                 }
3572         }
3573
3574         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3575                 elink_bits_dis(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3576                                EMAC_MDIO_STATUS_10MB);
3577         return rc;
3578 }
3579
3580 static elink_status_t elink_cl45_write(struct bnx2x_softc *sc,
3581                             struct elink_phy *phy,
3582                             uint8_t devad, uint16_t reg, uint16_t val)
3583 {
3584         uint32_t tmp;
3585         uint8_t i;
3586         elink_status_t rc = ELINK_STATUS_OK;
3587         uint32_t chip_id;
3588         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_G) {
3589                 chip_id = (REG_RD(sc, MISC_REG_CHIP_NUM) << 16) |
3590                           ((REG_RD(sc, MISC_REG_CHIP_REV) & 0xf) << 12);
3591                 elink_set_mdio_clk(sc, chip_id, phy->mdio_ctrl);
3592         }
3593
3594         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3595                 elink_bits_en(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3596                               EMAC_MDIO_STATUS_10MB);
3597
3598         /* Address */
3599         tmp = ((phy->addr << 21) | (devad << 16) | reg |
3600                EMAC_MDIO_COMM_COMMAND_ADDRESS |
3601                EMAC_MDIO_COMM_START_BUSY);
3602         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3603
3604         for (i = 0; i < 50; i++) {
3605                 DELAY(10);
3606
3607                 tmp = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3608                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3609                         DELAY(5);
3610                         break;
3611                 }
3612         }
3613         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3614                 ELINK_DEBUG_P0(sc, "write phy register failed");
3615                 elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT);
3616                 /* "MDC/MDIO access timeout" */
3617
3618                 rc = ELINK_STATUS_TIMEOUT;
3619         } else {
3620                 /* Data */
3621                 tmp = ((phy->addr << 21) | (devad << 16) | val |
3622                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
3623                        EMAC_MDIO_COMM_START_BUSY);
3624                 REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3625
3626                 for (i = 0; i < 50; i++) {
3627                         DELAY(10);
3628
3629                         tmp = REG_RD(sc, phy->mdio_ctrl +
3630                                      EMAC_REG_EMAC_MDIO_COMM);
3631                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3632                                 DELAY(5);
3633                                 break;
3634                         }
3635                 }
3636                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3637                         ELINK_DEBUG_P0(sc, "write phy register failed");
3638                         elink_cb_event_log(sc,
3639                                            ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT);
3640                         /* "MDC/MDIO access timeout" */
3641
3642                         rc = ELINK_STATUS_TIMEOUT;
3643                 }
3644         }
3645         /* Work around for E3 A0 */
3646         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA) {
3647                 phy->flags ^= ELINK_FLAGS_DUMMY_READ;
3648                 if (phy->flags & ELINK_FLAGS_DUMMY_READ) {
3649                         uint16_t temp_val;
3650                         elink_cl45_read(sc, phy, devad, 0xf, &temp_val);
3651                 }
3652         }
3653         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3654                 elink_bits_dis(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3655                                EMAC_MDIO_STATUS_10MB);
3656         return rc;
3657 }
3658
3659 /******************************************************************/
3660 /*                      EEE section                                */
3661 /******************************************************************/
3662 static uint8_t elink_eee_has_cap(struct elink_params *params)
3663 {
3664         struct bnx2x_softc *sc = params->sc;
3665
3666         if (REG_RD(sc, params->shmem2_base) <=
3667                    offsetof(struct shmem2_region, eee_status[params->port]))
3668                 return 0;
3669
3670         return 1;
3671 }
3672
3673 static elink_status_t elink_eee_nvram_to_time(uint32_t nvram_mode,
3674                                               uint32_t *idle_timer)
3675 {
3676         switch (nvram_mode) {
3677         case PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED:
3678                 *idle_timer = ELINK_EEE_MODE_NVRAM_BALANCED_TIME;
3679                 break;
3680         case PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE:
3681                 *idle_timer = ELINK_EEE_MODE_NVRAM_AGGRESSIVE_TIME;
3682                 break;
3683         case PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY:
3684                 *idle_timer = ELINK_EEE_MODE_NVRAM_LATENCY_TIME;
3685                 break;
3686         default:
3687                 *idle_timer = 0;
3688                 break;
3689         }
3690
3691         return ELINK_STATUS_OK;
3692 }
3693
3694 static elink_status_t elink_eee_time_to_nvram(uint32_t idle_timer,
3695                                               uint32_t *nvram_mode)
3696 {
3697         switch (idle_timer) {
3698         case ELINK_EEE_MODE_NVRAM_BALANCED_TIME:
3699                 *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED;
3700                 break;
3701         case ELINK_EEE_MODE_NVRAM_AGGRESSIVE_TIME:
3702                 *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE;
3703                 break;
3704         case ELINK_EEE_MODE_NVRAM_LATENCY_TIME:
3705                 *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY;
3706                 break;
3707         default:
3708                 *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED;
3709                 break;
3710         }
3711
3712         return ELINK_STATUS_OK;
3713 }
3714
3715 static uint32_t elink_eee_calc_timer(struct elink_params *params)
3716 {
3717         uint32_t eee_mode, eee_idle;
3718         struct bnx2x_softc *sc = params->sc;
3719
3720         if (params->eee_mode & ELINK_EEE_MODE_OVERRIDE_NVRAM) {
3721                 if (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME) {
3722                         /* time value in eee_mode --> used directly*/
3723                         eee_idle = params->eee_mode & ELINK_EEE_MODE_TIMER_MASK;
3724                 } else {
3725                         /* hsi value in eee_mode --> time */
3726                         if (elink_eee_nvram_to_time(params->eee_mode &
3727                                                     ELINK_EEE_MODE_NVRAM_MASK,
3728                                                     &eee_idle))
3729                                 return 0;
3730                 }
3731         } else {
3732                 /* hsi values in nvram --> time*/
3733                 eee_mode = ((REG_RD(sc, params->shmem_base +
3734                                     offsetof(struct shmem_region, dev_info.
3735                                     port_feature_config[params->port].
3736                                     eee_power_mode)) &
3737                              PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >>
3738                             PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT);
3739
3740                 if (elink_eee_nvram_to_time(eee_mode, &eee_idle))
3741                         return 0;
3742         }
3743
3744         return eee_idle;
3745 }
3746
3747 static elink_status_t elink_eee_set_timers(struct elink_params *params,
3748                                    struct elink_vars *vars)
3749 {
3750         uint32_t eee_idle = 0, eee_mode;
3751         struct bnx2x_softc *sc = params->sc;
3752
3753         eee_idle = elink_eee_calc_timer(params);
3754
3755         if (eee_idle) {
3756                 REG_WR(sc, MISC_REG_CPMU_LP_IDLE_THR_P0 + (params->port << 2),
3757                        eee_idle);
3758         } else if ((params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI) &&
3759                    (params->eee_mode & ELINK_EEE_MODE_OVERRIDE_NVRAM) &&
3760                    (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME)) {
3761                 ELINK_DEBUG_P0(sc, "Error: Tx LPI is enabled with timer 0");
3762                 return ELINK_STATUS_ERROR;
3763         }
3764
3765         vars->eee_status &= ~(SHMEM_EEE_TIMER_MASK | SHMEM_EEE_TIME_OUTPUT_BIT);
3766         if (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME) {
3767                 /* eee_idle in 1u --> eee_status in 16u */
3768                 eee_idle >>= 4;
3769                 vars->eee_status |= (eee_idle & SHMEM_EEE_TIMER_MASK) |
3770                                     SHMEM_EEE_TIME_OUTPUT_BIT;
3771         } else {
3772                 if (elink_eee_time_to_nvram(eee_idle, &eee_mode))
3773                         return ELINK_STATUS_ERROR;
3774                 vars->eee_status |= eee_mode;
3775         }
3776
3777         return ELINK_STATUS_OK;
3778 }
3779
3780 static elink_status_t elink_eee_initial_config(struct elink_params *params,
3781                                      struct elink_vars *vars, uint8_t mode)
3782 {
3783         vars->eee_status |= ((uint32_t) mode) << SHMEM_EEE_SUPPORTED_SHIFT;
3784
3785         /* Propagate params' bits --> vars (for migration exposure) */
3786         if (params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)
3787                 vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT;
3788         else
3789                 vars->eee_status &= ~SHMEM_EEE_LPI_REQUESTED_BIT;
3790
3791         if (params->eee_mode & ELINK_EEE_MODE_ADV_LPI)
3792                 vars->eee_status |= SHMEM_EEE_REQUESTED_BIT;
3793         else
3794                 vars->eee_status &= ~SHMEM_EEE_REQUESTED_BIT;
3795
3796         return elink_eee_set_timers(params, vars);
3797 }
3798
3799 static elink_status_t elink_eee_disable(struct elink_phy *phy,
3800                                 struct elink_params *params,
3801                                 struct elink_vars *vars)
3802 {
3803         struct bnx2x_softc *sc = params->sc;
3804
3805         /* Make Certain LPI is disabled */
3806         REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), 0);
3807
3808         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0x0);
3809
3810         vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
3811
3812         return ELINK_STATUS_OK;
3813 }
3814
3815 static elink_status_t elink_eee_advertise(struct elink_phy *phy,
3816                                   struct elink_params *params,
3817                                   struct elink_vars *vars, uint8_t modes)
3818 {
3819         struct bnx2x_softc *sc = params->sc;
3820         uint16_t val = 0;
3821
3822         /* Mask events preventing LPI generation */
3823         REG_WR(sc, MISC_REG_CPMU_LP_MASK_EXT_P0 + (params->port << 2), 0xfc20);
3824
3825         if (modes & SHMEM_EEE_10G_ADV) {
3826                 ELINK_DEBUG_P0(sc, "Advertise 10GBase-T EEE");
3827                 val |= 0x8;
3828         }
3829         if (modes & SHMEM_EEE_1G_ADV) {
3830                 ELINK_DEBUG_P0(sc, "Advertise 1GBase-T EEE");
3831                 val |= 0x4;
3832         }
3833
3834         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, val);
3835
3836         vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
3837         vars->eee_status |= (modes << SHMEM_EEE_ADV_STATUS_SHIFT);
3838
3839         return ELINK_STATUS_OK;
3840 }
3841
3842 static void elink_update_mng_eee(struct elink_params *params,
3843                                  uint32_t eee_status)
3844 {
3845         struct bnx2x_softc *sc = params->sc;
3846
3847         if (elink_eee_has_cap(params))
3848                 REG_WR(sc, params->shmem2_base +
3849                        offsetof(struct shmem2_region,
3850                                 eee_status[params->port]), eee_status);
3851 }
3852
3853 static void elink_eee_an_resolve(struct elink_phy *phy,
3854                                   struct elink_params *params,
3855                                   struct elink_vars *vars)
3856 {
3857         struct bnx2x_softc *sc = params->sc;
3858         uint16_t adv = 0, lp = 0;
3859         uint32_t lp_adv = 0;
3860         uint8_t neg = 0;
3861
3862         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, &adv);
3863         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LP_EEE_ADV, &lp);
3864
3865         if (lp & 0x2) {
3866                 lp_adv |= SHMEM_EEE_100M_ADV;
3867                 if (adv & 0x2) {
3868                         if (vars->line_speed == ELINK_SPEED_100)
3869                                 neg = 1;
3870                         ELINK_DEBUG_P0(sc, "EEE negotiated - 100M");
3871                 }
3872         }
3873         if (lp & 0x14) {
3874                 lp_adv |= SHMEM_EEE_1G_ADV;
3875                 if (adv & 0x14) {
3876                         if (vars->line_speed == ELINK_SPEED_1000)
3877                                 neg = 1;
3878                         ELINK_DEBUG_P0(sc, "EEE negotiated - 1G");
3879                 }
3880         }
3881         if (lp & 0x68) {
3882                 lp_adv |= SHMEM_EEE_10G_ADV;
3883                 if (adv & 0x68) {
3884                         if (vars->line_speed == ELINK_SPEED_10000)
3885                                 neg = 1;
3886                         ELINK_DEBUG_P0(sc, "EEE negotiated - 10G");
3887                 }
3888         }
3889
3890         vars->eee_status &= ~SHMEM_EEE_LP_ADV_STATUS_MASK;
3891         vars->eee_status |= (lp_adv << SHMEM_EEE_LP_ADV_STATUS_SHIFT);
3892
3893         if (neg) {
3894                 ELINK_DEBUG_P0(sc, "EEE is active");
3895                 vars->eee_status |= SHMEM_EEE_ACTIVE_BIT;
3896         }
3897 }
3898
3899 /******************************************************************/
3900 /*                      BSC access functions from E3              */
3901 /******************************************************************/
3902 static void elink_bsc_module_sel(struct elink_params *params)
3903 {
3904         int idx;
3905         uint32_t board_cfg, sfp_ctrl;
3906         uint32_t i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
3907         struct bnx2x_softc *sc = params->sc;
3908         uint8_t port = params->port;
3909         /* Read I2C output PINs */
3910         board_cfg = REG_RD(sc, params->shmem_base +
3911                            offsetof(struct shmem_region,
3912                                     dev_info.shared_hw_config.board));
3913         i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
3914         i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
3915                         SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
3916
3917         /* Read I2C output value */
3918         sfp_ctrl = REG_RD(sc, params->shmem_base +
3919                           offsetof(struct shmem_region,
3920                                  dev_info.port_hw_config[port].e3_cmn_pin_cfg));
3921         i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
3922         i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
3923         ELINK_DEBUG_P0(sc, "Setting BSC switch");
3924         for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
3925                 elink_set_cfg_pin(sc, i2c_pins[idx], i2c_val[idx]);
3926 }
3927
3928 static elink_status_t elink_bsc_read(struct bnx2x_softc *sc,
3929                           uint8_t sl_devid,
3930                           uint16_t sl_addr,
3931                           uint8_t lc_addr,
3932                           uint8_t xfer_cnt,
3933                           uint32_t *data_array)
3934 {
3935         uint32_t val, i;
3936         elink_status_t rc = ELINK_STATUS_OK;
3937
3938         if (xfer_cnt > 16) {
3939                 ELINK_DEBUG_P1(sc, "invalid xfer_cnt %d. Max is 16 bytes",
3940                                         xfer_cnt);
3941                 return ELINK_STATUS_ERROR;
3942         }
3943
3944         xfer_cnt = 16 - lc_addr;
3945
3946         /* Enable the engine */
3947         val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3948         val |= MCPR_IMC_COMMAND_ENABLE;
3949         REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
3950
3951         /* Program slave device ID */
3952         val = (sl_devid << 16) | sl_addr;
3953         REG_WR(sc, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
3954
3955         /* Start xfer with 0 byte to update the address pointer ???*/
3956         val = (MCPR_IMC_COMMAND_ENABLE) |
3957               (MCPR_IMC_COMMAND_WRITE_OP <<
3958                 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3959                 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
3960         REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
3961
3962         /* Poll for completion */
3963         i = 0;
3964         val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3965         while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3966                 DELAY(10);
3967                 val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3968                 if (i++ > 1000) {
3969                         ELINK_DEBUG_P1(sc, "wr 0 byte timed out after %d try",
3970                                                                 i);
3971                         rc = ELINK_STATUS_TIMEOUT;
3972                         break;
3973                 }
3974         }
3975         if (rc == ELINK_STATUS_TIMEOUT)
3976                 return rc;
3977
3978         /* Start xfer with read op */
3979         val = (MCPR_IMC_COMMAND_ENABLE) |
3980                 (MCPR_IMC_COMMAND_READ_OP <<
3981                 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3982                 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
3983                   (xfer_cnt);
3984         REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
3985
3986         /* Poll for completion */
3987         i = 0;
3988         val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3989         while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3990                 DELAY(10);
3991                 val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3992                 if (i++ > 1000) {
3993                         ELINK_DEBUG_P1(sc, "rd op timed out after %d try", i);
3994                         rc = ELINK_STATUS_TIMEOUT;
3995                         break;
3996                 }
3997         }
3998         if (rc == ELINK_STATUS_TIMEOUT)
3999                 return rc;
4000
4001         for (i = (lc_addr >> 2); i < 4; i++) {
4002                 data_array[i] = REG_RD(sc, (MCP_REG_MCPR_IMC_DATAREG0 + i * 4));
4003 #ifdef __BIG_ENDIAN
4004                 data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
4005                                 ((data_array[i] & 0x0000ff00) << 8) |
4006                                 ((data_array[i] & 0x00ff0000) >> 8) |
4007                                 ((data_array[i] & 0xff000000) >> 24);
4008 #endif
4009         }
4010         return rc;
4011 }
4012
4013 static void elink_cl45_read_or_write(struct bnx2x_softc *sc,
4014                                      struct elink_phy *phy,
4015                                      uint8_t devad, uint16_t reg,
4016                                      uint16_t or_val)
4017 {
4018         uint16_t val;
4019         elink_cl45_read(sc, phy, devad, reg, &val);
4020         elink_cl45_write(sc, phy, devad, reg, val | or_val);
4021 }
4022
4023 static void elink_cl45_read_and_write(struct bnx2x_softc *sc,
4024                                       struct elink_phy *phy,
4025                                       uint8_t devad, uint16_t reg,
4026                                       uint16_t and_val)
4027 {
4028         uint16_t val;
4029         elink_cl45_read(sc, phy, devad, reg, &val);
4030         elink_cl45_write(sc, phy, devad, reg, val & and_val);
4031 }
4032
4033 elink_status_t elink_phy_read(struct elink_params *params, uint8_t phy_addr,
4034                    uint8_t devad, uint16_t reg, uint16_t *ret_val)
4035 {
4036         uint8_t phy_index;
4037         /* Probe for the phy according to the given phy_addr, and execute
4038          * the read request on it
4039          */
4040         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
4041                 if (params->phy[phy_index].addr == phy_addr) {
4042                         return elink_cl45_read(params->sc,
4043                                                &params->phy[phy_index], devad,
4044                                                reg, ret_val);
4045                 }
4046         }
4047         return ELINK_STATUS_ERROR;
4048 }
4049
4050 elink_status_t elink_phy_write(struct elink_params *params, uint8_t phy_addr,
4051                     uint8_t devad, uint16_t reg, uint16_t val)
4052 {
4053         uint8_t phy_index;
4054         /* Probe for the phy according to the given phy_addr, and execute
4055          * the write request on it
4056          */
4057         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
4058                 if (params->phy[phy_index].addr == phy_addr) {
4059                         return elink_cl45_write(params->sc,
4060                                                 &params->phy[phy_index], devad,
4061                                                 reg, val);
4062                 }
4063         }
4064         return ELINK_STATUS_ERROR;
4065 }
4066
4067 static uint8_t elink_get_warpcore_lane(__rte_unused struct elink_phy *phy,
4068                                   struct elink_params *params)
4069 {
4070         uint8_t lane = 0;
4071         struct bnx2x_softc *sc = params->sc;
4072         uint32_t path_swap, path_swap_ovr;
4073         uint8_t path, port;
4074
4075         path = SC_PATH(sc);
4076         port = params->port;
4077
4078         if (elink_is_4_port_mode(sc)) {
4079                 uint32_t port_swap, port_swap_ovr;
4080
4081                 /* Figure out path swap value */
4082                 path_swap_ovr = REG_RD(sc, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
4083                 if (path_swap_ovr & 0x1)
4084                         path_swap = (path_swap_ovr & 0x2);
4085                 else
4086                         path_swap = REG_RD(sc, MISC_REG_FOUR_PORT_PATH_SWAP);
4087
4088                 if (path_swap)
4089                         path = path ^ 1;
4090
4091                 /* Figure out port swap value */
4092                 port_swap_ovr = REG_RD(sc, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
4093                 if (port_swap_ovr & 0x1)
4094                         port_swap = (port_swap_ovr & 0x2);
4095                 else
4096                         port_swap = REG_RD(sc, MISC_REG_FOUR_PORT_PORT_SWAP);
4097
4098                 if (port_swap)
4099                         port = port ^ 1;
4100
4101                 lane = (port << 1) + path;
4102         } else { /* Two port mode - no port swap */
4103
4104                 /* Figure out path swap value */
4105                 path_swap_ovr =
4106                         REG_RD(sc, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
4107                 if (path_swap_ovr & 0x1) {
4108                         path_swap = (path_swap_ovr & 0x2);
4109                 } else {
4110                         path_swap =
4111                                 REG_RD(sc, MISC_REG_TWO_PORT_PATH_SWAP);
4112                 }
4113                 if (path_swap)
4114                         path = path ^ 1;
4115
4116                 lane = path << 1;
4117         }
4118         return lane;
4119 }
4120
4121
4122 static void elink_set_aer_mmd(struct elink_params *params,
4123                               struct elink_phy *phy)
4124 {
4125         uint32_t ser_lane;
4126         uint16_t offset, aer_val;
4127         struct bnx2x_softc *sc = params->sc;
4128         ser_lane = ((params->lane_config &
4129                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4130                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4131
4132         offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
4133                 (phy->addr + ser_lane) : 0;
4134
4135         if (USES_WARPCORE(sc)) {
4136                 aer_val = elink_get_warpcore_lane(phy, params);
4137                 /* In Dual-lane mode, two lanes are joined together,
4138                  * so in order to configure them, the AER broadcast method is
4139                  * used here.
4140                  * 0x200 is the broadcast address for lanes 0,1
4141                  * 0x201 is the broadcast address for lanes 2,3
4142                  */
4143                 if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
4144                         aer_val = (aer_val >> 1) | 0x200;
4145         } else if (CHIP_IS_E2(sc))
4146                 aer_val = 0x3800 + offset - 1;
4147         else
4148                 aer_val = 0x3800 + offset;
4149
4150         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4151                           MDIO_AER_BLOCK_AER_REG, aer_val);
4152
4153 }
4154
4155 /******************************************************************/
4156 /*                      Internal phy section                      */
4157 /******************************************************************/
4158
4159 static void elink_set_serdes_access(struct bnx2x_softc *sc, uint8_t port)
4160 {
4161         uint32_t emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4162
4163         /* Set Clause 22 */
4164         REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_ST + port * 0x10, 1);
4165         REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
4166         DELAY(500);
4167         REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
4168         DELAY(500);
4169          /* Set Clause 45 */
4170         REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_ST + port * 0x10, 0);
4171 }
4172
4173 static void elink_serdes_deassert(struct bnx2x_softc *sc, uint8_t port)
4174 {
4175         uint32_t val;
4176
4177         ELINK_DEBUG_P0(sc, "elink_serdes_deassert");
4178
4179         val = ELINK_SERDES_RESET_BITS << (port * 16);
4180
4181         /* Reset and unreset the SerDes/XGXS */
4182         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
4183         DELAY(500);
4184         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
4185
4186         elink_set_serdes_access(sc, port);
4187
4188         REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_DEVAD + port * 0x10,
4189                ELINK_DEFAULT_PHY_DEV_ADDR);
4190 }
4191
4192 static void elink_xgxs_specific_func(struct elink_phy *phy,
4193                                      struct elink_params *params,
4194                                      uint32_t action)
4195 {
4196         struct bnx2x_softc *sc = params->sc;
4197         switch (action) {
4198         case ELINK_PHY_INIT:
4199                 /* Set correct devad */
4200                 REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_ST + params->port * 0x18, 0);
4201                 REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port * 0x18,
4202                        phy->def_md_devad);
4203                 break;
4204         }
4205 }
4206
4207 static void elink_xgxs_deassert(struct elink_params *params)
4208 {
4209         struct bnx2x_softc *sc = params->sc;
4210         uint8_t port;
4211         uint32_t val;
4212         ELINK_DEBUG_P0(sc, "elink_xgxs_deassert");
4213         port = params->port;
4214
4215         val = ELINK_XGXS_RESET_BITS << (port * 16);
4216
4217         /* Reset and unreset the SerDes/XGXS */
4218         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
4219         DELAY(500);
4220         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
4221         elink_xgxs_specific_func(&params->phy[ELINK_INT_PHY], params,
4222                                  ELINK_PHY_INIT);
4223 }
4224
4225 static void elink_calc_ieee_aneg_adv(struct elink_phy *phy,
4226                                      struct elink_params *params,
4227                                      uint16_t *ieee_fc)
4228 {
4229         struct bnx2x_softc *sc = params->sc;
4230         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
4231         /* Resolve pause mode and advertisement Please refer to Table
4232          * 28B-3 of the 802.3ab-1999 spec
4233          */
4234
4235         switch (phy->req_flow_ctrl) {
4236         case ELINK_FLOW_CTRL_AUTO:
4237                 switch (params->req_fc_auto_adv) {
4238                 case ELINK_FLOW_CTRL_BOTH:
4239                 case ELINK_FLOW_CTRL_RX:
4240                         *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4241                         break;
4242                 case ELINK_FLOW_CTRL_TX:
4243                         *ieee_fc |=
4244                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
4245                         break;
4246                 default:
4247                         break;
4248                 }
4249                 break;
4250         case ELINK_FLOW_CTRL_TX:
4251                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
4252                 break;
4253
4254         case ELINK_FLOW_CTRL_RX:
4255         case ELINK_FLOW_CTRL_BOTH:
4256                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4257                 break;
4258
4259         case ELINK_FLOW_CTRL_NONE:
4260         default:
4261                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
4262                 break;
4263         }
4264         ELINK_DEBUG_P1(sc, "ieee_fc = 0x%x", *ieee_fc);
4265 }
4266
4267 static void set_phy_vars(struct elink_params *params,
4268                          struct elink_vars *vars)
4269 {
4270         struct bnx2x_softc *sc = params->sc;
4271         uint8_t actual_phy_idx, phy_index, link_cfg_idx;
4272         uint8_t phy_config_swapped = params->multi_phy_config &
4273                         PORT_HW_CFG_PHY_SWAPPED_ENABLED;
4274         for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
4275               phy_index++) {
4276                 link_cfg_idx = ELINK_LINK_CONFIG_IDX(phy_index);
4277                 actual_phy_idx = phy_index;
4278                 if (phy_config_swapped) {
4279                         if (phy_index == ELINK_EXT_PHY1)
4280                                 actual_phy_idx = ELINK_EXT_PHY2;
4281                         else if (phy_index == ELINK_EXT_PHY2)
4282                                 actual_phy_idx = ELINK_EXT_PHY1;
4283                 }
4284                 params->phy[actual_phy_idx].req_flow_ctrl =
4285                         params->req_flow_ctrl[link_cfg_idx];
4286
4287                 params->phy[actual_phy_idx].req_line_speed =
4288                         params->req_line_speed[link_cfg_idx];
4289
4290                 params->phy[actual_phy_idx].speed_cap_mask =
4291                         params->speed_cap_mask[link_cfg_idx];
4292
4293                 params->phy[actual_phy_idx].req_duplex =
4294                         params->req_duplex[link_cfg_idx];
4295
4296                 if (params->req_line_speed[link_cfg_idx] ==
4297                     ELINK_SPEED_AUTO_NEG)
4298                         vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
4299
4300                 ELINK_DEBUG_P3(sc, "req_flow_ctrl %x, req_line_speed %x,"
4301                            " speed_cap_mask %x",
4302                            params->phy[actual_phy_idx].req_flow_ctrl,
4303                            params->phy[actual_phy_idx].req_line_speed,
4304                            params->phy[actual_phy_idx].speed_cap_mask);
4305         }
4306 }
4307
4308 static void elink_ext_phy_set_pause(struct elink_params *params,
4309                                     struct elink_phy *phy,
4310                                     struct elink_vars *vars)
4311 {
4312         uint16_t val;
4313         struct bnx2x_softc *sc = params->sc;
4314         /* Read modify write pause advertizing */
4315         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
4316
4317         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
4318
4319         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
4320         elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
4321         if ((vars->ieee_fc &
4322             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
4323             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
4324                 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
4325         }
4326         if ((vars->ieee_fc &
4327             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
4328             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
4329                 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
4330         }
4331         ELINK_DEBUG_P1(sc, "Ext phy AN advertize 0x%x", val);
4332         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
4333 }
4334
4335 static void elink_pause_resolve(__rte_unused struct elink_phy *phy,
4336                                 struct elink_params *params,
4337                                 struct elink_vars *vars,
4338                                 uint32_t pause_result)
4339 {
4340         struct bnx2x_softc *sc = params->sc;
4341                                                 /*  LD      LP   */
4342         switch (pause_result) {                 /* ASYM P ASYM P */
4343         case 0xb:                               /*   1  0   1  1 */
4344                 ELINK_DEBUG_P0(sc, "Flow Control: TX only");
4345                 vars->flow_ctrl = ELINK_FLOW_CTRL_TX;
4346                 break;
4347
4348         case 0xe:                               /*   1  1   1  0 */
4349                 ELINK_DEBUG_P0(sc, "Flow Control: RX only");
4350                 vars->flow_ctrl = ELINK_FLOW_CTRL_RX;
4351                 break;
4352
4353         case 0x5:                               /*   0  1   0  1 */
4354         case 0x7:                               /*   0  1   1  1 */
4355         case 0xd:                               /*   1  1   0  1 */
4356         case 0xf:                               /*   1  1   1  1 */
4357                 /* If the user selected to advertise RX ONLY,
4358                  * although we advertised both, need to enable
4359                  * RX only.
4360                  */
4361
4362                 if (params->req_fc_auto_adv == ELINK_FLOW_CTRL_BOTH) {
4363                         ELINK_DEBUG_P0(sc, "Flow Control: RX & TX");
4364                 vars->flow_ctrl = ELINK_FLOW_CTRL_BOTH;
4365                 } else {
4366                         ELINK_DEBUG_P0(sc, "Flow Control: RX only");
4367                         vars->flow_ctrl = ELINK_FLOW_CTRL_RX;
4368                 }
4369                 break;
4370         default:
4371                 ELINK_DEBUG_P0(sc, "Flow Control: None");
4372                 vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
4373                 break;
4374         }
4375         if (pause_result & (1 << 0))
4376                 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
4377         if (pause_result & (1 << 1))
4378                 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
4379
4380 }
4381
4382 static void elink_ext_phy_update_adv_fc(struct elink_phy *phy,
4383                                         struct elink_params *params,
4384                                         struct elink_vars *vars)
4385 {
4386         uint16_t ld_pause;              /* local */
4387         uint16_t lp_pause;              /* link partner */
4388         uint16_t pause_result;
4389         struct bnx2x_softc *sc = params->sc;
4390         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE) {
4391                 elink_cl22_read(sc, phy, 0x4, &ld_pause);
4392                 elink_cl22_read(sc, phy, 0x5, &lp_pause);
4393         } else if (CHIP_IS_E3(sc) &&
4394                 ELINK_SINGLE_MEDIA_DIRECT(params)) {
4395                 uint8_t lane = elink_get_warpcore_lane(phy, params);
4396                 uint16_t gp_status, gp_mask;
4397                 elink_cl45_read(sc, phy,
4398                                 MDIO_AN_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_4,
4399                                 &gp_status);
4400                 gp_mask = (MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL |
4401                            MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP) <<
4402                         lane;
4403                 if ((gp_status & gp_mask) == gp_mask) {
4404                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4405                                         MDIO_AN_REG_ADV_PAUSE, &ld_pause);
4406                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4407                                         MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
4408                 } else {
4409                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4410                                         MDIO_AN_REG_CL37_FC_LD, &ld_pause);
4411                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4412                                         MDIO_AN_REG_CL37_FC_LP, &lp_pause);
4413                         ld_pause = ((ld_pause &
4414                                      MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
4415                                     << 3);
4416                         lp_pause = ((lp_pause &
4417                                      MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
4418                                     << 3);
4419                 }
4420         } else {
4421                 elink_cl45_read(sc, phy,
4422                                 MDIO_AN_DEVAD,
4423                                 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
4424                 elink_cl45_read(sc, phy,
4425                                 MDIO_AN_DEVAD,
4426                                 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
4427         }
4428         pause_result = (ld_pause &
4429                         MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
4430         pause_result |= (lp_pause &
4431                          MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
4432         ELINK_DEBUG_P1(sc, "Ext PHY pause result 0x%x", pause_result);
4433         elink_pause_resolve(phy, params, vars, pause_result);
4434
4435 }
4436
4437 static uint8_t elink_ext_phy_resolve_fc(struct elink_phy *phy,
4438                                    struct elink_params *params,
4439                                    struct elink_vars *vars)
4440 {
4441         uint8_t ret = 0;
4442         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
4443         if (phy->req_flow_ctrl != ELINK_FLOW_CTRL_AUTO) {
4444                 /* Update the advertised flow-controled of LD/LP in AN */
4445                 if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
4446                         elink_ext_phy_update_adv_fc(phy, params, vars);
4447                 /* But set the flow-control result as the requested one */
4448                 vars->flow_ctrl = phy->req_flow_ctrl;
4449         } else if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
4450                 vars->flow_ctrl = params->req_fc_auto_adv;
4451         else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
4452                 ret = 1;
4453                 elink_ext_phy_update_adv_fc(phy, params, vars);
4454         }
4455         return ret;
4456 }
4457 /******************************************************************/
4458 /*                      Warpcore section                          */
4459 /******************************************************************/
4460 /* The init_internal_warpcore should mirror the xgxs,
4461  * i.e. reset the lane (if needed), set aer for the
4462  * init configuration, and set/clear SGMII flag. Internal
4463  * phy init is done purely in phy_init stage.
4464  */
4465 #define WC_TX_DRIVER(post2, idriver, ipre, ifir) \
4466         ((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \
4467          (idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \
4468          (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET) | \
4469          (ifir << MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET))
4470
4471 #define WC_TX_FIR(post, main, pre) \
4472         ((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \
4473          (main << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | \
4474          (pre << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET))
4475
4476 static void elink_update_link_attr(struct elink_params *params,
4477                                    uint32_t link_attr)
4478 {
4479         struct bnx2x_softc *sc = params->sc;
4480
4481         if (SHMEM2_HAS(sc, link_attr_sync))
4482                 REG_WR(sc, params->shmem2_base +
4483                        offsetof(struct shmem2_region,
4484                                 link_attr_sync[params->port]), link_attr);
4485 }
4486
4487 static void elink_warpcore_enable_AN_KR2(struct elink_phy *phy,
4488                                          struct elink_params *params,
4489                                          __rte_unused struct elink_vars *vars)
4490 {
4491         struct bnx2x_softc *sc = params->sc;
4492         uint16_t i;
4493         static struct elink_reg_set reg_set[] = {
4494                 /* Step 1 - Program the TX/RX alignment markers */
4495                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0xa157},
4496                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xcbe2},
4497                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0x7537},
4498                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0xa157},
4499                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xcbe2},
4500                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0x7537},
4501                 /* Step 2 - Configure the NP registers */
4502                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000a},
4503                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6400},
4504                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0620},
4505                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0157},
4506                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x6464},
4507                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x3150},
4508                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x3150},
4509                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0157},
4510                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0620}
4511         };
4512         ELINK_DEBUG_P0(sc, "Enabling 20G-KR2");
4513
4514         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4515                                  MDIO_WC_REG_CL49_USERB0_CTRL, (3 << 6));
4516
4517         for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4518                 elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4519                                  reg_set[i].val);
4520
4521         /* Start KR2 work-around timer which handles BNX2X8073 link-parner */
4522         params->link_attr_sync |= LINK_ATTR_SYNC_KR2_ENABLE;
4523         elink_update_link_attr(params, params->link_attr_sync);
4524 }
4525
4526 static void elink_disable_kr2(struct elink_params *params,
4527                               struct elink_vars *vars,
4528                               struct elink_phy *phy)
4529 {
4530         struct bnx2x_softc *sc = params->sc;
4531         int i;
4532         static struct elink_reg_set reg_set[] = {
4533                 /* Step 1 - Program the TX/RX alignment markers */
4534                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0x7690},
4535                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xe647},
4536                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0xc4f0},
4537                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0x7690},
4538                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xe647},
4539                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0xc4f0},
4540                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000c},
4541                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6000},
4542                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0000},
4543                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0002},
4544                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x0000},
4545                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x0af7},
4546                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x0af7},
4547                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0002},
4548                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0000}
4549         };
4550         ELINK_DEBUG_P0(sc, "Disabling 20G-KR2");
4551
4552         for (i = 0; i < (int)ARRAY_SIZE(reg_set); i++)
4553                 elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4554                                  reg_set[i].val);
4555         params->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE;
4556         elink_update_link_attr(params, params->link_attr_sync);
4557
4558         vars->check_kr2_recovery_cnt = ELINK_CHECK_KR2_RECOVERY_CNT;
4559 }
4560
4561 static void elink_warpcore_set_lpi_passthrough(struct elink_phy *phy,
4562                                                struct elink_params *params)
4563 {
4564         struct bnx2x_softc *sc = params->sc;
4565
4566         ELINK_DEBUG_P0(sc, "Configure WC for LPI pass through");
4567         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4568                          MDIO_WC_REG_EEE_COMBO_CONTROL0, 0x7c);
4569         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4570                                  MDIO_WC_REG_DIGITAL4_MISC5, 0xc000);
4571 }
4572
4573 static void elink_warpcore_restart_AN_KR(struct elink_phy *phy,
4574                                          struct elink_params *params)
4575 {
4576         /* Restart autoneg on the leading lane only */
4577         struct bnx2x_softc *sc = params->sc;
4578         uint16_t lane = elink_get_warpcore_lane(phy, params);
4579         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4580                           MDIO_AER_BLOCK_AER_REG, lane);
4581         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4582                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
4583
4584         /* Restore AER */
4585         elink_set_aer_mmd(params, phy);
4586 }
4587
4588 static void elink_warpcore_enable_AN_KR(struct elink_phy *phy,
4589                                         struct elink_params *params,
4590                                         struct elink_vars *vars) {
4591         uint16_t lane, i, cl72_ctrl, an_adv = 0, val;
4592         uint32_t wc_lane_config;
4593         struct bnx2x_softc *sc = params->sc;
4594         static struct elink_reg_set reg_set[] = {
4595                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
4596                 {MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0},
4597                 {MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415},
4598                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190},
4599                 /* Disable Autoneg: re-enable it after adv is done. */
4600                 {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0},
4601                 {MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2},
4602                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0},
4603         };
4604         ELINK_DEBUG_P0(sc,  "Enable Auto Negotiation for KR");
4605         /* Set to default registers that may be overridden by 10G force */
4606         for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4607                 elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4608                                  reg_set[i].val);
4609
4610         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4611                         MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl);
4612         cl72_ctrl &= 0x08ff;
4613         cl72_ctrl |= 0x3800;
4614         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4615                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl);
4616
4617         /* Check adding advertisement for 1G KX */
4618         if (((vars->line_speed == ELINK_SPEED_AUTO_NEG) &&
4619              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
4620             (vars->line_speed == ELINK_SPEED_1000)) {
4621                 uint16_t addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2;
4622                 an_adv |= (1 << 5);
4623
4624                 /* Enable CL37 1G Parallel Detect */
4625                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD, addr, 0x1);
4626                 ELINK_DEBUG_P0(sc, "Advertize 1G");
4627         }
4628         if (((vars->line_speed == ELINK_SPEED_AUTO_NEG) &&
4629              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
4630             (vars->line_speed ==  ELINK_SPEED_10000)) {
4631                 /* Check adding advertisement for 10G KR */
4632                 an_adv |= (1 << 7);
4633                 /* Enable 10G Parallel Detect */
4634                 CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4635                                   MDIO_AER_BLOCK_AER_REG, 0);
4636
4637                 elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4638                                  MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
4639                 elink_set_aer_mmd(params, phy);
4640                 ELINK_DEBUG_P0(sc, "Advertize 10G");
4641         }
4642
4643         /* Set Transmit PMD settings */
4644         lane = elink_get_warpcore_lane(phy, params);
4645         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4646                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * lane,
4647                          WC_TX_DRIVER(0x02, 0x06, 0x09, 0));
4648         /* Configure the next lane if dual mode */
4649         if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
4650                 elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4651                                  MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * (lane + 1),
4652                                  WC_TX_DRIVER(0x02, 0x06, 0x09, 0));
4653         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4654                          MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
4655                          0x03f0);
4656         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4657                          MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
4658                          0x03f0);
4659
4660         /* Advertised speeds */
4661         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4662                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, an_adv);
4663
4664         /* Advertised and set FEC (Forward Error Correction) */
4665         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4666                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2,
4667                          (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY |
4668                           MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ));
4669
4670         /* Enable CL37 BAM */
4671         if (REG_RD(sc, params->shmem_base +
4672                    offsetof(struct shmem_region, dev_info.
4673                             port_hw_config[params->port].default_cfg)) &
4674             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
4675                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4676                                          MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL,
4677                                          1);
4678                 ELINK_DEBUG_P0(sc, "Enable CL37 BAM on KR");
4679         }
4680
4681         /* Advertise pause */
4682         elink_ext_phy_set_pause(params, phy, vars);
4683         vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
4684         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4685                                  MDIO_WC_REG_DIGITAL5_MISC7, 0x100);
4686
4687         /* Over 1G - AN local device user page 1 */
4688         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4689                         MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
4690
4691         if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
4692              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) ||
4693             (phy->req_line_speed == ELINK_SPEED_20000)) {
4694
4695                 CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4696                                   MDIO_AER_BLOCK_AER_REG, lane);
4697
4698                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4699                                          MDIO_WC_REG_RX1_PCI_CTRL +
4700                                          (0x10 * lane),
4701                                          (1 << 11));
4702
4703                 elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4704                                  MDIO_WC_REG_XGXS_X2_CONTROL3, 0x7);
4705                 elink_set_aer_mmd(params, phy);
4706
4707                 elink_warpcore_enable_AN_KR2(phy, params, vars);
4708         } else {
4709                 /* Enable Auto-Detect to support 1G over CL37 as well */
4710                 elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4711                                  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x10);
4712                 wc_lane_config = REG_RD(sc, params->shmem_base +
4713                                         offsetof(struct shmem_region, dev_info.
4714                                         shared_hw_config.wc_lane_config));
4715                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4716                                 MDIO_WC_REG_RX0_PCI_CTRL + (lane << 4), &val);
4717                 /* Force cl48 sync_status LOW to avoid getting stuck in CL73
4718                  * parallel-detect loop when CL73 and CL37 are enabled.
4719                  */
4720                 val |= 1 << 11;
4721
4722                 /* Restore Polarity settings in case it was run over by
4723                  * previous link owner
4724                  */
4725                 if (wc_lane_config &
4726                     (SHARED_HW_CFG_RX_LANE0_POL_FLIP_ENABLED << lane))
4727                         val |= 3 << 2;
4728                 else
4729                         val &= ~(3 << 2);
4730                 elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4731                                  MDIO_WC_REG_RX0_PCI_CTRL + (lane << 4),
4732                                  val);
4733
4734                 elink_disable_kr2(params, vars, phy);
4735         }
4736
4737         /* Enable Autoneg: only on the main lane */
4738         elink_warpcore_restart_AN_KR(phy, params);
4739 }
4740
4741 static void elink_warpcore_set_10G_KR(struct elink_phy *phy,
4742                                       struct elink_params *params,
4743                                       __rte_unused struct elink_vars *vars)
4744 {
4745         struct bnx2x_softc *sc = params->sc;
4746         uint16_t val16, i, lane;
4747         static struct elink_reg_set reg_set[] = {
4748                 /* Disable Autoneg */
4749                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
4750                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
4751                         0x3f00},
4752                 {MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0},
4753                 {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0},
4754                 {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1},
4755                 {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa},
4756                 /* Leave cl72 training enable, needed for KR */
4757                 {MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2}
4758         };
4759
4760         for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4761                 elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4762                                  reg_set[i].val);
4763
4764         lane = elink_get_warpcore_lane(phy, params);
4765         /* Global registers */
4766         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4767                           MDIO_AER_BLOCK_AER_REG, 0);
4768         /* Disable CL36 PCS Tx */
4769         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4770                         MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
4771         val16 &= ~(0x0011 << lane);
4772         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4773                          MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
4774
4775         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4776                         MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
4777         val16 |= (0x0303 << (lane << 1));
4778         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4779                          MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
4780         /* Restore AER */
4781         elink_set_aer_mmd(params, phy);
4782         /* Set speed via PMA/PMD register */
4783         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD,
4784                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
4785
4786         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD,
4787                          MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
4788
4789         /* Enable encoded forced speed */
4790         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4791                          MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
4792
4793         /* Turn TX scramble payload only the 64/66 scrambler */
4794         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4795                          MDIO_WC_REG_TX66_CONTROL, 0x9);
4796
4797         /* Turn RX scramble payload only the 64/66 scrambler */
4798         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4799                                  MDIO_WC_REG_RX66_CONTROL, 0xF9);
4800
4801         /* Set and clear loopback to cause a reset to 64/66 decoder */
4802         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4803                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
4804         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4805                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
4806
4807 }
4808
4809 static void elink_warpcore_set_10G_XFI(struct elink_phy *phy,
4810                                        struct elink_params *params,
4811                                        uint8_t is_xfi)
4812 {
4813         struct bnx2x_softc *sc = params->sc;
4814         uint16_t misc1_val, tap_val, tx_driver_val, lane, val;
4815         uint32_t cfg_tap_val, tx_drv_brdct, tx_equal;
4816         uint32_t ifir_val, ipost2_val, ipre_driver_val;
4817         /* Hold rxSeqStart */
4818         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4819                                  MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x8000);
4820
4821         /* Hold tx_fifo_reset */
4822         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4823                                  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x1);
4824
4825         /* Disable CL73 AN */
4826         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
4827
4828         /* Disable 100FX Enable and Auto-Detect */
4829         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4830                                   MDIO_WC_REG_FX100_CTRL1, 0xFFFA);
4831
4832         /* Disable 100FX Idle detect */
4833         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4834                                  MDIO_WC_REG_FX100_CTRL3, 0x0080);
4835
4836         /* Set Block address to Remote PHY & Clear forced_speed[5] */
4837         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4838                                   MDIO_WC_REG_DIGITAL4_MISC3, 0xFF7F);
4839
4840         /* Turn off auto-detect & fiber mode */
4841         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4842                                   MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4843                                   0xFFEE);
4844
4845         /* Set filter_force_link, disable_false_link and parallel_detect */
4846         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4847                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
4848         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4849                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4850                          ((val | 0x0006) & 0xFFFE));
4851
4852         /* Set XFI / SFI */
4853         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4854                         MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
4855
4856         misc1_val &= ~(0x1f);
4857
4858         if (is_xfi) {
4859                 misc1_val |= 0x5;
4860                 tap_val = WC_TX_FIR(0x08, 0x37, 0x00);
4861                 tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03, 0);
4862         } else {
4863                 cfg_tap_val = REG_RD(sc, params->shmem_base +
4864                                      offsetof(struct shmem_region, dev_info.
4865                                               port_hw_config[params->port].
4866                                               sfi_tap_values));
4867
4868                 tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK;
4869
4870                 misc1_val |= 0x9;
4871
4872                 /* TAP values are controlled by nvram, if value there isn't 0 */
4873                 if (tx_equal)
4874                         tap_val = (uint16_t)tx_equal;
4875                 else
4876                         tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02);
4877
4878                 ifir_val = DEFAULT_TX_DRV_IFIR;
4879                 ipost2_val = DEFAULT_TX_DRV_POST2;
4880                 ipre_driver_val = DEFAULT_TX_DRV_IPRE_DRIVER;
4881                 tx_drv_brdct = DEFAULT_TX_DRV_BRDCT;
4882
4883                 /* If any of the IFIR/IPRE_DRIVER/POST@ is set, apply all
4884                  * configuration.
4885                  */
4886                 if (cfg_tap_val & (PORT_HW_CFG_TX_DRV_IFIR_MASK |
4887                                    PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK |
4888                                    PORT_HW_CFG_TX_DRV_POST2_MASK)) {
4889                         ifir_val = (cfg_tap_val &
4890                                     PORT_HW_CFG_TX_DRV_IFIR_MASK) >>
4891                                 PORT_HW_CFG_TX_DRV_IFIR_SHIFT;
4892                         ipre_driver_val = (cfg_tap_val &
4893                                            PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK)
4894                         >> PORT_HW_CFG_TX_DRV_IPREDRIVER_SHIFT;
4895                         ipost2_val = (cfg_tap_val &
4896                                       PORT_HW_CFG_TX_DRV_POST2_MASK) >>
4897                                 PORT_HW_CFG_TX_DRV_POST2_SHIFT;
4898                 }
4899
4900                 if (cfg_tap_val & PORT_HW_CFG_TX_DRV_BROADCAST_MASK) {
4901                         tx_drv_brdct = (cfg_tap_val &
4902                                         PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >>
4903                                 PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT;
4904                 }
4905
4906                 tx_driver_val = WC_TX_DRIVER(ipost2_val, tx_drv_brdct,
4907                                              ipre_driver_val, ifir_val);
4908         }
4909         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4910                          MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
4911
4912         /* Set Transmit PMD settings */
4913         lane = elink_get_warpcore_lane(phy, params);
4914         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4915                          MDIO_WC_REG_TX_FIR_TAP,
4916                          tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
4917         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4918                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * lane,
4919                          tx_driver_val);
4920
4921         /* Enable fiber mode, enable and invert sig_det */
4922         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4923                                  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0xd);
4924
4925         /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
4926         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4927                                  MDIO_WC_REG_DIGITAL4_MISC3, 0x8080);
4928
4929         elink_warpcore_set_lpi_passthrough(phy, params);
4930
4931         /* 10G XFI Full Duplex */
4932         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4933                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
4934
4935         /* Release tx_fifo_reset */
4936         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4937                                   MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3,
4938                                   0xFFFE);
4939         /* Release rxSeqStart */
4940         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4941                                   MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x7FFF);
4942 }
4943
4944 static void elink_warpcore_set_20G_force_KR2(struct elink_phy *phy,
4945                                              struct elink_params *params)
4946 {
4947         uint16_t val;
4948         struct bnx2x_softc *sc = params->sc;
4949         /* Set global registers, so set AER lane to 0 */
4950         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4951                           MDIO_AER_BLOCK_AER_REG, 0);
4952
4953         /* Disable sequencer */
4954         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4955                                   MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, ~(1 << 13));
4956
4957         elink_set_aer_mmd(params, phy);
4958
4959         elink_cl45_read_and_write(sc, phy, MDIO_PMA_DEVAD,
4960                                   MDIO_WC_REG_PMD_KR_CONTROL, ~(1 << 1));
4961         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4962                          MDIO_AN_REG_CTRL, 0);
4963         /* Turn off CL73 */
4964         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4965                         MDIO_WC_REG_CL73_USERB0_CTRL, &val);
4966         val &= ~(1 << 5);
4967         val |= (1 << 6);
4968         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4969                          MDIO_WC_REG_CL73_USERB0_CTRL, val);
4970
4971         /* Set 20G KR2 force speed */
4972         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4973                                  MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x1f);
4974
4975         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4976                                  MDIO_WC_REG_DIGITAL4_MISC3, (1 << 7));
4977
4978         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4979                         MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &val);
4980         val &= ~(3 << 14);
4981         val |= (1 << 15);
4982         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4983                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, val);
4984         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4985                          MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0x835A);
4986
4987         /* Enable sequencer (over lane 0) */
4988         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4989                           MDIO_AER_BLOCK_AER_REG, 0);
4990
4991         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4992                                  MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, (1 << 13));
4993
4994         elink_set_aer_mmd(params, phy);
4995 }
4996
4997 static void elink_warpcore_set_20G_DXGXS(struct bnx2x_softc *sc,
4998                                          struct elink_phy *phy,
4999                                          uint16_t lane)
5000 {
5001         /* Rx0 anaRxControl1G */
5002         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5003                          MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
5004
5005         /* Rx2 anaRxControl1G */
5006         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5007                          MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
5008
5009         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5010                          MDIO_WC_REG_RX66_SCW0, 0xE070);
5011
5012         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5013                          MDIO_WC_REG_RX66_SCW1, 0xC0D0);
5014
5015         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5016                          MDIO_WC_REG_RX66_SCW2, 0xA0B0);
5017
5018         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5019                          MDIO_WC_REG_RX66_SCW3, 0x8090);
5020
5021         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5022                          MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
5023
5024         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5025                          MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
5026
5027         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5028                          MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
5029
5030         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5031                          MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
5032
5033         /* Serdes Digital Misc1 */
5034         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5035                          MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
5036
5037         /* Serdes Digital4 Misc3 */
5038         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5039                          MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
5040
5041         /* Set Transmit PMD settings */
5042         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5043                          MDIO_WC_REG_TX_FIR_TAP,
5044                          (WC_TX_FIR(0x12, 0x2d, 0x00) |
5045                           MDIO_WC_REG_TX_FIR_TAP_ENABLE));
5046         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5047                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * lane,
5048                          WC_TX_DRIVER(0x02, 0x02, 0x02, 0));
5049 }
5050
5051 static void elink_warpcore_set_sgmii_speed(struct elink_phy *phy,
5052                                            struct elink_params *params,
5053                                            uint8_t fiber_mode,
5054                                            uint8_t always_autoneg)
5055 {
5056         struct bnx2x_softc *sc = params->sc;
5057         uint16_t val16, digctrl_kx1, digctrl_kx2;
5058
5059         /* Clear XFI clock comp in non-10G single lane mode. */
5060         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5061                                   MDIO_WC_REG_RX66_CONTROL, ~(3 << 13));
5062
5063         elink_warpcore_set_lpi_passthrough(phy, params);
5064
5065         if (always_autoneg || phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
5066                 /* SGMII Autoneg */
5067                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5068                                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
5069                                          0x1000);
5070                 ELINK_DEBUG_P0(sc, "set SGMII AUTONEG");
5071         } else {
5072                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5073                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
5074                 val16 &= 0xcebf;
5075                 switch (phy->req_line_speed) {
5076                 case ELINK_SPEED_10:
5077                         break;
5078                 case ELINK_SPEED_100:
5079                         val16 |= 0x2000;
5080                         break;
5081                 case ELINK_SPEED_1000:
5082                         val16 |= 0x0040;
5083                         break;
5084                 default:
5085                         ELINK_DEBUG_P1(sc,
5086                            "Speed not supported: 0x%x", phy->req_line_speed);
5087                         return;
5088                 }
5089
5090                 if (phy->req_duplex == DUPLEX_FULL)
5091                         val16 |= 0x0100;
5092
5093                 elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5094                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
5095
5096                 ELINK_DEBUG_P1(sc, "set SGMII force speed %d",
5097                                phy->req_line_speed);
5098                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5099                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
5100                 ELINK_DEBUG_P1(sc, "  (readback) %x", val16);
5101         }
5102
5103         /* SGMII Slave mode and disable signal detect */
5104         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5105                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
5106         if (fiber_mode)
5107                 digctrl_kx1 = 1;
5108         else
5109                 digctrl_kx1 &= 0xff4a;
5110
5111         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5112                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
5113                         digctrl_kx1);
5114
5115         /* Turn off parallel detect */
5116         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5117                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
5118         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5119                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
5120                         (digctrl_kx2 & ~(1 << 2)));
5121
5122         /* Re-enable parallel detect */
5123         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5124                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
5125                         (digctrl_kx2 | (1 << 2)));
5126
5127         /* Enable autodet */
5128         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5129                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
5130                         (digctrl_kx1 | 0x10));
5131 }
5132
5133
5134 static void elink_warpcore_reset_lane(struct bnx2x_softc *sc,
5135                                       struct elink_phy *phy,
5136                                       uint8_t reset)
5137 {
5138         uint16_t val;
5139         /* Take lane out of reset after configuration is finished */
5140         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5141                         MDIO_WC_REG_DIGITAL5_MISC6, &val);
5142         if (reset)
5143                 val |= 0xC000;
5144         else
5145                 val &= 0x3FFF;
5146         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5147                          MDIO_WC_REG_DIGITAL5_MISC6, val);
5148         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5149                          MDIO_WC_REG_DIGITAL5_MISC6, &val);
5150 }
5151
5152 /* Clear SFI/XFI link settings registers */
5153 static void elink_warpcore_clear_regs(struct elink_phy *phy,
5154                                       struct elink_params *params,
5155                                       uint16_t lane)
5156 {
5157         struct bnx2x_softc *sc = params->sc;
5158         uint16_t i;
5159         static struct elink_reg_set wc_regs[] = {
5160                 {MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0},
5161                 {MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL1, 0x014a},
5162                 {MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL3, 0x0800},
5163                 {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL4_MISC3, 0x8008},
5164                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
5165                         0x0195},
5166                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
5167                         0x0007},
5168                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3,
5169                         0x0002},
5170                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000},
5171                 {MDIO_WC_DEVAD, MDIO_WC_REG_TX_FIR_TAP, 0x0000},
5172                 {MDIO_WC_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040},
5173                 {MDIO_WC_DEVAD, MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140}
5174         };
5175         /* Set XFI clock comp as default. */
5176         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5177                                  MDIO_WC_REG_RX66_CONTROL, (3 << 13));
5178
5179         for (i = 0; i < ARRAY_SIZE(wc_regs); i++)
5180                 elink_cl45_write(sc, phy, wc_regs[i].devad, wc_regs[i].reg,
5181                                  wc_regs[i].val);
5182
5183         lane = elink_get_warpcore_lane(phy, params);
5184         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5185                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10 * lane, 0x0990);
5186
5187 }
5188
5189 static elink_status_t elink_get_mod_abs_int_cfg(struct bnx2x_softc *sc,
5190                                                 __rte_unused uint32_t chip_id,
5191                                                 uint32_t shmem_base,
5192                                                 uint8_t port,
5193                                                 uint8_t *gpio_num,
5194                                                 uint8_t *gpio_port)
5195 {
5196         uint32_t cfg_pin;
5197         *gpio_num = 0;
5198         *gpio_port = 0;
5199         if (CHIP_IS_E3(sc)) {
5200                 cfg_pin = (REG_RD(sc, shmem_base +
5201                                 offsetof(struct shmem_region,
5202                                 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
5203                                 PORT_HW_CFG_E3_MOD_ABS_MASK) >>
5204                                 PORT_HW_CFG_E3_MOD_ABS_SHIFT;
5205
5206                 /*
5207                  * This should not happen since this function is called
5208                  * from interrupt triggered by GPIO (since EPIO can only
5209                  * generate interrupts to MCP).
5210                  * So if this function was called and none of the GPIOs was set,
5211                  * it means something disastrous has already happened.
5212                  */
5213                 if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
5214                     (cfg_pin > PIN_CFG_GPIO3_P1)) {
5215                         ELINK_DEBUG_P1(sc,
5216                            "No cfg pin %x for module detect indication",
5217                            cfg_pin);
5218                         return ELINK_STATUS_ERROR;
5219                 }
5220
5221                 *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
5222                 *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
5223         } else {
5224                 *gpio_num = MISC_REGISTERS_GPIO_3;
5225                 *gpio_port = port;
5226         }
5227
5228         return ELINK_STATUS_OK;
5229 }
5230
5231 static int elink_is_sfp_module_plugged(__rte_unused struct elink_phy *phy,
5232                                        struct elink_params *params)
5233 {
5234         struct bnx2x_softc *sc = params->sc;
5235         uint8_t gpio_num, gpio_port;
5236         uint32_t gpio_val;
5237         if (elink_get_mod_abs_int_cfg(sc, params->chip_id,
5238                                       params->shmem_base, params->port,
5239                                       &gpio_num, &gpio_port) != ELINK_STATUS_OK)
5240                 return 0;
5241         gpio_val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
5242
5243         /* Call the handling function in case module is detected */
5244         if (gpio_val == 0)
5245                 return 1;
5246         else
5247                 return 0;
5248 }
5249 static int elink_warpcore_get_sigdet(struct elink_phy *phy,
5250                                      struct elink_params *params)
5251 {
5252         uint16_t gp2_status_reg0, lane;
5253         struct bnx2x_softc *sc = params->sc;
5254
5255         lane = elink_get_warpcore_lane(phy, params);
5256
5257         elink_cl45_read(sc, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
5258                                  &gp2_status_reg0);
5259
5260         return (gp2_status_reg0 >> (8 + lane)) & 0x1;
5261 }
5262
5263 static void elink_warpcore_config_runtime(struct elink_phy *phy,
5264                                           struct elink_params *params,
5265                                           struct elink_vars *vars)
5266 {
5267         struct bnx2x_softc *sc = params->sc;
5268         uint32_t serdes_net_if;
5269         uint16_t gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
5270
5271         vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
5272
5273         if (!vars->turn_to_run_wc_rt)
5274                 return;
5275
5276         if (vars->rx_tx_asic_rst) {
5277                 uint16_t lane = elink_get_warpcore_lane(phy, params);
5278                 serdes_net_if = (REG_RD(sc, params->shmem_base +
5279                                 offsetof(struct shmem_region, dev_info.
5280                                 port_hw_config[params->port].default_cfg)) &
5281                                 PORT_HW_CFG_NET_SERDES_IF_MASK);
5282
5283                 switch (serdes_net_if) {
5284                 case PORT_HW_CFG_NET_SERDES_IF_KR:
5285                         /* Do we get link yet? */
5286                         elink_cl45_read(sc, phy, MDIO_WC_DEVAD, 0x81d1,
5287                                         &gp_status1);
5288                         lnkup = (gp_status1 >> (8 + lane)) & 0x1;/* 1G */
5289                                 /*10G KR*/
5290                         lnkup_kr = (gp_status1 >> (12 + lane)) & 0x1;
5291
5292                         if (lnkup_kr || lnkup) {
5293                                 vars->rx_tx_asic_rst = 0;
5294                         } else {
5295                                 /* Reset the lane to see if link comes up.*/
5296                                 elink_warpcore_reset_lane(sc, phy, 1);
5297                                 elink_warpcore_reset_lane(sc, phy, 0);
5298
5299                                 /* Restart Autoneg */
5300                                 elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
5301                                         MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
5302
5303                                 vars->rx_tx_asic_rst--;
5304                                 ELINK_DEBUG_P1(sc, "0x%x retry left",
5305                                 vars->rx_tx_asic_rst);
5306                         }
5307                         break;
5308
5309                 default:
5310                         break;
5311                 }
5312
5313         } /*params->rx_tx_asic_rst*/
5314 }
5315
5316 static void elink_warpcore_config_sfi(struct elink_phy *phy,
5317                                       struct elink_params *params)
5318 {
5319         uint16_t lane = elink_get_warpcore_lane(phy, params);
5320         struct bnx2x_softc *sc = params->sc;
5321         elink_warpcore_clear_regs(phy, params, lane);
5322         if ((params->req_line_speed[ELINK_LINK_CONFIG_IDX(ELINK_INT_PHY)] ==
5323              ELINK_SPEED_10000) &&
5324             (phy->media_type != ELINK_ETH_PHY_SFP_1G_FIBER)) {
5325                 ELINK_DEBUG_P0(sc, "Setting 10G SFI");
5326                 elink_warpcore_set_10G_XFI(phy, params, 0);
5327         } else {
5328                 ELINK_DEBUG_P0(sc, "Setting 1G Fiber");
5329                 elink_warpcore_set_sgmii_speed(phy, params, 1, 0);
5330         }
5331 }
5332
5333 static void elink_sfp_e3_set_transmitter(struct elink_params *params,
5334                                          struct elink_phy *phy,
5335                                          uint8_t tx_en)
5336 {
5337         struct bnx2x_softc *sc = params->sc;
5338         uint32_t cfg_pin;
5339         uint8_t port = params->port;
5340
5341         cfg_pin = REG_RD(sc, params->shmem_base +
5342                          offsetof(struct shmem_region,
5343                                   dev_info.port_hw_config[port].e3_sfp_ctrl)) &
5344                 PORT_HW_CFG_E3_TX_LASER_MASK;
5345         /* Set the !tx_en since this pin is DISABLE_TX_LASER */
5346         ELINK_DEBUG_P1(sc, "Setting WC TX to %d", tx_en);
5347
5348         /* For 20G, the expected pin to be used is 3 pins after the current */
5349         elink_set_cfg_pin(sc, cfg_pin, tx_en ^ 1);
5350         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
5351                 elink_set_cfg_pin(sc, cfg_pin + 3, tx_en ^ 1);
5352 }
5353
5354 static uint8_t elink_warpcore_config_init(struct elink_phy *phy,
5355                                        struct elink_params *params,
5356                                        struct elink_vars *vars)
5357 {
5358         struct bnx2x_softc *sc = params->sc;
5359         uint32_t serdes_net_if;
5360         uint8_t fiber_mode;
5361         uint16_t lane = elink_get_warpcore_lane(phy, params);
5362         serdes_net_if = (REG_RD(sc, params->shmem_base +
5363                          offsetof(struct shmem_region, dev_info.
5364                                   port_hw_config[params->port].default_cfg)) &
5365                          PORT_HW_CFG_NET_SERDES_IF_MASK);
5366         ELINK_DEBUG_P2(sc, "Begin Warpcore init, link_speed %d, "
5367                            "serdes_net_if = 0x%x",
5368                        vars->line_speed, serdes_net_if);
5369         elink_set_aer_mmd(params, phy);
5370         elink_warpcore_reset_lane(sc, phy, 1);
5371         vars->phy_flags |= PHY_XGXS_FLAG;
5372         if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
5373             (phy->req_line_speed &&
5374              ((phy->req_line_speed == ELINK_SPEED_100) ||
5375               (phy->req_line_speed == ELINK_SPEED_10)))) {
5376                 vars->phy_flags |= PHY_SGMII_FLAG;
5377                 ELINK_DEBUG_P0(sc, "Setting SGMII mode");
5378                 elink_warpcore_clear_regs(phy, params, lane);
5379                 elink_warpcore_set_sgmii_speed(phy, params, 0, 1);
5380         } else {
5381                 switch (serdes_net_if) {
5382                 case PORT_HW_CFG_NET_SERDES_IF_KR:
5383                         /* Enable KR Auto Neg */
5384                         if (params->loopback_mode != ELINK_LOOPBACK_EXT)
5385                                 elink_warpcore_enable_AN_KR(phy, params, vars);
5386                         else {
5387                                 ELINK_DEBUG_P0(sc, "Setting KR 10G-Force");
5388                                 elink_warpcore_set_10G_KR(phy, params, vars);
5389                         }
5390                         break;
5391
5392                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
5393                         elink_warpcore_clear_regs(phy, params, lane);
5394                         if (vars->line_speed == ELINK_SPEED_10000) {
5395                                 ELINK_DEBUG_P0(sc, "Setting 10G XFI");
5396                                 elink_warpcore_set_10G_XFI(phy, params, 1);
5397                         } else {
5398                                 if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
5399                                         ELINK_DEBUG_P0(sc, "1G Fiber");
5400                                         fiber_mode = 1;
5401                                 } else {
5402                                         ELINK_DEBUG_P0(sc, "10/100/1G SGMII");
5403                                         fiber_mode = 0;
5404                                 }
5405                                 elink_warpcore_set_sgmii_speed(phy,
5406                                                                 params,
5407                                                                 fiber_mode,
5408                                                                 0);
5409                         }
5410
5411                         break;
5412
5413                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
5414                         /* Issue Module detection if module is plugged, or
5415                          * enabled transmitter to avoid current leakage in case
5416                          * no module is connected
5417                          */
5418                         if ((params->loopback_mode == ELINK_LOOPBACK_NONE) ||
5419                             (params->loopback_mode == ELINK_LOOPBACK_EXT)) {
5420                                 if (elink_is_sfp_module_plugged(phy, params))
5421                                         elink_sfp_module_detection(phy, params);
5422                                 else
5423                                         elink_sfp_e3_set_transmitter(params,
5424                                                                      phy, 1);
5425                         }
5426
5427                         elink_warpcore_config_sfi(phy, params);
5428                         break;
5429
5430                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
5431                         if (vars->line_speed != ELINK_SPEED_20000) {
5432                                 ELINK_DEBUG_P0(sc, "Speed not supported yet");
5433                                 return 0;
5434                         }
5435                         ELINK_DEBUG_P0(sc, "Setting 20G DXGXS");
5436                         elink_warpcore_set_20G_DXGXS(sc, phy, lane);
5437                         /* Issue Module detection */
5438
5439                         elink_sfp_module_detection(phy, params);
5440                         break;
5441                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
5442                         if (!params->loopback_mode) {
5443                                 elink_warpcore_enable_AN_KR(phy, params, vars);
5444                         } else {
5445                                 ELINK_DEBUG_P0(sc, "Setting KR 20G-Force");
5446                                 elink_warpcore_set_20G_force_KR2(phy, params);
5447                         }
5448                         break;
5449                 default:
5450                         ELINK_DEBUG_P1(sc,
5451                            "Unsupported Serdes Net Interface 0x%x",
5452                            serdes_net_if);
5453                         return 0;
5454                 }
5455         }
5456
5457         /* Take lane out of reset after configuration is finished */
5458         elink_warpcore_reset_lane(sc, phy, 0);
5459         ELINK_DEBUG_P0(sc, "Exit config init");
5460
5461         return 0;
5462 }
5463
5464 static void elink_warpcore_link_reset(struct elink_phy *phy,
5465                                       struct elink_params *params)
5466 {
5467         struct bnx2x_softc *sc = params->sc;
5468         uint16_t val16, lane;
5469         elink_sfp_e3_set_transmitter(params, phy, 0);
5470         elink_set_mdio_emac_per_phy(sc, params);
5471         elink_set_aer_mmd(params, phy);
5472         /* Global register */
5473         elink_warpcore_reset_lane(sc, phy, 1);
5474
5475         /* Clear loopback settings (if any) */
5476         /* 10G & 20G */
5477         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5478                                   MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0xBFFF);
5479
5480         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5481                                   MDIO_WC_REG_IEEE0BLK_MIICNTL, 0xfffe);
5482
5483         /* Update those 1-copy registers */
5484         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
5485                           MDIO_AER_BLOCK_AER_REG, 0);
5486         /* Enable 1G MDIO (1-copy) */
5487         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5488                                   MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
5489                                   ~0x10);
5490
5491         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5492                                   MDIO_WC_REG_XGXSBLK1_LANECTRL2, 0xff00);
5493         lane = elink_get_warpcore_lane(phy, params);
5494         /* Disable CL36 PCS Tx */
5495         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5496                         MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
5497         val16 |= (0x11 << lane);
5498         if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
5499                 val16 |= (0x22 << lane);
5500         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5501                          MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
5502
5503         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5504                         MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
5505         val16 &= ~(0x0303 << (lane << 1));
5506         val16 |= (0x0101 << (lane << 1));
5507         if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE) {
5508                 val16 &= ~(0x0c0c << (lane << 1));
5509                 val16 |= (0x0404 << (lane << 1));
5510         }
5511
5512         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5513                          MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
5514         /* Restore AER */
5515         elink_set_aer_mmd(params, phy);
5516
5517 }
5518
5519 static void elink_set_warpcore_loopback(struct elink_phy *phy,
5520                                         struct elink_params *params)
5521 {
5522         struct bnx2x_softc *sc = params->sc;
5523         uint16_t val16;
5524         uint32_t lane;
5525         ELINK_DEBUG_P2(sc, "Setting Warpcore loopback type %x, speed %d",
5526                        params->loopback_mode, phy->req_line_speed);
5527
5528         if (phy->req_line_speed < ELINK_SPEED_10000 ||
5529             phy->supported & ELINK_SUPPORTED_20000baseKR2_Full) {
5530                 /* 10/100/1000/20G-KR2 */
5531
5532                 /* Update those 1-copy registers */
5533                 CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
5534                                   MDIO_AER_BLOCK_AER_REG, 0);
5535                 /* Enable 1G MDIO (1-copy) */
5536                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5537                                          MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
5538                                          0x10);
5539                 /* Set 1G loopback based on lane (1-copy) */
5540                 lane = elink_get_warpcore_lane(phy, params);
5541                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5542                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
5543                 val16 |= (1 << lane);
5544                 if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
5545                         val16 |= (2 << lane);
5546                 elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5547                                  MDIO_WC_REG_XGXSBLK1_LANECTRL2,
5548                                  val16);
5549
5550                 /* Switch back to 4-copy registers */
5551                 elink_set_aer_mmd(params, phy);
5552         } else {
5553                 /* 10G / 20G-DXGXS */
5554                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5555                                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
5556                                          0x4000);
5557                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5558                                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1);
5559         }
5560 }
5561
5562
5563
5564 static void elink_sync_link(struct elink_params *params,
5565                              struct elink_vars *vars)
5566 {
5567         struct bnx2x_softc *sc = params->sc;
5568         uint8_t link_10g_plus;
5569         if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
5570                 vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
5571         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
5572         if (vars->link_up) {
5573                 ELINK_DEBUG_P0(sc, "phy link up");
5574                 ELINK_DEBUG_P1(sc, "link status = %x", vars->link_status);
5575
5576                 vars->phy_link_up = 1;
5577                 vars->duplex = DUPLEX_FULL;
5578                 switch (vars->link_status &
5579                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
5580                 case ELINK_LINK_10THD:
5581                         vars->duplex = DUPLEX_HALF;
5582                         /* Fall thru */
5583                 case ELINK_LINK_10TFD:
5584                         vars->line_speed = ELINK_SPEED_10;
5585                         break;
5586
5587                 case ELINK_LINK_100TXHD:
5588                         vars->duplex = DUPLEX_HALF;
5589                         /* Fall thru */
5590                 case ELINK_LINK_100T4:
5591                 case ELINK_LINK_100TXFD:
5592                         vars->line_speed = ELINK_SPEED_100;
5593                         break;
5594
5595                 case ELINK_LINK_1000THD:
5596                         vars->duplex = DUPLEX_HALF;
5597                         /* Fall thru */
5598                 case ELINK_LINK_1000TFD:
5599                         vars->line_speed = ELINK_SPEED_1000;
5600                         break;
5601
5602                 case ELINK_LINK_2500THD:
5603                         vars->duplex = DUPLEX_HALF;
5604                         /* Fall thru */
5605                 case ELINK_LINK_2500TFD:
5606                         vars->line_speed = ELINK_SPEED_2500;
5607                         break;
5608
5609                 case ELINK_LINK_10GTFD:
5610                         vars->line_speed = ELINK_SPEED_10000;
5611                         break;
5612                 case ELINK_LINK_20GTFD:
5613                         vars->line_speed = ELINK_SPEED_20000;
5614                         break;
5615                 default:
5616                         break;
5617                 }
5618                 vars->flow_ctrl = 0;
5619                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
5620                         vars->flow_ctrl |= ELINK_FLOW_CTRL_TX;
5621
5622                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
5623                         vars->flow_ctrl |= ELINK_FLOW_CTRL_RX;
5624
5625                 if (!vars->flow_ctrl)
5626                         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
5627
5628                 if (vars->line_speed &&
5629                     ((vars->line_speed == ELINK_SPEED_10) ||
5630                      (vars->line_speed == ELINK_SPEED_100))) {
5631                         vars->phy_flags |= PHY_SGMII_FLAG;
5632                 } else {
5633                         vars->phy_flags &= ~PHY_SGMII_FLAG;
5634                 }
5635                 if (vars->line_speed &&
5636                     USES_WARPCORE(sc) &&
5637                     (vars->line_speed == ELINK_SPEED_1000))
5638                         vars->phy_flags |= PHY_SGMII_FLAG;
5639                 /* Anything 10 and over uses the bmac */
5640                 link_10g_plus = (vars->line_speed >= ELINK_SPEED_10000);
5641
5642                 if (link_10g_plus) {
5643                         if (USES_WARPCORE(sc))
5644                                 vars->mac_type = ELINK_MAC_TYPE_XMAC;
5645                         else
5646                                 vars->mac_type = ELINK_MAC_TYPE_BMAC;
5647                 } else {
5648                         if (USES_WARPCORE(sc))
5649                                 vars->mac_type = ELINK_MAC_TYPE_UMAC;
5650                         else
5651                                 vars->mac_type = ELINK_MAC_TYPE_EMAC;
5652                 }
5653         } else { /* Link down */
5654                 ELINK_DEBUG_P0(sc, "phy link down");
5655
5656                 vars->phy_link_up = 0;
5657
5658                 vars->line_speed = 0;
5659                 vars->duplex = DUPLEX_FULL;
5660                 vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
5661
5662                 /* Indicate no mac active */
5663                 vars->mac_type = ELINK_MAC_TYPE_NONE;
5664                 if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
5665                         vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
5666                 if (vars->link_status & LINK_STATUS_SFP_TX_FAULT)
5667                         vars->phy_flags |= PHY_SFP_TX_FAULT_FLAG;
5668         }
5669 }
5670
5671 void elink_link_status_update(struct elink_params *params,
5672                               struct elink_vars *vars)
5673 {
5674         struct bnx2x_softc *sc = params->sc;
5675         uint8_t port = params->port;
5676         uint32_t sync_offset, media_types;
5677         /* Update PHY configuration */
5678         set_phy_vars(params, vars);
5679
5680         vars->link_status = REG_RD(sc, params->shmem_base +
5681                                    offsetof(struct shmem_region,
5682                                             port_mb[port].link_status));
5683
5684         /* Force link UP in non LOOPBACK_EXT loopback mode(s) */
5685         if (params->loopback_mode != ELINK_LOOPBACK_NONE &&
5686             params->loopback_mode != ELINK_LOOPBACK_EXT)
5687                 vars->link_status |= LINK_STATUS_LINK_UP;
5688
5689         if (elink_eee_has_cap(params))
5690                 vars->eee_status = REG_RD(sc, params->shmem2_base +
5691                                           offsetof(struct shmem2_region,
5692                                                    eee_status[params->port]));
5693
5694         vars->phy_flags = PHY_XGXS_FLAG;
5695         elink_sync_link(params, vars);
5696         /* Sync media type */
5697         sync_offset = params->shmem_base +
5698                         offsetof(struct shmem_region,
5699                                  dev_info.port_hw_config[port].media_type);
5700         media_types = REG_RD(sc, sync_offset);
5701
5702         params->phy[ELINK_INT_PHY].media_type =
5703                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
5704                 PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
5705         params->phy[ELINK_EXT_PHY1].media_type =
5706                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
5707                 PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
5708         params->phy[ELINK_EXT_PHY2].media_type =
5709                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
5710                 PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
5711         ELINK_DEBUG_P1(sc, "media_types = 0x%x", media_types);
5712
5713         /* Sync AEU offset */
5714         sync_offset = params->shmem_base +
5715                         offsetof(struct shmem_region,
5716                                  dev_info.port_hw_config[port].aeu_int_mask);
5717
5718         vars->aeu_int_mask = REG_RD(sc, sync_offset);
5719
5720         /* Sync PFC status */
5721         if (vars->link_status & LINK_STATUS_PFC_ENABLED)
5722                 params->feature_config_flags |=
5723                                         ELINK_FEATURE_CONFIG_PFC_ENABLED;
5724         else
5725                 params->feature_config_flags &=
5726                                         ~ELINK_FEATURE_CONFIG_PFC_ENABLED;
5727
5728         if (SHMEM2_HAS(sc, link_attr_sync))
5729                 params->link_attr_sync = SHMEM2_RD(sc,
5730                                                  link_attr_sync[params->port]);
5731
5732         ELINK_DEBUG_P3(sc, "link_status 0x%x  phy_link_up %x int_mask 0x%x",
5733                  vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
5734         ELINK_DEBUG_P3(sc, "line_speed %x  duplex %x  flow_ctrl 0x%x",
5735                  vars->line_speed, vars->duplex, vars->flow_ctrl);
5736 }
5737
5738 static void elink_set_master_ln(struct elink_params *params,
5739                                 struct elink_phy *phy)
5740 {
5741         struct bnx2x_softc *sc = params->sc;
5742         uint16_t new_master_ln, ser_lane;
5743         ser_lane = ((params->lane_config &
5744                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5745                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5746
5747         /* Set the master_ln for AN */
5748         CL22_RD_OVER_CL45(sc, phy,
5749                           MDIO_REG_BANK_XGXS_BLOCK2,
5750                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
5751                           &new_master_ln);
5752
5753         CL22_WR_OVER_CL45(sc, phy,
5754                           MDIO_REG_BANK_XGXS_BLOCK2,
5755                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
5756                           (new_master_ln | ser_lane));
5757 }
5758
5759 static elink_status_t elink_reset_unicore(struct elink_params *params,
5760                                struct elink_phy *phy,
5761                                uint8_t set_serdes)
5762 {
5763         struct bnx2x_softc *sc = params->sc;
5764         uint16_t mii_control;
5765         uint16_t i;
5766         CL22_RD_OVER_CL45(sc, phy,
5767                           MDIO_REG_BANK_COMBO_IEEE0,
5768                           MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
5769
5770         /* Reset the unicore */
5771         CL22_WR_OVER_CL45(sc, phy,
5772                           MDIO_REG_BANK_COMBO_IEEE0,
5773                           MDIO_COMBO_IEEE0_MII_CONTROL,
5774                           (mii_control |
5775                            MDIO_COMBO_IEEO_MII_CONTROL_RESET));
5776         if (set_serdes)
5777                 elink_set_serdes_access(sc, params->port);
5778
5779         /* Wait for the reset to self clear */
5780         for (i = 0; i < ELINK_MDIO_ACCESS_TIMEOUT; i++) {
5781                 DELAY(5);
5782
5783                 /* The reset erased the previous bank value */
5784                 CL22_RD_OVER_CL45(sc, phy,
5785                                   MDIO_REG_BANK_COMBO_IEEE0,
5786                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5787                                   &mii_control);
5788
5789                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
5790                         DELAY(5);
5791                         return ELINK_STATUS_OK;
5792                 }
5793         }
5794
5795         elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED, params->port);
5796                              /* "Warning: PHY was not initialized,"
5797                               * " Port %d",
5798                               */
5799
5800         ELINK_DEBUG_P0(sc, "BUG! XGXS is still in reset!");
5801         return ELINK_STATUS_ERROR;
5802
5803 }
5804
5805 static void elink_set_swap_lanes(struct elink_params *params,
5806                                  struct elink_phy *phy)
5807 {
5808         struct bnx2x_softc *sc = params->sc;
5809         /* Each two bits represents a lane number:
5810          * No swap is 0123 => 0x1b no need to enable the swap
5811          */
5812         uint16_t rx_lane_swap, tx_lane_swap;
5813
5814         rx_lane_swap = ((params->lane_config &
5815                          PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
5816                         PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
5817         tx_lane_swap = ((params->lane_config &
5818                          PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
5819                         PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
5820
5821         if (rx_lane_swap != 0x1b) {
5822                 CL22_WR_OVER_CL45(sc, phy,
5823                                   MDIO_REG_BANK_XGXS_BLOCK2,
5824                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP,
5825                                   (rx_lane_swap |
5826                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
5827                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
5828         } else {
5829                 CL22_WR_OVER_CL45(sc, phy,
5830                                   MDIO_REG_BANK_XGXS_BLOCK2,
5831                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
5832         }
5833
5834         if (tx_lane_swap != 0x1b) {
5835                 CL22_WR_OVER_CL45(sc, phy,
5836                                   MDIO_REG_BANK_XGXS_BLOCK2,
5837                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP,
5838                                   (tx_lane_swap |
5839                                    MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
5840         } else {
5841                 CL22_WR_OVER_CL45(sc, phy,
5842                                   MDIO_REG_BANK_XGXS_BLOCK2,
5843                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
5844         }
5845 }
5846
5847 static void elink_set_parallel_detection(struct elink_phy *phy,
5848                                          struct elink_params *params)
5849 {
5850         struct bnx2x_softc *sc = params->sc;
5851         uint16_t control2;
5852         CL22_RD_OVER_CL45(sc, phy,
5853                           MDIO_REG_BANK_SERDES_DIGITAL,
5854                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
5855                           &control2);
5856         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5857                 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
5858         else
5859                 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
5860         ELINK_DEBUG_P2(sc, "phy->speed_cap_mask = 0x%x, control2 = 0x%x",
5861                 phy->speed_cap_mask, control2);
5862         CL22_WR_OVER_CL45(sc, phy,
5863                           MDIO_REG_BANK_SERDES_DIGITAL,
5864                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
5865                           control2);
5866
5867         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
5868              (phy->speed_cap_mask &
5869                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
5870                 ELINK_DEBUG_P0(sc, "XGXS");
5871
5872                 CL22_WR_OVER_CL45(sc, phy,
5873                                  MDIO_REG_BANK_10G_PARALLEL_DETECT,
5874                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
5875                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
5876
5877                 CL22_RD_OVER_CL45(sc, phy,
5878                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
5879                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
5880                                   &control2);
5881
5882
5883                 control2 |=
5884                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
5885
5886                 CL22_WR_OVER_CL45(sc, phy,
5887                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
5888                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
5889                                   control2);
5890
5891                 /* Disable parallel detection of HiG */
5892                 CL22_WR_OVER_CL45(sc, phy,
5893                                   MDIO_REG_BANK_XGXS_BLOCK2,
5894                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
5895                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
5896                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
5897         }
5898 }
5899
5900 static void elink_set_autoneg(struct elink_phy *phy,
5901                               struct elink_params *params,
5902                               struct elink_vars *vars,
5903                               uint8_t enable_cl73)
5904 {
5905         struct bnx2x_softc *sc = params->sc;
5906         uint16_t reg_val;
5907
5908         /* CL37 Autoneg */
5909         CL22_RD_OVER_CL45(sc, phy,
5910                           MDIO_REG_BANK_COMBO_IEEE0,
5911                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
5912
5913         /* CL37 Autoneg Enabled */
5914         if (vars->line_speed == ELINK_SPEED_AUTO_NEG)
5915                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
5916         else /* CL37 Autoneg Disabled */
5917                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5918                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
5919
5920         CL22_WR_OVER_CL45(sc, phy,
5921                           MDIO_REG_BANK_COMBO_IEEE0,
5922                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
5923
5924         /* Enable/Disable Autodetection */
5925
5926         CL22_RD_OVER_CL45(sc, phy,
5927                           MDIO_REG_BANK_SERDES_DIGITAL,
5928                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
5929         reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
5930                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
5931         reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
5932         if (vars->line_speed == ELINK_SPEED_AUTO_NEG)
5933                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
5934         else
5935                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
5936
5937         CL22_WR_OVER_CL45(sc, phy,
5938                           MDIO_REG_BANK_SERDES_DIGITAL,
5939                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
5940
5941         /* Enable TetonII and BAM autoneg */
5942         CL22_RD_OVER_CL45(sc, phy,
5943                           MDIO_REG_BANK_BAM_NEXT_PAGE,
5944                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
5945                           &reg_val);
5946         if (vars->line_speed == ELINK_SPEED_AUTO_NEG) {
5947                 /* Enable BAM aneg Mode and TetonII aneg Mode */
5948                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
5949                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
5950         } else {
5951                 /* TetonII and BAM Autoneg Disabled */
5952                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
5953                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
5954         }
5955         CL22_WR_OVER_CL45(sc, phy,
5956                           MDIO_REG_BANK_BAM_NEXT_PAGE,
5957                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
5958                           reg_val);
5959
5960         if (enable_cl73) {
5961                 /* Enable Cl73 FSM status bits */
5962                 CL22_WR_OVER_CL45(sc, phy,
5963                                   MDIO_REG_BANK_CL73_USERB0,
5964                                   MDIO_CL73_USERB0_CL73_UCTRL,
5965                                   0xe);
5966
5967                 /* Enable BAM Station Manager*/
5968                 CL22_WR_OVER_CL45(sc, phy,
5969                         MDIO_REG_BANK_CL73_USERB0,
5970                         MDIO_CL73_USERB0_CL73_BAM_CTRL1,
5971                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
5972                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
5973                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
5974
5975                 /* Advertise CL73 link speeds */
5976                 CL22_RD_OVER_CL45(sc, phy,
5977                                   MDIO_REG_BANK_CL73_IEEEB1,
5978                                   MDIO_CL73_IEEEB1_AN_ADV2,
5979                                   &reg_val);
5980                 if (phy->speed_cap_mask &
5981                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
5982                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
5983                 if (phy->speed_cap_mask &
5984                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5985                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
5986
5987                 CL22_WR_OVER_CL45(sc, phy,
5988                                   MDIO_REG_BANK_CL73_IEEEB1,
5989                                   MDIO_CL73_IEEEB1_AN_ADV2,
5990                                   reg_val);
5991
5992                 /* CL73 Autoneg Enabled */
5993                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
5994
5995         } else /* CL73 Autoneg Disabled */
5996                 reg_val = 0;
5997
5998         CL22_WR_OVER_CL45(sc, phy,
5999                           MDIO_REG_BANK_CL73_IEEEB0,
6000                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
6001 }
6002
6003 /* Program SerDes, forced speed */
6004 static void elink_program_serdes(struct elink_phy *phy,
6005                                  struct elink_params *params,
6006                                  struct elink_vars *vars)
6007 {
6008         struct bnx2x_softc *sc = params->sc;
6009         uint16_t reg_val;
6010
6011         /* Program duplex, disable autoneg and sgmii*/
6012         CL22_RD_OVER_CL45(sc, phy,
6013                           MDIO_REG_BANK_COMBO_IEEE0,
6014                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
6015         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
6016                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
6017                      MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
6018         if (phy->req_duplex == DUPLEX_FULL)
6019                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
6020         CL22_WR_OVER_CL45(sc, phy,
6021                           MDIO_REG_BANK_COMBO_IEEE0,
6022                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
6023
6024         /* Program speed
6025          *  - needed only if the speed is greater than 1G (2.5G or 10G)
6026          */
6027         CL22_RD_OVER_CL45(sc, phy,
6028                           MDIO_REG_BANK_SERDES_DIGITAL,
6029                           MDIO_SERDES_DIGITAL_MISC1, &reg_val);
6030         /* Clearing the speed value before setting the right speed */
6031         ELINK_DEBUG_P1(sc, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x", reg_val);
6032
6033         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
6034                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
6035
6036         if (!((vars->line_speed == ELINK_SPEED_1000) ||
6037               (vars->line_speed == ELINK_SPEED_100) ||
6038               (vars->line_speed == ELINK_SPEED_10))) {
6039
6040                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
6041                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
6042                 if (vars->line_speed == ELINK_SPEED_10000)
6043                         reg_val |=
6044                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
6045         }
6046
6047         CL22_WR_OVER_CL45(sc, phy,
6048                           MDIO_REG_BANK_SERDES_DIGITAL,
6049                           MDIO_SERDES_DIGITAL_MISC1, reg_val);
6050
6051 }
6052
6053 static void elink_set_brcm_cl37_advertisement(struct elink_phy *phy,
6054                                               struct elink_params *params)
6055 {
6056         struct bnx2x_softc *sc = params->sc;
6057         uint16_t val = 0;
6058
6059         /* Set extended capabilities */
6060         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
6061                 val |= MDIO_OVER_1G_UP1_2_5G;
6062         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
6063                 val |= MDIO_OVER_1G_UP1_10G;
6064         CL22_WR_OVER_CL45(sc, phy,
6065                           MDIO_REG_BANK_OVER_1G,
6066                           MDIO_OVER_1G_UP1, val);
6067
6068         CL22_WR_OVER_CL45(sc, phy,
6069                           MDIO_REG_BANK_OVER_1G,
6070                           MDIO_OVER_1G_UP3, 0x400);
6071 }
6072
6073 static void elink_set_ieee_aneg_advertisement(struct elink_phy *phy,
6074                                               struct elink_params *params,
6075                                               uint16_t ieee_fc)
6076 {
6077         struct bnx2x_softc *sc = params->sc;
6078         uint16_t val;
6079         /* For AN, we are always publishing full duplex */
6080
6081         CL22_WR_OVER_CL45(sc, phy,
6082                           MDIO_REG_BANK_COMBO_IEEE0,
6083                           MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
6084         CL22_RD_OVER_CL45(sc, phy,
6085                           MDIO_REG_BANK_CL73_IEEEB1,
6086                           MDIO_CL73_IEEEB1_AN_ADV1, &val);
6087         val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
6088         val |= ((ieee_fc << 3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
6089         CL22_WR_OVER_CL45(sc, phy,
6090                           MDIO_REG_BANK_CL73_IEEEB1,
6091                           MDIO_CL73_IEEEB1_AN_ADV1, val);
6092 }
6093
6094 static void elink_restart_autoneg(struct elink_phy *phy,
6095                                   struct elink_params *params,
6096                                   uint8_t enable_cl73)
6097 {
6098         struct bnx2x_softc *sc = params->sc;
6099         uint16_t mii_control;
6100
6101         ELINK_DEBUG_P0(sc, "elink_restart_autoneg");
6102         /* Enable and restart BAM/CL37 aneg */
6103
6104         if (enable_cl73) {
6105                 CL22_RD_OVER_CL45(sc, phy,
6106                                   MDIO_REG_BANK_CL73_IEEEB0,
6107                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6108                                   &mii_control);
6109
6110                 CL22_WR_OVER_CL45(sc, phy,
6111                                   MDIO_REG_BANK_CL73_IEEEB0,
6112                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6113                                   (mii_control |
6114                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
6115                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
6116         } else {
6117
6118                 CL22_RD_OVER_CL45(sc, phy,
6119                                   MDIO_REG_BANK_COMBO_IEEE0,
6120                                   MDIO_COMBO_IEEE0_MII_CONTROL,
6121                                   &mii_control);
6122                 ELINK_DEBUG_P1(sc,
6123                          "elink_restart_autoneg mii_control before = 0x%x",
6124                          mii_control);
6125                 CL22_WR_OVER_CL45(sc, phy,
6126                                   MDIO_REG_BANK_COMBO_IEEE0,
6127                                   MDIO_COMBO_IEEE0_MII_CONTROL,
6128                                   (mii_control |
6129                                    MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
6130                                    MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
6131         }
6132 }
6133
6134 static void elink_initialize_sgmii_process(struct elink_phy *phy,
6135                                            struct elink_params *params,
6136                                            struct elink_vars *vars)
6137 {
6138         struct bnx2x_softc *sc = params->sc;
6139         uint16_t control1;
6140
6141         /* In SGMII mode, the unicore is always slave */
6142
6143         CL22_RD_OVER_CL45(sc, phy,
6144                           MDIO_REG_BANK_SERDES_DIGITAL,
6145                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
6146                           &control1);
6147         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
6148         /* Set sgmii mode (and not fiber) */
6149         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
6150                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
6151                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
6152         CL22_WR_OVER_CL45(sc, phy,
6153                           MDIO_REG_BANK_SERDES_DIGITAL,
6154                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
6155                           control1);
6156
6157         /* If forced speed */
6158         if (!(vars->line_speed == ELINK_SPEED_AUTO_NEG)) {
6159                 /* Set speed, disable autoneg */
6160                 uint16_t mii_control;
6161
6162                 CL22_RD_OVER_CL45(sc, phy,
6163                                   MDIO_REG_BANK_COMBO_IEEE0,
6164                                   MDIO_COMBO_IEEE0_MII_CONTROL,
6165                                   &mii_control);
6166                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
6167                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK |
6168                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
6169
6170                 switch (vars->line_speed) {
6171                 case ELINK_SPEED_100:
6172                         mii_control |=
6173                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
6174                         break;
6175                 case ELINK_SPEED_1000:
6176                         mii_control |=
6177                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
6178                         break;
6179                 case ELINK_SPEED_10:
6180                         /* There is nothing to set for 10M */
6181                         break;
6182                 default:
6183                         /* Invalid speed for SGMII */
6184                         ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x",
6185                                   vars->line_speed);
6186                         break;
6187                 }
6188
6189                 /* Setting the full duplex */
6190                 if (phy->req_duplex == DUPLEX_FULL)
6191                         mii_control |=
6192                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
6193                 CL22_WR_OVER_CL45(sc, phy,
6194                                   MDIO_REG_BANK_COMBO_IEEE0,
6195                                   MDIO_COMBO_IEEE0_MII_CONTROL,
6196                                   mii_control);
6197
6198         } else { /* AN mode */
6199                 /* Enable and restart AN */
6200                 elink_restart_autoneg(phy, params, 0);
6201         }
6202 }
6203
6204 /* Link management
6205  */
6206 static elink_status_t elink_direct_parallel_detect_used(struct elink_phy *phy,
6207                                              struct elink_params *params)
6208 {
6209         struct bnx2x_softc *sc = params->sc;
6210         uint16_t pd_10g, status2_1000x;
6211         if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
6212                 return ELINK_STATUS_OK;
6213         CL22_RD_OVER_CL45(sc, phy,
6214                           MDIO_REG_BANK_SERDES_DIGITAL,
6215                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
6216                           &status2_1000x);
6217         CL22_RD_OVER_CL45(sc, phy,
6218                           MDIO_REG_BANK_SERDES_DIGITAL,
6219                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
6220                           &status2_1000x);
6221         if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
6222                 ELINK_DEBUG_P1(sc, "1G parallel detect link on port %d",
6223                          params->port);
6224                 return 1;
6225         }
6226
6227         CL22_RD_OVER_CL45(sc, phy,
6228                           MDIO_REG_BANK_10G_PARALLEL_DETECT,
6229                           MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
6230                           &pd_10g);
6231
6232         if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
6233                 ELINK_DEBUG_P1(sc, "10G parallel detect link on port %d",
6234                          params->port);
6235                 return 1;
6236         }
6237         return ELINK_STATUS_OK;
6238 }
6239
6240 static void elink_update_adv_fc(struct elink_phy *phy,
6241                                 struct elink_params *params,
6242                                 struct elink_vars *vars,
6243                                 uint32_t gp_status)
6244 {
6245         uint16_t ld_pause;   /* local driver */
6246         uint16_t lp_pause;   /* link partner */
6247         uint16_t pause_result;
6248         struct bnx2x_softc *sc = params->sc;
6249         if ((gp_status &
6250              (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
6251               MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
6252             (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
6253              MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
6254
6255                 CL22_RD_OVER_CL45(sc, phy,
6256                                   MDIO_REG_BANK_CL73_IEEEB1,
6257                                   MDIO_CL73_IEEEB1_AN_ADV1,
6258                                   &ld_pause);
6259                 CL22_RD_OVER_CL45(sc, phy,
6260                                   MDIO_REG_BANK_CL73_IEEEB1,
6261                                   MDIO_CL73_IEEEB1_AN_LP_ADV1,
6262                                   &lp_pause);
6263                 pause_result = (ld_pause &
6264                                 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) >> 8;
6265                 pause_result |= (lp_pause &
6266                                  MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK) >> 10;
6267                 ELINK_DEBUG_P1(sc, "pause_result CL73 0x%x", pause_result);
6268         } else {
6269                 CL22_RD_OVER_CL45(sc, phy,
6270                                   MDIO_REG_BANK_COMBO_IEEE0,
6271                                   MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
6272                                   &ld_pause);
6273                 CL22_RD_OVER_CL45(sc, phy,
6274                         MDIO_REG_BANK_COMBO_IEEE0,
6275                         MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
6276                         &lp_pause);
6277                 pause_result = (ld_pause &
6278                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) >> 5;
6279                 pause_result |= (lp_pause &
6280                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) >> 7;
6281                 ELINK_DEBUG_P1(sc, "pause_result CL37 0x%x", pause_result);
6282         }
6283         elink_pause_resolve(phy, params, vars, pause_result);
6284
6285 }
6286
6287 static void elink_flow_ctrl_resolve(struct elink_phy *phy,
6288                                     struct elink_params *params,
6289                                     struct elink_vars *vars,
6290                                     uint32_t gp_status)
6291 {
6292         struct bnx2x_softc *sc = params->sc;
6293         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
6294
6295         /* Resolve from gp_status in case of AN complete and not sgmii */
6296         if (phy->req_flow_ctrl != ELINK_FLOW_CTRL_AUTO) {
6297                 /* Update the advertised flow-controled of LD/LP in AN */
6298                 if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6299                         elink_update_adv_fc(phy, params, vars, gp_status);
6300                 /* But set the flow-control result as the requested one */
6301                 vars->flow_ctrl = phy->req_flow_ctrl;
6302         } else if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
6303                 vars->flow_ctrl = params->req_fc_auto_adv;
6304         else if ((gp_status & ELINK_MDIO_AN_CL73_OR_37_COMPLETE) &&
6305                  (!(vars->phy_flags & PHY_SGMII_FLAG))) {
6306                 if (elink_direct_parallel_detect_used(phy, params)) {
6307                         vars->flow_ctrl = params->req_fc_auto_adv;
6308                         return;
6309                 }
6310                 elink_update_adv_fc(phy, params, vars, gp_status);
6311         }
6312         ELINK_DEBUG_P1(sc, "flow_ctrl 0x%x", vars->flow_ctrl);
6313 }
6314
6315 static void elink_check_fallback_to_cl37(struct elink_phy *phy,
6316                                          struct elink_params *params)
6317 {
6318         struct bnx2x_softc *sc = params->sc;
6319         uint16_t rx_status, ustat_val, cl37_fsm_received;
6320         ELINK_DEBUG_P0(sc, "elink_check_fallback_to_cl37");
6321         /* Step 1: Make sure signal is detected */
6322         CL22_RD_OVER_CL45(sc, phy,
6323                           MDIO_REG_BANK_RX0,
6324                           MDIO_RX0_RX_STATUS,
6325                           &rx_status);
6326         if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
6327             (MDIO_RX0_RX_STATUS_SIGDET)) {
6328                 ELINK_DEBUG_P1(sc, "Signal is not detected. Restoring CL73."
6329                              "rx_status(0x80b0) = 0x%x", rx_status);
6330                 CL22_WR_OVER_CL45(sc, phy,
6331                                   MDIO_REG_BANK_CL73_IEEEB0,
6332                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6333                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
6334                 return;
6335         }
6336         /* Step 2: Check CL73 state machine */
6337         CL22_RD_OVER_CL45(sc, phy,
6338                           MDIO_REG_BANK_CL73_USERB0,
6339                           MDIO_CL73_USERB0_CL73_USTAT1,
6340                           &ustat_val);
6341         if ((ustat_val &
6342              (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
6343               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
6344             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
6345               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
6346                 ELINK_DEBUG_P1(sc, "CL73 state-machine is not stable. "
6347                              "ustat_val(0x8371) = 0x%x", ustat_val);
6348                 return;
6349         }
6350         /* Step 3: Check CL37 Message Pages received to indicate LP
6351          * supports only CL37
6352          */
6353         CL22_RD_OVER_CL45(sc, phy,
6354                           MDIO_REG_BANK_REMOTE_PHY,
6355                           MDIO_REMOTE_PHY_MISC_RX_STATUS,
6356                           &cl37_fsm_received);
6357         if ((cl37_fsm_received &
6358              (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
6359              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
6360             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
6361               MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
6362                 ELINK_DEBUG_P1(sc, "No CL37 FSM were received. "
6363                              "misc_rx_status(0x8330) = 0x%x",
6364                          cl37_fsm_received);
6365                 return;
6366         }
6367         /* The combined cl37/cl73 fsm state information indicating that
6368          * we are connected to a device which does not support cl73, but
6369          * does support cl37 BAM. In this case we disable cl73 and
6370          * restart cl37 auto-neg
6371          */
6372
6373         /* Disable CL73 */
6374         CL22_WR_OVER_CL45(sc, phy,
6375                           MDIO_REG_BANK_CL73_IEEEB0,
6376                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6377                           0);
6378         /* Restart CL37 autoneg */
6379         elink_restart_autoneg(phy, params, 0);
6380         ELINK_DEBUG_P0(sc, "Disabling CL73, and restarting CL37 autoneg");
6381 }
6382
6383 static void elink_xgxs_an_resolve(struct elink_phy *phy,
6384                                   struct elink_params *params,
6385                                   struct elink_vars *vars,
6386                                   uint32_t gp_status)
6387 {
6388         if (gp_status & ELINK_MDIO_AN_CL73_OR_37_COMPLETE)
6389                 vars->link_status |=
6390                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6391
6392         if (elink_direct_parallel_detect_used(phy, params))
6393                 vars->link_status |=
6394                         LINK_STATUS_PARALLEL_DETECTION_USED;
6395 }
6396 static elink_status_t elink_get_link_speed_duplex(struct elink_phy *phy,
6397                                      struct elink_params *params,
6398                                       struct elink_vars *vars,
6399                                       uint16_t is_link_up,
6400                                       uint16_t speed_mask,
6401                                       uint16_t is_duplex)
6402 {
6403         struct bnx2x_softc *sc = params->sc;
6404         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6405                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
6406         if (is_link_up) {
6407                 ELINK_DEBUG_P0(sc, "phy link up");
6408
6409                 vars->phy_link_up = 1;
6410                 vars->link_status |= LINK_STATUS_LINK_UP;
6411
6412                 switch (speed_mask) {
6413                 case ELINK_GP_STATUS_10M:
6414                         vars->line_speed = ELINK_SPEED_10;
6415                         if (is_duplex == DUPLEX_FULL)
6416                                 vars->link_status |= ELINK_LINK_10TFD;
6417                         else
6418                                 vars->link_status |= ELINK_LINK_10THD;
6419                         break;
6420
6421                 case ELINK_GP_STATUS_100M:
6422                         vars->line_speed = ELINK_SPEED_100;
6423                         if (is_duplex == DUPLEX_FULL)
6424                                 vars->link_status |= ELINK_LINK_100TXFD;
6425                         else
6426                                 vars->link_status |= ELINK_LINK_100TXHD;
6427                         break;
6428
6429                 case ELINK_GP_STATUS_1G:
6430                 case ELINK_GP_STATUS_1G_KX:
6431                         vars->line_speed = ELINK_SPEED_1000;
6432                         if (is_duplex == DUPLEX_FULL)
6433                                 vars->link_status |= ELINK_LINK_1000TFD;
6434                         else
6435                                 vars->link_status |= ELINK_LINK_1000THD;
6436                         break;
6437
6438                 case ELINK_GP_STATUS_2_5G:
6439                         vars->line_speed = ELINK_SPEED_2500;
6440                         if (is_duplex == DUPLEX_FULL)
6441                                 vars->link_status |= ELINK_LINK_2500TFD;
6442                         else
6443                                 vars->link_status |= ELINK_LINK_2500THD;
6444                         break;
6445
6446                 case ELINK_GP_STATUS_5G:
6447                 case ELINK_GP_STATUS_6G:
6448                         ELINK_DEBUG_P1(sc,
6449                                  "link speed unsupported  gp_status 0x%x",
6450                                   speed_mask);
6451                         return ELINK_STATUS_ERROR;
6452
6453                 case ELINK_GP_STATUS_10G_KX4:
6454                 case ELINK_GP_STATUS_10G_HIG:
6455                 case ELINK_GP_STATUS_10G_CX4:
6456                 case ELINK_GP_STATUS_10G_KR:
6457                 case ELINK_GP_STATUS_10G_SFI:
6458                 case ELINK_GP_STATUS_10G_XFI:
6459                         vars->line_speed = ELINK_SPEED_10000;
6460                         vars->link_status |= ELINK_LINK_10GTFD;
6461                         break;
6462                 case ELINK_GP_STATUS_20G_DXGXS:
6463                 case ELINK_GP_STATUS_20G_KR2:
6464                         vars->line_speed = ELINK_SPEED_20000;
6465                         vars->link_status |= ELINK_LINK_20GTFD;
6466                         break;
6467                 default:
6468                         ELINK_DEBUG_P1(sc,
6469                                   "link speed unsupported gp_status 0x%x",
6470                                   speed_mask);
6471                         return ELINK_STATUS_ERROR;
6472                 }
6473         } else { /* link_down */
6474                 ELINK_DEBUG_P0(sc, "phy link down");
6475
6476                 vars->phy_link_up = 0;
6477
6478                 vars->duplex = DUPLEX_FULL;
6479                 vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
6480                 vars->mac_type = ELINK_MAC_TYPE_NONE;
6481         }
6482         ELINK_DEBUG_P2(sc, " in elink_get_link_speed_duplex vars->link_status = %x, vars->duplex = %x",
6483                         vars->link_status, vars->duplex);
6484         ELINK_DEBUG_P2(sc, " phy_link_up %x line_speed %d",
6485                     vars->phy_link_up, vars->line_speed);
6486         return ELINK_STATUS_OK;
6487 }
6488
6489 static uint8_t elink_link_settings_status(struct elink_phy *phy,
6490                                       struct elink_params *params,
6491                                       struct elink_vars *vars)
6492 {
6493         struct bnx2x_softc *sc = params->sc;
6494
6495         uint16_t gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
6496         elink_status_t rc = ELINK_STATUS_OK;
6497
6498         /* Read gp_status */
6499         CL22_RD_OVER_CL45(sc, phy,
6500                           MDIO_REG_BANK_GP_STATUS,
6501                           MDIO_GP_STATUS_TOP_AN_STATUS1,
6502                           &gp_status);
6503         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS) {
6504                 duplex = DUPLEX_FULL;
6505                 ELINK_DEBUG_P1(sc, "duplex status read from phy is = %x",
6506                                 duplex);
6507         } else {
6508                 ELINK_DEBUG_P1(sc, "phy status does not allow interface to be FULL_DUPLEX : %x",
6509                         gp_status);
6510         }
6511
6512
6513         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
6514                 link_up = 1;
6515         speed_mask = gp_status & ELINK_GP_STATUS_SPEED_MASK;
6516         ELINK_DEBUG_P3(sc, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x",
6517                        gp_status, link_up, speed_mask);
6518         rc = elink_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
6519                                          duplex);
6520         if (rc == ELINK_STATUS_ERROR)
6521                 return rc;
6522
6523         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
6524                 if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
6525                         vars->duplex = duplex;
6526                         elink_flow_ctrl_resolve(phy, params, vars, gp_status);
6527                         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6528                                 elink_xgxs_an_resolve(phy, params, vars,
6529                                                       gp_status);
6530                 }
6531         } else { /* Link_down */
6532                 if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
6533                     ELINK_SINGLE_MEDIA_DIRECT(params)) {
6534                         /* Check signal is detected */
6535                         elink_check_fallback_to_cl37(phy, params);
6536                 }
6537         }
6538
6539         /* Read LP advertised speeds*/
6540         if (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6541             (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)) {
6542                 uint16_t val;
6543
6544                 CL22_RD_OVER_CL45(sc, phy, MDIO_REG_BANK_CL73_IEEEB1,
6545                                   MDIO_CL73_IEEEB1_AN_LP_ADV2, &val);
6546
6547                 if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
6548                         vars->link_status |=
6549                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
6550                 if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
6551                            MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
6552                         vars->link_status |=
6553                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6554
6555                 CL22_RD_OVER_CL45(sc, phy, MDIO_REG_BANK_OVER_1G,
6556                                   MDIO_OVER_1G_LP_UP1, &val);
6557
6558                 if (val & MDIO_OVER_1G_UP1_2_5G)
6559                         vars->link_status |=
6560                                 LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
6561                 if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
6562                         vars->link_status |=
6563                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6564         }
6565
6566         ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x",
6567                    vars->duplex, vars->flow_ctrl, vars->link_status);
6568         return rc;
6569 }
6570
6571 static uint8_t elink_warpcore_read_status(struct elink_phy *phy,
6572                                      struct elink_params *params,
6573                                      struct elink_vars *vars)
6574 {
6575         struct bnx2x_softc *sc = params->sc;
6576         uint8_t lane;
6577         uint16_t gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
6578         elink_status_t rc = ELINK_STATUS_OK;
6579         lane = elink_get_warpcore_lane(phy, params);
6580         /* Read gp_status */
6581         if ((params->loopback_mode) &&
6582             (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)) {
6583                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6584                                 MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up);
6585                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6586                                 MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up);
6587                 link_up &= 0x1;
6588                 ELINK_DEBUG_P1(sc, "params->loopback_mode link_up read = %x",
6589                                 link_up);
6590         } else if ((phy->req_line_speed > ELINK_SPEED_10000) &&
6591                 (phy->supported & ELINK_SUPPORTED_20000baseMLD2_Full)) {
6592                 uint16_t temp_link_up;
6593                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6594                                 1, &temp_link_up);
6595                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6596                                 1, &link_up);
6597                 ELINK_DEBUG_P2(sc, "PCS RX link status = 0x%x-->0x%x",
6598                                temp_link_up, link_up);
6599                 link_up &= (1 << 2);
6600                 if (link_up)
6601                         elink_ext_phy_resolve_fc(phy, params, vars);
6602         } else {
6603                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6604                                 MDIO_WC_REG_GP2_STATUS_GP_2_1,
6605                                 &gp_status1);
6606                 ELINK_DEBUG_P1(sc, "0x81d1 = 0x%x", gp_status1);
6607                 /* Check for either KR, 1G, or AN up. */
6608                 link_up = ((gp_status1 >> 8) |
6609                            (gp_status1 >> 12) |
6610                            (gp_status1)) &
6611                         (1 << lane);
6612                 if (phy->supported & ELINK_SUPPORTED_20000baseKR2_Full) {
6613                         uint16_t an_link;
6614                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6615                                         MDIO_AN_REG_STATUS, &an_link);
6616                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6617                                         MDIO_AN_REG_STATUS, &an_link);
6618                         link_up |= (an_link & (1 << 2));
6619                         ELINK_DEBUG_P2(sc, "an_link = %x, link_up = %x",
6620                                         an_link, link_up);
6621                 }
6622                 if (link_up && ELINK_SINGLE_MEDIA_DIRECT(params)) {
6623                         uint16_t pd, gp_status4;
6624                         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
6625                                 /* Check Autoneg complete */
6626                                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6627                                                 MDIO_WC_REG_GP2_STATUS_GP_2_4,
6628                                                 &gp_status4);
6629                                 if (gp_status4 & ((1 << 12) << lane))
6630                                         vars->link_status |=
6631                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6632
6633                                 /* Check parallel detect used */
6634                                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6635                                                 MDIO_WC_REG_PAR_DET_10G_STATUS,
6636                                                 &pd);
6637                                 if (pd & (1 << 15))
6638                                         vars->link_status |=
6639                                         LINK_STATUS_PARALLEL_DETECTION_USED;
6640                                 ELINK_DEBUG_P2(sc, "pd = %x, link_status = %x",
6641                                                 pd, vars->link_status);
6642                         }
6643                         elink_ext_phy_resolve_fc(phy, params, vars);
6644                         vars->duplex = duplex;
6645                         ELINK_DEBUG_P3(sc, " ELINK_SINGLE_MEDIA_DIRECT duplex %x  flow_ctrl 0x%x link_status 0x%x",
6646                                         vars->duplex, vars->flow_ctrl,
6647                                         vars->link_status);
6648                 }
6649         }
6650         ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x",
6651                         vars->duplex, vars->flow_ctrl, vars->link_status);
6652         if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) &&
6653             ELINK_SINGLE_MEDIA_DIRECT(params)) {
6654                 uint16_t val;
6655
6656                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6657                                 MDIO_AN_REG_LP_AUTO_NEG2, &val);
6658
6659                 if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
6660                         vars->link_status |=
6661                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
6662                 if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
6663                            MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
6664                         vars->link_status |=
6665                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6666                 ELINK_DEBUG_P2(sc, "val = %x, link_status = %x",
6667                                 val, vars->link_status);
6668                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6669                                 MDIO_WC_REG_DIGITAL3_LP_UP1, &val);
6670
6671                 if (val & MDIO_OVER_1G_UP1_2_5G)
6672                         vars->link_status |=
6673                                 LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
6674                 if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
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
6680         }
6681
6682
6683         if (lane < 2) {
6684                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6685                                 MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
6686         } else {
6687                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6688                                 MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
6689         }
6690         ELINK_DEBUG_P2(sc, "lane %d gp_speed 0x%x", lane, gp_speed);
6691
6692         if ((lane & 1) == 0)
6693                 gp_speed <<= 8;
6694         gp_speed &= 0x3f00;
6695         link_up = !!link_up;
6696
6697         /* Reset the TX FIFO to fix SGMII issue */
6698         rc = elink_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
6699                                          duplex);
6700
6701         /* In case of KR link down, start up the recovering procedure */
6702         if ((!link_up) && (phy->media_type == ELINK_ETH_PHY_KR) &&
6703             (!(phy->flags & ELINK_FLAGS_WC_DUAL_MODE)))
6704                 vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
6705
6706         ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x",
6707                    vars->duplex, vars->flow_ctrl, vars->link_status);
6708         return rc;
6709 }
6710 static void elink_set_gmii_tx_driver(struct elink_params *params)
6711 {
6712         struct bnx2x_softc *sc = params->sc;
6713         struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
6714         uint16_t lp_up2;
6715         uint16_t tx_driver;
6716         uint16_t bank;
6717
6718         /* Read precomp */
6719         CL22_RD_OVER_CL45(sc, phy,
6720                           MDIO_REG_BANK_OVER_1G,
6721                           MDIO_OVER_1G_LP_UP2, &lp_up2);
6722
6723         /* Bits [10:7] at lp_up2, positioned at [15:12] */
6724         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
6725                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
6726                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
6727
6728         if (lp_up2 == 0)
6729                 return;
6730
6731         for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
6732               bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
6733                 CL22_RD_OVER_CL45(sc, phy,
6734                                   bank,
6735                                   MDIO_TX0_TX_DRIVER, &tx_driver);
6736
6737                 /* Replace tx_driver bits [15:12] */
6738                 if (lp_up2 !=
6739                     (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
6740                         tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
6741                         tx_driver |= lp_up2;
6742                         CL22_WR_OVER_CL45(sc, phy,
6743                                           bank,
6744                                           MDIO_TX0_TX_DRIVER, tx_driver);
6745                 }
6746         }
6747 }
6748
6749 static elink_status_t elink_emac_program(struct elink_params *params,
6750                               struct elink_vars *vars)
6751 {
6752         struct bnx2x_softc *sc = params->sc;
6753         uint8_t port = params->port;
6754         uint16_t mode = 0;
6755
6756         ELINK_DEBUG_P0(sc, "setting link speed & duplex");
6757         elink_bits_dis(sc, GRCBASE_EMAC0 + port * 0x400 +
6758                        EMAC_REG_EMAC_MODE,
6759                        (EMAC_MODE_25G_MODE |
6760                         EMAC_MODE_PORT_MII_10M |
6761                         EMAC_MODE_HALF_DUPLEX));
6762         switch (vars->line_speed) {
6763         case ELINK_SPEED_10:
6764                 mode |= EMAC_MODE_PORT_MII_10M;
6765                 break;
6766
6767         case ELINK_SPEED_100:
6768                 mode |= EMAC_MODE_PORT_MII;
6769                 break;
6770
6771         case ELINK_SPEED_1000:
6772                 mode |= EMAC_MODE_PORT_GMII;
6773                 break;
6774
6775         case ELINK_SPEED_2500:
6776                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
6777                 break;
6778
6779         default:
6780                 /* 10G not valid for EMAC */
6781                 ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x",
6782                            vars->line_speed);
6783                 return ELINK_STATUS_ERROR;
6784         }
6785
6786         if (vars->duplex == DUPLEX_HALF)
6787                 mode |= EMAC_MODE_HALF_DUPLEX;
6788         elink_bits_en(sc,
6789                       GRCBASE_EMAC0 + port * 0x400 + EMAC_REG_EMAC_MODE,
6790                       mode);
6791
6792         elink_set_led(params, vars, ELINK_LED_MODE_OPER, vars->line_speed);
6793         return ELINK_STATUS_OK;
6794 }
6795
6796 static void elink_set_preemphasis(struct elink_phy *phy,
6797                                   struct elink_params *params)
6798 {
6799
6800         uint16_t bank, i = 0;
6801         struct bnx2x_softc *sc = params->sc;
6802
6803         for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
6804              bank += (MDIO_REG_BANK_RX1 - MDIO_REG_BANK_RX0), i++) {
6805                 CL22_WR_OVER_CL45(sc, phy,
6806                                   bank,
6807                                   MDIO_RX0_RX_EQ_BOOST,
6808                                   phy->rx_preemphasis[i]);
6809         }
6810
6811         for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
6812              bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
6813                 CL22_WR_OVER_CL45(sc, phy,
6814                                   bank,
6815                                   MDIO_TX0_TX_DRIVER,
6816                                   phy->tx_preemphasis[i]);
6817         }
6818 }
6819
6820 static uint8_t elink_xgxs_config_init(struct elink_phy *phy,
6821                                    struct elink_params *params,
6822                                    struct elink_vars *vars)
6823 {
6824         struct bnx2x_softc *sc = params->sc;
6825         uint8_t enable_cl73 = (ELINK_SINGLE_MEDIA_DIRECT(params) ||
6826                           (params->loopback_mode == ELINK_LOOPBACK_XGXS));
6827         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
6828                 if (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6829                     (params->feature_config_flags &
6830                      ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
6831                         elink_set_preemphasis(phy, params);
6832
6833                 /* Forced speed requested? */
6834                 if (vars->line_speed != ELINK_SPEED_AUTO_NEG ||
6835                     (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6836                      params->loopback_mode == ELINK_LOOPBACK_EXT)) {
6837                         ELINK_DEBUG_P0(sc, "not SGMII, no AN");
6838
6839                         /* Disable autoneg */
6840                         elink_set_autoneg(phy, params, vars, 0);
6841
6842                         /* Program speed and duplex */
6843                         elink_program_serdes(phy, params, vars);
6844
6845                 } else { /* AN_mode */
6846                         ELINK_DEBUG_P0(sc, "not SGMII, AN");
6847
6848                         /* AN enabled */
6849                         elink_set_brcm_cl37_advertisement(phy, params);
6850
6851                         /* Program duplex & pause advertisement (for aneg) */
6852                         elink_set_ieee_aneg_advertisement(phy, params,
6853                                                           vars->ieee_fc);
6854
6855                         /* Enable autoneg */
6856                         elink_set_autoneg(phy, params, vars, enable_cl73);
6857
6858                         /* Enable and restart AN */
6859                         elink_restart_autoneg(phy, params, enable_cl73);
6860                 }
6861
6862         } else { /* SGMII mode */
6863                 ELINK_DEBUG_P0(sc, "SGMII");
6864
6865                 elink_initialize_sgmii_process(phy, params, vars);
6866         }
6867
6868         return 0;
6869 }
6870
6871 static elink_status_t elink_prepare_xgxs(struct elink_phy *phy,
6872                           struct elink_params *params,
6873                           struct elink_vars *vars)
6874 {
6875         elink_status_t rc;
6876         vars->phy_flags |= PHY_XGXS_FLAG;
6877         if ((phy->req_line_speed &&
6878              ((phy->req_line_speed == ELINK_SPEED_100) ||
6879               (phy->req_line_speed == ELINK_SPEED_10))) ||
6880             (!phy->req_line_speed &&
6881              (phy->speed_cap_mask >=
6882               PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
6883              (phy->speed_cap_mask <
6884               PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
6885             (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD))
6886                 vars->phy_flags |= PHY_SGMII_FLAG;
6887         else
6888                 vars->phy_flags &= ~PHY_SGMII_FLAG;
6889
6890         elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
6891         elink_set_aer_mmd(params, phy);
6892         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
6893                 elink_set_master_ln(params, phy);
6894
6895         rc = elink_reset_unicore(params, phy, 0);
6896         /* Reset the SerDes and wait for reset bit return low */
6897         if (rc != ELINK_STATUS_OK)
6898                 return rc;
6899
6900         elink_set_aer_mmd(params, phy);
6901         /* Setting the masterLn_def again after the reset */
6902         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
6903                 elink_set_master_ln(params, phy);
6904                 elink_set_swap_lanes(params, phy);
6905         }
6906
6907         return rc;
6908 }
6909
6910 static uint16_t elink_wait_reset_complete(struct bnx2x_softc *sc,
6911                                      struct elink_phy *phy,
6912                                      struct elink_params *params)
6913 {
6914         uint16_t cnt, ctrl;
6915         /* Wait for soft reset to get cleared up to 1 sec */
6916         for (cnt = 0; cnt < 1000; cnt++) {
6917                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE)
6918                         elink_cl22_read(sc, phy,
6919                                 MDIO_PMA_REG_CTRL, &ctrl);
6920                 else
6921                         elink_cl45_read(sc, phy,
6922                                 MDIO_PMA_DEVAD,
6923                                 MDIO_PMA_REG_CTRL, &ctrl);
6924                 if (!(ctrl & (1 << 15)))
6925                         break;
6926                 DELAY(1000 * 1);
6927         }
6928
6929         if (cnt == 1000)
6930                 elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED,
6931                                    params->port);
6932                                      /* "Warning: PHY was not initialized,"
6933                                       * " Port %d",
6934                                       */
6935
6936         ELINK_DEBUG_P2(sc, "control reg 0x%x (after %d ms)", ctrl, cnt);
6937         return cnt;
6938 }
6939
6940 static void elink_link_int_enable(struct elink_params *params)
6941 {
6942         uint8_t port = params->port;
6943         uint32_t mask;
6944         struct bnx2x_softc *sc = params->sc;
6945
6946         /* Setting the status to report on link up for either XGXS or SerDes */
6947         if (CHIP_IS_E3(sc)) {
6948                 mask = ELINK_NIG_MASK_XGXS0_LINK_STATUS;
6949                 if (!(ELINK_SINGLE_MEDIA_DIRECT(params)))
6950                         mask |= ELINK_NIG_MASK_MI_INT;
6951         } else if (params->switch_cfg == ELINK_SWITCH_CFG_10G) {
6952                 mask = (ELINK_NIG_MASK_XGXS0_LINK10G |
6953                         ELINK_NIG_MASK_XGXS0_LINK_STATUS);
6954                 ELINK_DEBUG_P0(sc, "enabled XGXS interrupt");
6955                 if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) &&
6956                         params->phy[ELINK_INT_PHY].type !=
6957                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
6958                         mask |= ELINK_NIG_MASK_MI_INT;
6959                         ELINK_DEBUG_P0(sc, "enabled external phy int");
6960                 }
6961
6962         } else { /* SerDes */
6963                 mask = ELINK_NIG_MASK_SERDES0_LINK_STATUS;
6964                 ELINK_DEBUG_P0(sc, "enabled SerDes interrupt");
6965                 if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) &&
6966                         params->phy[ELINK_INT_PHY].type !=
6967                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
6968                         mask |= ELINK_NIG_MASK_MI_INT;
6969                         ELINK_DEBUG_P0(sc, "enabled external phy int");
6970                 }
6971         }
6972         elink_bits_en(sc,
6973                       NIG_REG_MASK_INTERRUPT_PORT0 + port * 4,
6974                       mask);
6975
6976         ELINK_DEBUG_P3(sc, "port %x, is_xgxs %x, int_status 0x%x", port,
6977                  (params->switch_cfg == ELINK_SWITCH_CFG_10G),
6978                  REG_RD(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port * 4));
6979         ELINK_DEBUG_P3(sc, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x",
6980                  REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port * 4),
6981                  REG_RD(sc, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port * 0x18),
6982                  REG_RD(sc, NIG_REG_SERDES0_STATUS_LINK_STATUS + port * 0x3c));
6983         ELINK_DEBUG_P2(sc, " 10G %x, XGXS_LINK %x",
6984            REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK10G + port * 0x68),
6985            REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK_STATUS + port * 0x68));
6986 }
6987
6988 static void elink_rearm_latch_signal(struct bnx2x_softc *sc, uint8_t port,
6989                                      uint8_t exp_mi_int)
6990 {
6991         uint32_t latch_status = 0;
6992
6993         /* Disable the MI INT ( external phy int ) by writing 1 to the
6994          * status register. Link down indication is high-active-signal,
6995          * so in this case we need to write the status to clear the XOR
6996          */
6997         /* Read Latched signals */
6998         latch_status = REG_RD(sc,
6999                                     NIG_REG_LATCH_STATUS_0 + port * 8);
7000         ELINK_DEBUG_P1(sc, "latch_status = 0x%x", latch_status);
7001         /* Handle only those with latched-signal=up.*/
7002         if (exp_mi_int)
7003                 elink_bits_en(sc,
7004                               NIG_REG_STATUS_INTERRUPT_PORT0
7005                               + port * 4,
7006                               ELINK_NIG_STATUS_EMAC0_MI_INT);
7007         else
7008                 elink_bits_dis(sc,
7009                                NIG_REG_STATUS_INTERRUPT_PORT0
7010                                + port * 4,
7011                                ELINK_NIG_STATUS_EMAC0_MI_INT);
7012
7013         if (latch_status & 1) {
7014
7015                 /* For all latched-signal=up : Re-Arm Latch signals */
7016                 REG_WR(sc, NIG_REG_LATCH_STATUS_0 + port * 8,
7017                        (latch_status & 0xfffe) | (latch_status & 1));
7018         }
7019         /* For all latched-signal=up,Write original_signal to status */
7020 }
7021
7022 static void elink_link_int_ack(struct elink_params *params,
7023                                struct elink_vars *vars, uint8_t is_10g_plus)
7024 {
7025         struct bnx2x_softc *sc = params->sc;
7026         uint8_t port = params->port;
7027         uint32_t mask;
7028         /* First reset all status we assume only one line will be
7029          * change at a time
7030          */
7031         elink_bits_dis(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port * 4,
7032                        (ELINK_NIG_STATUS_XGXS0_LINK10G |
7033                         ELINK_NIG_STATUS_XGXS0_LINK_STATUS |
7034                         ELINK_NIG_STATUS_SERDES0_LINK_STATUS));
7035         if (vars->phy_link_up) {
7036                 if (USES_WARPCORE(sc))
7037                         mask = ELINK_NIG_STATUS_XGXS0_LINK_STATUS;
7038                 else {
7039                         if (is_10g_plus)
7040                                 mask = ELINK_NIG_STATUS_XGXS0_LINK10G;
7041                         else if (params->switch_cfg == ELINK_SWITCH_CFG_10G) {
7042                                 /* Disable the link interrupt by writing 1 to
7043                                  * the relevant lane in the status register
7044                                  */
7045                                 uint32_t ser_lane =
7046                                         ((params->lane_config &
7047                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
7048                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
7049                                 mask = ((1 << ser_lane) <<
7050                                        ELINK_NIG_STATUS_XGXS0_LINK_STATUS_SIZE);
7051                         } else
7052                                 mask = ELINK_NIG_STATUS_SERDES0_LINK_STATUS;
7053                 }
7054                 ELINK_DEBUG_P1(sc, "Ack link up interrupt with mask 0x%x",
7055                                mask);
7056                 elink_bits_en(sc,
7057                               NIG_REG_STATUS_INTERRUPT_PORT0 + port * 4,
7058                               mask);
7059         }
7060 }
7061
7062 static elink_status_t elink_format_ver(uint32_t num, uint8_t *str,
7063                                        uint16_t *len)
7064 {
7065         uint8_t *str_ptr = str;
7066         uint32_t mask = 0xf0000000;
7067         uint8_t shift = 8 * 4;
7068         uint8_t digit;
7069         uint8_t remove_leading_zeros = 1;
7070         if (*len < 10) {
7071                 /* Need more than 10chars for this format */
7072                 *str_ptr = '\0';
7073                 (*len)--;
7074                 return ELINK_STATUS_ERROR;
7075         }
7076         while (shift > 0) {
7077
7078                 shift -= 4;
7079                 digit = ((num & mask) >> shift);
7080                 if (digit == 0 && remove_leading_zeros) {
7081                         mask = mask >> 4;
7082                         continue;
7083                 } else if (digit < 0xa)
7084                         *str_ptr = digit + '0';
7085                 else
7086                         *str_ptr = digit - 0xa + 'a';
7087                 remove_leading_zeros = 0;
7088                 str_ptr++;
7089                 (*len)--;
7090                 mask = mask >> 4;
7091                 if (shift == 4 * 4) {
7092                         *str_ptr = '.';
7093                         str_ptr++;
7094                         (*len)--;
7095                         remove_leading_zeros = 1;
7096                 }
7097         }
7098         return ELINK_STATUS_OK;
7099 }
7100
7101
7102 static elink_status_t elink_null_format_ver(__rte_unused uint32_t spirom_ver,
7103                                  uint8_t *str,
7104                                  uint16_t *len)
7105 {
7106         str[0] = '\0';
7107         (*len)--;
7108         return ELINK_STATUS_OK;
7109 }
7110
7111 elink_status_t elink_get_ext_phy_fw_version(struct elink_params *params,
7112                                  uint8_t *version,
7113                                  uint16_t len)
7114 {
7115         struct bnx2x_softc *sc;
7116         uint32_t spirom_ver = 0;
7117         elink_status_t status = ELINK_STATUS_OK;
7118         uint8_t *ver_p = version;
7119         uint16_t remain_len = len;
7120         if (version == NULL || params == NULL)
7121                 return ELINK_STATUS_ERROR;
7122         sc = params->sc;
7123
7124         /* Extract first external phy*/
7125         version[0] = '\0';
7126         spirom_ver = REG_RD(sc, params->phy[ELINK_EXT_PHY1].ver_addr);
7127
7128         if (params->phy[ELINK_EXT_PHY1].format_fw_ver) {
7129                 status |= params->phy[ELINK_EXT_PHY1].format_fw_ver(spirom_ver,
7130                                                               ver_p,
7131                                                               &remain_len);
7132                 ver_p += (len - remain_len);
7133         }
7134         if ((params->num_phys == ELINK_MAX_PHYS) &&
7135             (params->phy[ELINK_EXT_PHY2].ver_addr != 0)) {
7136                 spirom_ver = REG_RD(sc, params->phy[ELINK_EXT_PHY2].ver_addr);
7137                 if (params->phy[ELINK_EXT_PHY2].format_fw_ver) {
7138                         *ver_p = '/';
7139                         ver_p++;
7140                         remain_len--;
7141                         status |= params->phy[ELINK_EXT_PHY2].format_fw_ver(
7142                                 spirom_ver,
7143                                 ver_p,
7144                                 &remain_len);
7145                         ver_p = version + (len - remain_len);
7146                 }
7147         }
7148         *ver_p = '\0';
7149         return status;
7150 }
7151
7152 static void elink_set_xgxs_loopback(struct elink_phy *phy,
7153                                     struct elink_params *params)
7154 {
7155         uint8_t port = params->port;
7156         struct bnx2x_softc *sc = params->sc;
7157
7158         if (phy->req_line_speed != ELINK_SPEED_1000) {
7159                 uint32_t md_devad = 0;
7160
7161                 ELINK_DEBUG_P0(sc, "XGXS 10G loopback enable");
7162
7163                 if (!CHIP_IS_E3(sc)) {
7164                         /* Change the uni_phy_addr in the nig */
7165                         md_devad = REG_RD(sc, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
7166                                                port * 0x18));
7167
7168                         REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + port * 0x18,
7169                                0x5);
7170                 }
7171
7172                 elink_cl45_write(sc, phy,
7173                                  5,
7174                                  (MDIO_REG_BANK_AER_BLOCK +
7175                                   (MDIO_AER_BLOCK_AER_REG & 0xf)),
7176                                  0x2800);
7177
7178                 elink_cl45_write(sc, phy,
7179                                  5,
7180                                  (MDIO_REG_BANK_CL73_IEEEB0 +
7181                                   (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
7182                                  0x6041);
7183                 DELAY(1000 * 200);
7184                 /* Set aer mmd back */
7185                 elink_set_aer_mmd(params, phy);
7186
7187                 if (!CHIP_IS_E3(sc)) {
7188                         /* And md_devad */
7189                         REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + port * 0x18,
7190                                md_devad);
7191                 }
7192         } else {
7193                 uint16_t mii_ctrl;
7194                 ELINK_DEBUG_P0(sc, "XGXS 1G loopback enable");
7195                 elink_cl45_read(sc, phy, 5,
7196                                 (MDIO_REG_BANK_COMBO_IEEE0 +
7197                                 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
7198                                 &mii_ctrl);
7199                 elink_cl45_write(sc, phy, 5,
7200                                  (MDIO_REG_BANK_COMBO_IEEE0 +
7201                                  (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
7202                                  mii_ctrl |
7203                                  MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
7204         }
7205 }
7206
7207 elink_status_t elink_set_led(struct elink_params *params,
7208                   struct elink_vars *vars, uint8_t mode, uint32_t speed)
7209 {
7210         uint8_t port = params->port;
7211         uint16_t hw_led_mode = params->hw_led_mode;
7212         elink_status_t rc = ELINK_STATUS_OK;
7213         uint8_t phy_idx;
7214         uint32_t tmp;
7215         uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
7216         struct bnx2x_softc *sc = params->sc;
7217         ELINK_DEBUG_P2(sc, "elink_set_led: port %x, mode %d", port, mode);
7218         ELINK_DEBUG_P2(sc, "speed 0x%x, hw_led_mode 0x%x",
7219                  speed, hw_led_mode);
7220         /* In case */
7221         for (phy_idx = ELINK_EXT_PHY1; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
7222                 if (params->phy[phy_idx].set_link_led) {
7223                         params->phy[phy_idx].set_link_led(
7224                                 &params->phy[phy_idx], params, mode);
7225                 }
7226         }
7227 #ifdef ELINK_INCLUDE_EMUL
7228         if (params->feature_config_flags &
7229             ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC)
7230                 return rc;
7231 #endif
7232
7233         switch (mode) {
7234         case ELINK_LED_MODE_FRONT_PANEL_OFF:
7235         case ELINK_LED_MODE_OFF:
7236                 REG_WR(sc, NIG_REG_LED_10G_P0 + port * 4, 0);
7237                 REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4,
7238                        SHARED_HW_CFG_LED_MAC1);
7239
7240                 tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7241                 if (params->phy[ELINK_EXT_PHY1].type ==
7242                         PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE)
7243                         tmp &= ~(EMAC_LED_1000MB_OVERRIDE |
7244                                 EMAC_LED_100MB_OVERRIDE |
7245                                 EMAC_LED_10MB_OVERRIDE);
7246                 else
7247                         tmp |= EMAC_LED_OVERRIDE;
7248
7249                 elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED, tmp);
7250                 break;
7251
7252         case ELINK_LED_MODE_OPER:
7253                 /* For all other phys, OPER mode is same as ON, so in case
7254                  * link is down, do nothing
7255                  */
7256                 if (!vars->link_up)
7257                         break;
7258                 /* fallthrough */
7259         case ELINK_LED_MODE_ON:
7260                 if (((params->phy[ELINK_EXT_PHY1].type ==
7261                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727) ||
7262                          (params->phy[ELINK_EXT_PHY1].type ==
7263                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722)) &&
7264                     CHIP_IS_E2(sc) && params->num_phys == 2) {
7265                         /* This is a work-around for E2 + 8727 Configurations */
7266                         if (mode == ELINK_LED_MODE_ON ||
7267                                 speed == ELINK_SPEED_10000){
7268                                 REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4, 0);
7269                                 REG_WR(sc, NIG_REG_LED_10G_P0 + port * 4, 1);
7270
7271                                 tmp = elink_cb_reg_read(sc, emac_base +
7272                                                         EMAC_REG_EMAC_LED);
7273                                 elink_cb_reg_write(sc, emac_base +
7274                                                    EMAC_REG_EMAC_LED,
7275                                                    (tmp | EMAC_LED_OVERRIDE));
7276                                 /* Return here without enabling traffic
7277                                  * LED blink and setting rate in ON mode.
7278                                  * In oper mode, enabling LED blink
7279                                  * and setting rate is needed.
7280                                  */
7281                                 if (mode == ELINK_LED_MODE_ON)
7282                                         return rc;
7283                         }
7284                 } else if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
7285                         /* This is a work-around for HW issue found when link
7286                          * is up in CL73
7287                          */
7288                         if ((!CHIP_IS_E3(sc)) ||
7289                             (CHIP_IS_E3(sc) &&
7290                              mode == ELINK_LED_MODE_ON))
7291                                 REG_WR(sc, NIG_REG_LED_10G_P0 + port * 4, 1);
7292
7293                         if (CHIP_IS_E1x(sc) ||
7294                             CHIP_IS_E2(sc) ||
7295                             (mode == ELINK_LED_MODE_ON))
7296                                 REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4, 0);
7297                         else
7298                                 REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4,
7299                                        hw_led_mode);
7300                 } else if ((params->phy[ELINK_EXT_PHY1].type ==
7301                             PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE) &&
7302                            (mode == ELINK_LED_MODE_ON)) {
7303                         REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4, 0);
7304                         tmp = elink_cb_reg_read(sc, emac_base +
7305                                                 EMAC_REG_EMAC_LED);
7306                         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED,
7307                                            tmp | EMAC_LED_OVERRIDE |
7308                                            EMAC_LED_1000MB_OVERRIDE);
7309                         /* Break here; otherwise, it'll disable the
7310                          * intended override.
7311                          */
7312                         break;
7313                 } else {
7314                         uint32_t nig_led_mode = ((params->hw_led_mode <<
7315                                              SHARED_HW_CFG_LED_MODE_SHIFT) ==
7316                                             SHARED_HW_CFG_LED_EXTPHY2) ?
7317                                 (SHARED_HW_CFG_LED_PHY1 >>
7318                                  SHARED_HW_CFG_LED_MODE_SHIFT) : hw_led_mode;
7319                         REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4,
7320                                nig_led_mode);
7321                 }
7322
7323                 REG_WR(sc, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port * 4,
7324                        0);
7325                 /* Set blinking rate to ~15.9Hz */
7326                 if (CHIP_IS_E3(sc))
7327                         REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port * 4,
7328                                LED_BLINK_RATE_VAL_E3);
7329                 else
7330                         REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port * 4,
7331                                LED_BLINK_RATE_VAL_E1X_E2);
7332                 REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
7333                        port * 4, 1);
7334                 tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7335                 elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED,
7336                         (tmp & (~EMAC_LED_OVERRIDE)));
7337
7338                 if (CHIP_IS_E1(sc) &&
7339                     ((speed == ELINK_SPEED_2500) ||
7340                      (speed == ELINK_SPEED_1000) ||
7341                      (speed == ELINK_SPEED_100) ||
7342                      (speed == ELINK_SPEED_10))) {
7343                         /* For speeds less than 10G LED scheme is different */
7344                         REG_WR(sc, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
7345                                + port * 4, 1);
7346                         REG_WR(sc, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
7347                                port * 4, 0);
7348                         REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
7349                                port * 4, 1);
7350                 }
7351                 break;
7352
7353         default:
7354                 rc = ELINK_STATUS_ERROR;
7355                 ELINK_DEBUG_P1(sc, "elink_set_led: Invalid led mode %d",
7356                          mode);
7357                 break;
7358         }
7359         return rc;
7360
7361 }
7362
7363 /* This function comes to reflect the actual link state read DIRECTLY from the
7364  * HW
7365  */
7366 elink_status_t elink_test_link(struct elink_params *params,
7367                                __rte_unused struct elink_vars *vars,
7368                     uint8_t is_serdes)
7369 {
7370         struct bnx2x_softc *sc = params->sc;
7371         uint16_t gp_status = 0, phy_index = 0;
7372         uint8_t ext_phy_link_up = 0, serdes_phy_type;
7373         struct elink_vars temp_vars;
7374         struct elink_phy *int_phy = &params->phy[ELINK_INT_PHY];
7375 #ifdef ELINK_INCLUDE_FPGA
7376         if (CHIP_REV_IS_FPGA(sc))
7377                 return ELINK_STATUS_OK;
7378 #endif
7379 #ifdef ELINK_INCLUDE_EMUL
7380         if (CHIP_REV_IS_EMUL(sc))
7381                 return ELINK_STATUS_OK;
7382 #endif
7383
7384         if (CHIP_IS_E3(sc)) {
7385                 uint16_t link_up;
7386                 if (params->req_line_speed[ELINK_LINK_CONFIG_IDX(ELINK_INT_PHY)]
7387                     > ELINK_SPEED_10000) {
7388                         /* Check 20G link */
7389                         elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7390                                         1, &link_up);
7391                         elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7392                                         1, &link_up);
7393                         link_up &= (1 << 2);
7394                 } else {
7395                         /* Check 10G link and below*/
7396                         uint8_t lane = elink_get_warpcore_lane(int_phy, params);
7397                         elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7398                                         MDIO_WC_REG_GP2_STATUS_GP_2_1,
7399                                         &gp_status);
7400                         gp_status = ((gp_status >> 8) & 0xf) |
7401                                 ((gp_status >> 12) & 0xf);
7402                         link_up = gp_status & (1 << lane);
7403                 }
7404                 if (!link_up)
7405                         return ELINK_STATUS_NO_LINK;
7406         } else {
7407                 CL22_RD_OVER_CL45(sc, int_phy,
7408                           MDIO_REG_BANK_GP_STATUS,
7409                           MDIO_GP_STATUS_TOP_AN_STATUS1,
7410                           &gp_status);
7411         /* Link is up only if both local phy and external phy are up */
7412         if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
7413                 return ELINK_STATUS_NO_LINK;
7414         }
7415         /* In XGXS loopback mode, do not check external PHY */
7416         if (params->loopback_mode == ELINK_LOOPBACK_XGXS)
7417                 return ELINK_STATUS_OK;
7418
7419         switch (params->num_phys) {
7420         case 1:
7421                 /* No external PHY */
7422                 return ELINK_STATUS_OK;
7423         case 2:
7424                 ext_phy_link_up = params->phy[ELINK_EXT_PHY1].read_status(
7425                         &params->phy[ELINK_EXT_PHY1],
7426                         params, &temp_vars);
7427                 break;
7428         case 3: /* Dual Media */
7429                 for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7430                       phy_index++) {
7431                         serdes_phy_type = ((params->phy[phy_index].media_type ==
7432                                             ELINK_ETH_PHY_SFPP_10G_FIBER) ||
7433                                            (params->phy[phy_index].media_type ==
7434                                             ELINK_ETH_PHY_SFP_1G_FIBER) ||
7435                                            (params->phy[phy_index].media_type ==
7436                                             ELINK_ETH_PHY_XFP_FIBER) ||
7437                                            (params->phy[phy_index].media_type ==
7438                                             ELINK_ETH_PHY_DA_TWINAX));
7439
7440                         if (is_serdes != serdes_phy_type)
7441                                 continue;
7442                         if (params->phy[phy_index].read_status) {
7443                                 ext_phy_link_up |=
7444                                         params->phy[phy_index].read_status(
7445                                                 &params->phy[phy_index],
7446                                                 params, &temp_vars);
7447                         }
7448                 }
7449                 break;
7450         }
7451         if (ext_phy_link_up)
7452                 return ELINK_STATUS_OK;
7453         return ELINK_STATUS_NO_LINK;
7454 }
7455
7456 static elink_status_t elink_link_initialize(struct elink_params *params,
7457                                  struct elink_vars *vars)
7458 {
7459         uint8_t phy_index, non_ext_phy;
7460         struct bnx2x_softc *sc = params->sc;
7461         /* In case of external phy existence, the line speed would be the
7462          * line speed linked up by the external phy. In case it is direct
7463          * only, then the line_speed during initialization will be
7464          * equal to the req_line_speed
7465          */
7466         vars->line_speed = params->phy[ELINK_INT_PHY].req_line_speed;
7467
7468         /* Initialize the internal phy in case this is a direct board
7469          * (no external phys), or this board has external phy which requires
7470          * to first.
7471          */
7472         if (!USES_WARPCORE(sc))
7473                 elink_prepare_xgxs(&params->phy[ELINK_INT_PHY], params, vars);
7474         /* init ext phy and enable link state int */
7475         non_ext_phy = (ELINK_SINGLE_MEDIA_DIRECT(params) ||
7476                        (params->loopback_mode == ELINK_LOOPBACK_XGXS));
7477
7478         if (non_ext_phy ||
7479             (params->phy[ELINK_EXT_PHY1].flags & ELINK_FLAGS_INIT_XGXS_FIRST) ||
7480             (params->loopback_mode == ELINK_LOOPBACK_EXT_PHY)) {
7481                 struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
7482                 if (vars->line_speed == ELINK_SPEED_AUTO_NEG &&
7483                     (CHIP_IS_E1x(sc) ||
7484                      CHIP_IS_E2(sc)))
7485                         elink_set_parallel_detection(phy, params);
7486                 if (params->phy[ELINK_INT_PHY].config_init)
7487                         params->phy[ELINK_INT_PHY].config_init(phy, params,
7488                                                                vars);
7489         }
7490
7491         /* Re-read this value in case it was changed inside config_init due to
7492          * limitations of optic module
7493          */
7494         vars->line_speed = params->phy[ELINK_INT_PHY].req_line_speed;
7495
7496         /* Init external phy*/
7497         if (non_ext_phy) {
7498                 if (params->phy[ELINK_INT_PHY].supported &
7499                     ELINK_SUPPORTED_FIBRE)
7500                         vars->link_status |= LINK_STATUS_SERDES_LINK;
7501         } else {
7502                 for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7503                       phy_index++) {
7504                         /* No need to initialize second phy in case of first
7505                          * phy only selection. In case of second phy, we do
7506                          * need to initialize the first phy, since they are
7507                          * connected.
7508                          */
7509                         if (params->phy[phy_index].supported &
7510                             ELINK_SUPPORTED_FIBRE)
7511                                 vars->link_status |= LINK_STATUS_SERDES_LINK;
7512
7513                         if (phy_index == ELINK_EXT_PHY2 &&
7514                             (elink_phy_selection(params) ==
7515                              PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
7516                                 ELINK_DEBUG_P0(sc,
7517                                    "Not initializing second phy");
7518                                 continue;
7519                         }
7520                         params->phy[phy_index].config_init(
7521                                 &params->phy[phy_index],
7522                                 params, vars);
7523                 }
7524         }
7525         /* Reset the interrupt indication after phy was initialized */
7526         elink_bits_dis(sc, NIG_REG_STATUS_INTERRUPT_PORT0 +
7527                        params->port * 4,
7528                        (ELINK_NIG_STATUS_XGXS0_LINK10G |
7529                         ELINK_NIG_STATUS_XGXS0_LINK_STATUS |
7530                         ELINK_NIG_STATUS_SERDES0_LINK_STATUS |
7531                         ELINK_NIG_MASK_MI_INT));
7532         return ELINK_STATUS_OK;
7533 }
7534
7535 static void elink_int_link_reset(__rte_unused struct elink_phy *phy,
7536                                  struct elink_params *params)
7537 {
7538         /* Reset the SerDes/XGXS */
7539         REG_WR(params->sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
7540                (0x1ff << (params->port * 16)));
7541 }
7542
7543 static void elink_common_ext_link_reset(__rte_unused struct elink_phy *phy,
7544                                         struct elink_params *params)
7545 {
7546         struct bnx2x_softc *sc = params->sc;
7547         uint8_t gpio_port;
7548         /* HW reset */
7549         if (CHIP_IS_E2(sc))
7550                 gpio_port = SC_PATH(sc);
7551         else
7552                 gpio_port = params->port;
7553         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
7554                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
7555                        gpio_port);
7556         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
7557                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
7558                        gpio_port);
7559         ELINK_DEBUG_P0(sc, "reset external PHY");
7560 }
7561
7562 static elink_status_t elink_update_link_down(struct elink_params *params,
7563                                   struct elink_vars *vars)
7564 {
7565         struct bnx2x_softc *sc = params->sc;
7566         uint8_t port = params->port;
7567
7568         ELINK_DEBUG_P1(sc, "Port %x: Link is down", port);
7569         elink_set_led(params, vars, ELINK_LED_MODE_OFF, 0);
7570         vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG;
7571         /* Indicate no mac active */
7572         vars->mac_type = ELINK_MAC_TYPE_NONE;
7573
7574         /* Update shared memory */
7575         vars->link_status &= ~ELINK_LINK_UPDATE_MASK;
7576         vars->line_speed = 0;
7577         elink_update_mng(params, vars->link_status);
7578
7579         /* Activate nig drain */
7580         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port * 4, 1);
7581
7582         /* Disable emac */
7583         if (!CHIP_IS_E3(sc))
7584                 REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port * 4, 0);
7585
7586         DELAY(1000 * 10);
7587         /* Reset BigMac/Xmac */
7588         if (CHIP_IS_E1x(sc) ||
7589             CHIP_IS_E2(sc))
7590                 elink_set_bmac_rx(sc, params->chip_id, params->port, 0);
7591
7592         if (CHIP_IS_E3(sc)) {
7593                 /* Prevent LPI Generation by chip */
7594                 REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2),
7595                        0);
7596                 REG_WR(sc, MISC_REG_CPMU_LP_MASK_ENT_P0 + (params->port << 2),
7597                        0);
7598                 vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
7599                                       SHMEM_EEE_ACTIVE_BIT);
7600
7601                 elink_update_mng_eee(params, vars->eee_status);
7602                 elink_set_xmac_rxtx(params, 0);
7603                 elink_set_umac_rxtx(params, 0);
7604         }
7605
7606         return ELINK_STATUS_OK;
7607 }
7608
7609 static elink_status_t elink_update_link_up(struct elink_params *params,
7610                                 struct elink_vars *vars,
7611                                 uint8_t link_10g)
7612 {
7613         struct bnx2x_softc *sc = params->sc;
7614         uint8_t phy_idx, port = params->port;
7615         elink_status_t rc = ELINK_STATUS_OK;
7616
7617         vars->link_status |= (LINK_STATUS_LINK_UP |
7618                               LINK_STATUS_PHYSICAL_LINK_FLAG);
7619         vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
7620
7621         if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
7622                 vars->link_status |=
7623                         LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
7624
7625         if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
7626                 vars->link_status |=
7627                         LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
7628         if (USES_WARPCORE(sc)) {
7629                 if (link_10g) {
7630                         if (elink_xmac_enable(params, vars, 0) ==
7631                             ELINK_STATUS_NO_LINK) {
7632                                 ELINK_DEBUG_P0(sc, "Found errors on XMAC");
7633                                 vars->link_up = 0;
7634                                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
7635                                 vars->link_status &= ~LINK_STATUS_LINK_UP;
7636                         }
7637                 } else
7638                         elink_umac_enable(params, vars, 0);
7639                 elink_set_led(params, vars,
7640                               ELINK_LED_MODE_OPER, vars->line_speed);
7641
7642                 if ((vars->eee_status & SHMEM_EEE_ACTIVE_BIT) &&
7643                     (vars->eee_status & SHMEM_EEE_LPI_REQUESTED_BIT)) {
7644                         ELINK_DEBUG_P0(sc, "Enabling LPI assertion");
7645                         REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 +
7646                                (params->port << 2), 1);
7647                         REG_WR(sc, MISC_REG_CPMU_LP_DR_ENABLE, 1);
7648                         REG_WR(sc, MISC_REG_CPMU_LP_MASK_ENT_P0 +
7649                                (params->port << 2), 0xfc20);
7650                 }
7651         }
7652         if ((CHIP_IS_E1x(sc) ||
7653              CHIP_IS_E2(sc))) {
7654                 if (link_10g) {
7655                         if (elink_bmac_enable(params, vars, 0, 1) ==
7656                             ELINK_STATUS_NO_LINK) {
7657                                 ELINK_DEBUG_P0(sc, "Found errors on BMAC");
7658                                 vars->link_up = 0;
7659                                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
7660                                 vars->link_status &= ~LINK_STATUS_LINK_UP;
7661                         }
7662
7663                         elink_set_led(params, vars,
7664                                       ELINK_LED_MODE_OPER, ELINK_SPEED_10000);
7665                 } else {
7666                         rc = elink_emac_program(params, vars);
7667                         elink_emac_enable(params, vars, 0);
7668
7669                         /* AN complete? */
7670                         if ((vars->link_status &
7671                              LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
7672                             && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
7673                             ELINK_SINGLE_MEDIA_DIRECT(params))
7674                                 elink_set_gmii_tx_driver(params);
7675                 }
7676         }
7677
7678         /* PBF - link up */
7679         if (CHIP_IS_E1x(sc))
7680                 rc |= elink_pbf_update(params, vars->flow_ctrl,
7681                                        vars->line_speed);
7682
7683         /* Disable drain */
7684         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port * 4, 0);
7685
7686         /* Update shared memory */
7687         elink_update_mng(params, vars->link_status);
7688         elink_update_mng_eee(params, vars->eee_status);
7689         /* Check remote fault */
7690         for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
7691                 if (params->phy[phy_idx].flags & ELINK_FLAGS_TX_ERROR_CHECK) {
7692                         elink_check_half_open_conn(params, vars, 0);
7693                         break;
7694                 }
7695         }
7696         DELAY(1000 * 20);
7697         return rc;
7698 }
7699
7700 static void elink_chng_link_count(struct elink_params *params, uint8_t clear)
7701 {
7702         struct bnx2x_softc *sc = params->sc;
7703         uint32_t addr, val;
7704
7705         /* Verify the link_change_count is supported by the MFW */
7706         if (!(SHMEM2_HAS(sc, link_change_count)))
7707                 return;
7708
7709         addr = params->shmem2_base +
7710                 offsetof(struct shmem2_region, link_change_count[params->port]);
7711         if (clear)
7712                 val = 0;
7713         else
7714                 val = REG_RD(sc, addr) + 1;
7715         REG_WR(sc, addr, val);
7716 }
7717
7718 /* The elink_link_update function should be called upon link
7719  * interrupt.
7720  * Link is considered up as follows:
7721  * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
7722  *   to be up
7723  * - SINGLE_MEDIA - The link between the 577xx and the external
7724  *   phy (XGXS) need to up as well as the external link of the
7725  *   phy (PHY_EXT1)
7726  * - DUAL_MEDIA - The link between the 577xx and the first
7727  *   external phy needs to be up, and at least one of the 2
7728  *   external phy link must be up.
7729  */
7730 elink_status_t elink_link_update(struct elink_params *params,
7731                                  struct elink_vars *vars)
7732 {
7733         struct bnx2x_softc *sc = params->sc;
7734         struct elink_vars phy_vars[ELINK_MAX_PHYS];
7735         uint8_t port = params->port;
7736         uint8_t link_10g_plus, phy_index;
7737         uint32_t prev_link_status = vars->link_status;
7738         uint8_t ext_phy_link_up = 0, cur_link_up;
7739         elink_status_t rc = ELINK_STATUS_OK;
7740         uint16_t ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
7741         uint8_t active_external_phy = ELINK_INT_PHY;
7742         vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
7743         vars->link_status &= ~ELINK_LINK_UPDATE_MASK;
7744         for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
7745               phy_index++) {
7746                 phy_vars[phy_index].flow_ctrl = 0;
7747                 phy_vars[phy_index].link_status = 0;
7748                 phy_vars[phy_index].line_speed = 0;
7749                 phy_vars[phy_index].duplex = DUPLEX_FULL;
7750                 phy_vars[phy_index].phy_link_up = 0;
7751                 phy_vars[phy_index].link_up = 0;
7752                 phy_vars[phy_index].fault_detected = 0;
7753                 /* different consideration, since vars holds inner state */
7754                 phy_vars[phy_index].eee_status = vars->eee_status;
7755         }
7756
7757         if (USES_WARPCORE(sc))
7758                 elink_set_aer_mmd(params, &params->phy[ELINK_INT_PHY]);
7759
7760         ELINK_DEBUG_P3(sc, "port %x, XGXS?%x, int_status 0x%x",
7761                  port, (vars->phy_flags & PHY_XGXS_FLAG),
7762                  REG_RD(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port * 4));
7763
7764         ELINK_DEBUG_P3(sc, "int_mask 0x%x MI_INT %x, SERDES_LINK %x",
7765                  REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port * 4),
7766                  REG_RD(sc, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port * 0x18) > 0,
7767                  REG_RD(sc, NIG_REG_SERDES0_STATUS_LINK_STATUS + port * 0x3c));
7768
7769         ELINK_DEBUG_P2(sc, " 10G %x, XGXS_LINK %x",
7770           REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK10G + port * 0x68),
7771           REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK_STATUS + port * 0x68));
7772
7773         /* Disable emac */
7774         if (!CHIP_IS_E3(sc))
7775                 REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port * 4, 0);
7776
7777         /* Step 1:
7778          * Check external link change only for external phys, and apply
7779          * priority selection between them in case the link on both phys
7780          * is up. Note that instead of the common vars, a temporary
7781          * vars argument is used since each phy may have different link/
7782          * speed/duplex result
7783          */
7784         for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7785               phy_index++) {
7786                 struct elink_phy *phy = &params->phy[phy_index];
7787                 if (!phy->read_status)
7788                         continue;
7789                 /* Read link status and params of this ext phy */
7790                 cur_link_up = phy->read_status(phy, params,
7791                                                &phy_vars[phy_index]);
7792                 if (cur_link_up) {
7793                         ELINK_DEBUG_P1(sc, "phy in index %d link is up",
7794                                    phy_index);
7795                 } else {
7796                         ELINK_DEBUG_P1(sc, "phy in index %d link is down",
7797                                    phy_index);
7798                         continue;
7799                 }
7800
7801                 if (!ext_phy_link_up) {
7802                         ext_phy_link_up = 1;
7803                         active_external_phy = phy_index;
7804                 } else {
7805                         switch (elink_phy_selection(params)) {
7806                         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
7807                         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
7808                         /* In this option, the first PHY makes sure to pass the
7809                          * traffic through itself only.
7810                          * Its not clear how to reset the link on the second phy
7811                          */
7812                                 active_external_phy = ELINK_EXT_PHY1;
7813                                 break;
7814                         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
7815                         /* In this option, the first PHY makes sure to pass the
7816                          * traffic through the second PHY.
7817                          */
7818                                 active_external_phy = ELINK_EXT_PHY2;
7819                                 break;
7820                         default:
7821                         /* Link indication on both PHYs with the following cases
7822                          * is invalid:
7823                          * - FIRST_PHY means that second phy wasn't initialized,
7824                          * hence its link is expected to be down
7825                          * - SECOND_PHY means that first phy should not be able
7826                          * to link up by itself (using configuration)
7827                          * - DEFAULT should be overridden during initialiazation
7828                          */
7829                                 ELINK_DEBUG_P1(sc, "Invalid link indication"
7830                                                " mpc=0x%x. DISABLING LINK !!!",
7831                                            params->multi_phy_config);
7832                                 ext_phy_link_up = 0;
7833                                 break;
7834                         }
7835                 }
7836         }
7837         prev_line_speed = vars->line_speed;
7838         /* Step 2:
7839          * Read the status of the internal phy. In case of
7840          * DIRECT_SINGLE_MEDIA board, this link is the external link,
7841          * otherwise this is the link between the 577xx and the first
7842          * external phy
7843          */
7844         if (params->phy[ELINK_INT_PHY].read_status)
7845                 params->phy[ELINK_INT_PHY].read_status(
7846                         &params->phy[ELINK_INT_PHY],
7847                         params, vars);
7848         /* The INT_PHY flow control reside in the vars. This include the
7849          * case where the speed or flow control are not set to AUTO.
7850          * Otherwise, the active external phy flow control result is set
7851          * to the vars. The ext_phy_line_speed is needed to check if the
7852          * speed is different between the internal phy and external phy.
7853          * This case may be result of intermediate link speed change.
7854          */
7855         if (active_external_phy > ELINK_INT_PHY) {
7856                 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
7857                 /* Link speed is taken from the XGXS. AN and FC result from
7858                  * the external phy.
7859                  */
7860                 vars->link_status |= phy_vars[active_external_phy].link_status;
7861
7862                 /* if active_external_phy is first PHY and link is up - disable
7863                  * disable TX on second external PHY
7864                  */
7865                 if (active_external_phy == ELINK_EXT_PHY1) {
7866                         if (params->phy[ELINK_EXT_PHY2].phy_specific_func) {
7867                                 ELINK_DEBUG_P0(sc,
7868                                    "Disabling TX on EXT_PHY2");
7869                                 params->phy[ELINK_EXT_PHY2].phy_specific_func(
7870                                         &params->phy[ELINK_EXT_PHY2],
7871                                         params, ELINK_DISABLE_TX);
7872                         }
7873                 }
7874
7875                 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
7876                 vars->duplex = phy_vars[active_external_phy].duplex;
7877                 if (params->phy[active_external_phy].supported &
7878                     ELINK_SUPPORTED_FIBRE)
7879                         vars->link_status |= LINK_STATUS_SERDES_LINK;
7880                 else
7881                         vars->link_status &= ~LINK_STATUS_SERDES_LINK;
7882
7883                 vars->eee_status = phy_vars[active_external_phy].eee_status;
7884
7885                 ELINK_DEBUG_P1(sc, "Active external phy selected: %x",
7886                            active_external_phy);
7887         }
7888
7889         ELINK_DEBUG_P3(sc, "vars : phy_flags = %x, mac_type = %x, phy_link_up = %x",
7890                        vars->phy_flags, vars->mac_type, vars->phy_link_up);
7891         ELINK_DEBUG_P3(sc, "vars : link_up = %x, line_speed = %x, duplex = %x",
7892                        vars->link_up, vars->line_speed, vars->duplex);
7893         ELINK_DEBUG_P3(sc, "vars : flow_ctrl = %x, ieee_fc = %x, link_status = %x",
7894                        vars->flow_ctrl, vars->ieee_fc, vars->link_status);
7895         ELINK_DEBUG_P3(sc, "vars : eee_status = %x, fault_detected = %x, check_kr2_recovery_cnt = %x",
7896                        vars->eee_status, vars->fault_detected,
7897                        vars->check_kr2_recovery_cnt);
7898         ELINK_DEBUG_P3(sc, "vars : periodic_flags = %x, aeu_int_mask = %x, rx_tx_asic_rst = %x",
7899                        vars->periodic_flags, vars->aeu_int_mask,
7900                        vars->rx_tx_asic_rst);
7901         ELINK_DEBUG_P2(sc, "vars : turn_to_run_wc_rt = %x, rsrv2 = %x",
7902                        vars->turn_to_run_wc_rt, vars->rsrv2);
7903
7904         for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7905               phy_index++) {
7906                 if (params->phy[phy_index].flags &
7907                     ELINK_FLAGS_REARM_LATCH_SIGNAL) {
7908                         elink_rearm_latch_signal(sc, port,
7909                                                  phy_index ==
7910                                                  active_external_phy);
7911                         break;
7912                 }
7913         }
7914         ELINK_DEBUG_P3(sc, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
7915                    " ext_phy_line_speed = %d", vars->flow_ctrl,
7916                    vars->link_status, ext_phy_line_speed);
7917         /* Upon link speed change set the NIG into drain mode. Comes to
7918          * deals with possible FIFO glitch due to clk change when speed
7919          * is decreased without link down indicator
7920          */
7921
7922         if (vars->phy_link_up) {
7923                 if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
7924                     (ext_phy_line_speed != vars->line_speed)) {
7925                         ELINK_DEBUG_P2(sc, "Internal link speed %d is"
7926                                    " different than the external"
7927                                    " link speed %d", vars->line_speed,
7928                                    ext_phy_line_speed);
7929                         vars->phy_link_up = 0;
7930                         ELINK_DEBUG_P0(sc, "phy_link_up set to 0");
7931                 } else if (prev_line_speed != vars->line_speed) {
7932                         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE +
7933                                params->port * 4, 0);
7934                         DELAY(1000 * 1);
7935                 }
7936         }
7937
7938         /* Anything 10 and over uses the bmac */
7939         link_10g_plus = (vars->line_speed >= ELINK_SPEED_10000);
7940
7941         elink_link_int_ack(params, vars, link_10g_plus);
7942
7943         /* In case external phy link is up, and internal link is down
7944          * (not initialized yet probably after link initialization, it
7945          * needs to be initialized.
7946          * Note that after link down-up as result of cable plug, the xgxs
7947          * link would probably become up again without the need
7948          * initialize it
7949          */
7950         if (!(ELINK_SINGLE_MEDIA_DIRECT(params))) {
7951                 ELINK_DEBUG_P3(sc, "ext_phy_link_up = %d, int_link_up = %d,"
7952                            " init_preceding = %d", ext_phy_link_up,
7953                            vars->phy_link_up,
7954                            params->phy[ELINK_EXT_PHY1].flags &
7955                            ELINK_FLAGS_INIT_XGXS_FIRST);
7956                 if (!(params->phy[ELINK_EXT_PHY1].flags &
7957                       ELINK_FLAGS_INIT_XGXS_FIRST)
7958                     && ext_phy_link_up && !vars->phy_link_up) {
7959                         vars->line_speed = ext_phy_line_speed;
7960                         if (vars->line_speed < ELINK_SPEED_1000)
7961                                 vars->phy_flags |= PHY_SGMII_FLAG;
7962                         else
7963                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
7964
7965                         if (params->phy[ELINK_INT_PHY].config_init)
7966                                 params->phy[ELINK_INT_PHY].config_init(
7967                                         &params->phy[ELINK_INT_PHY], params,
7968                                                 vars);
7969                 }
7970         }
7971         /* Link is up only if both local phy and external phy (in case of
7972          * non-direct board) are up and no fault detected on active PHY.
7973          */
7974         vars->link_up = (vars->phy_link_up &&
7975                          (ext_phy_link_up ||
7976                           ELINK_SINGLE_MEDIA_DIRECT(params)) &&
7977                          (phy_vars[active_external_phy].fault_detected == 0));
7978
7979         if (vars->link_up)
7980                 ELINK_DEBUG_P0(sc, "local phy and external phy are up");
7981         else
7982                 ELINK_DEBUG_P0(sc, "either local phy or external phy or both are down");
7983
7984         /* Update the PFC configuration in case it was changed */
7985         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
7986                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
7987         else
7988                 vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
7989
7990         if (vars->link_up)
7991                 rc = elink_update_link_up(params, vars, link_10g_plus);
7992         else
7993                 rc = elink_update_link_down(params, vars);
7994
7995         if ((prev_link_status ^ vars->link_status) & LINK_STATUS_LINK_UP)
7996                 elink_chng_link_count(params, 0);
7997
7998         /* Update MCP link status was changed */
7999         if (params->feature_config_flags &
8000             ELINK_FEATURE_CONFIG_BC_SUPPORTS_AFEX)
8001                 elink_cb_fw_command(sc, DRV_MSG_CODE_LINK_STATUS_CHANGED, 0);
8002
8003         return rc;
8004 }
8005
8006 /*****************************************************************************/
8007 /*                          External Phy section                             */
8008 /*****************************************************************************/
8009 void elink_ext_phy_hw_reset(struct bnx2x_softc *sc, uint8_t port)
8010 {
8011         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
8012                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
8013         DELAY(1000 * 1);
8014         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
8015                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
8016 }
8017
8018 static void elink_save_spirom_version(struct bnx2x_softc *sc, uint8_t port,
8019                                       uint32_t spirom_ver, uint32_t ver_addr)
8020 {
8021         ELINK_DEBUG_P3(sc, "FW version 0x%x:0x%x for port %d",
8022                  (uint16_t)(spirom_ver >> 16), (uint16_t)spirom_ver, port);
8023
8024         if (ver_addr)
8025                 REG_WR(sc, ver_addr, spirom_ver);
8026 }
8027
8028 static void elink_save_bnx2x_spirom_ver(struct bnx2x_softc *sc,
8029                                       struct elink_phy *phy,
8030                                       uint8_t port)
8031 {
8032         uint16_t fw_ver1, fw_ver2;
8033
8034         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
8035                         MDIO_PMA_REG_ROM_VER1, &fw_ver1);
8036         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
8037                         MDIO_PMA_REG_ROM_VER2, &fw_ver2);
8038         elink_save_spirom_version(sc, port, (uint32_t)(fw_ver1 << 16 | fw_ver2),
8039                                   phy->ver_addr);
8040 }
8041
8042 static void elink_ext_phy_10G_an_resolve(struct bnx2x_softc *sc,
8043                                        struct elink_phy *phy,
8044                                        struct elink_vars *vars)
8045 {
8046         uint16_t val;
8047         elink_cl45_read(sc, phy,
8048                         MDIO_AN_DEVAD,
8049                         MDIO_AN_REG_STATUS, &val);
8050         elink_cl45_read(sc, phy,
8051                         MDIO_AN_DEVAD,
8052                         MDIO_AN_REG_STATUS, &val);
8053         if (val & (1 << 5))
8054                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
8055         if ((val & (1 << 0)) == 0)
8056                 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
8057 }
8058
8059 /******************************************************************/
8060 /*              common BNX2X8073/BNX2X8727 PHY SECTION            */
8061 /******************************************************************/
8062 static void elink_8073_resolve_fc(struct elink_phy *phy,
8063                                   struct elink_params *params,
8064                                   struct elink_vars *vars)
8065 {
8066         struct bnx2x_softc *sc = params->sc;
8067         if (phy->req_line_speed == ELINK_SPEED_10 ||
8068             phy->req_line_speed == ELINK_SPEED_100) {
8069                 vars->flow_ctrl = phy->req_flow_ctrl;
8070                 return;
8071         }
8072
8073         if (elink_ext_phy_resolve_fc(phy, params, vars) &&
8074             (vars->flow_ctrl == ELINK_FLOW_CTRL_NONE)) {
8075                 uint16_t pause_result;
8076                 uint16_t ld_pause;              /* local */
8077                 uint16_t lp_pause;              /* link partner */
8078                 elink_cl45_read(sc, phy,
8079                                 MDIO_AN_DEVAD,
8080                                 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
8081
8082                 elink_cl45_read(sc, phy,
8083                                 MDIO_AN_DEVAD,
8084                                 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
8085                 pause_result = (ld_pause &
8086                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
8087                 pause_result |= (lp_pause &
8088                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
8089
8090                 elink_pause_resolve(phy, params, vars, pause_result);
8091                 ELINK_DEBUG_P1(sc, "Ext PHY CL37 pause result 0x%x",
8092                            pause_result);
8093         }
8094 }
8095 static elink_status_t elink_8073_8727_external_rom_boot(struct bnx2x_softc *sc,
8096                                              struct elink_phy *phy,
8097                                              uint8_t port)
8098 {
8099         uint32_t count = 0;
8100         uint16_t fw_ver1 = 0, fw_msgout;
8101         elink_status_t rc = ELINK_STATUS_OK;
8102
8103         /* Boot port from external ROM  */
8104         /* EDC grst */
8105         elink_cl45_write(sc, phy,
8106                          MDIO_PMA_DEVAD,
8107                          MDIO_PMA_REG_GEN_CTRL,
8108                          0x0001);
8109
8110         /* Ucode reboot and rst */
8111         elink_cl45_write(sc, phy,
8112                          MDIO_PMA_DEVAD,
8113                          MDIO_PMA_REG_GEN_CTRL,
8114                          0x008c);
8115
8116         elink_cl45_write(sc, phy,
8117                          MDIO_PMA_DEVAD,
8118                          MDIO_PMA_REG_MISC_CTRL1, 0x0001);
8119
8120         /* Reset internal microprocessor */
8121         elink_cl45_write(sc, phy,
8122                          MDIO_PMA_DEVAD,
8123                          MDIO_PMA_REG_GEN_CTRL,
8124                          MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
8125
8126         /* Release srst bit */
8127         elink_cl45_write(sc, phy,
8128                          MDIO_PMA_DEVAD,
8129                          MDIO_PMA_REG_GEN_CTRL,
8130                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
8131
8132         /* Delay 100ms per the PHY specifications */
8133         DELAY(1000 * 100);
8134
8135         /* 8073 sometimes taking longer to download */
8136         do {
8137                 count++;
8138                 if (count > 300) {
8139                         ELINK_DEBUG_P2(sc,
8140                                  "elink_8073_8727_external_rom_boot port %x:"
8141                                  "Download failed. fw version = 0x%x",
8142                                  port, fw_ver1);
8143                         rc = ELINK_STATUS_ERROR;
8144                         break;
8145                 }
8146
8147                 elink_cl45_read(sc, phy,
8148                                 MDIO_PMA_DEVAD,
8149                                 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
8150                 elink_cl45_read(sc, phy,
8151                                 MDIO_PMA_DEVAD,
8152                                 MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
8153
8154                 DELAY(1000 * 1);
8155         } while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
8156                         ((fw_msgout & 0xff) != 0x03 && (phy->type ==
8157                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8073)));
8158
8159         /* Clear ser_boot_ctl bit */
8160         elink_cl45_write(sc, phy,
8161                          MDIO_PMA_DEVAD,
8162                          MDIO_PMA_REG_MISC_CTRL1, 0x0000);
8163         elink_save_bnx2x_spirom_ver(sc, phy, port);
8164
8165         ELINK_DEBUG_P2(sc,
8166                  "elink_8073_8727_external_rom_boot port %x:"
8167                  "Download complete. fw version = 0x%x",
8168                  port, fw_ver1);
8169
8170         return rc;
8171 }
8172
8173 /******************************************************************/
8174 /*                      BNX2X8073 PHY SECTION                     */
8175 /******************************************************************/
8176 static elink_status_t elink_8073_is_snr_needed(struct bnx2x_softc *sc,
8177                                                struct elink_phy *phy)
8178 {
8179         /* This is only required for 8073A1, version 102 only */
8180         uint16_t val;
8181
8182         /* Read 8073 HW revision*/
8183         elink_cl45_read(sc, phy,
8184                         MDIO_PMA_DEVAD,
8185                         MDIO_PMA_REG_8073_CHIP_REV, &val);
8186
8187         if (val != 1) {
8188                 /* No need to workaround in 8073 A1 */
8189                 return ELINK_STATUS_OK;
8190         }
8191
8192         elink_cl45_read(sc, phy,
8193                         MDIO_PMA_DEVAD,
8194                         MDIO_PMA_REG_ROM_VER2, &val);
8195
8196         /* SNR should be applied only for version 0x102 */
8197         if (val != 0x102)
8198                 return ELINK_STATUS_OK;
8199
8200         return 1;
8201 }
8202
8203 static elink_status_t elink_8073_xaui_wa(struct bnx2x_softc *sc,
8204                                          struct elink_phy *phy)
8205 {
8206         uint16_t val, cnt, cnt1;
8207
8208         elink_cl45_read(sc, phy,
8209                         MDIO_PMA_DEVAD,
8210                         MDIO_PMA_REG_8073_CHIP_REV, &val);
8211
8212         if (val > 0) {
8213                 /* No need to workaround in 8073 A1 */
8214                 return ELINK_STATUS_OK;
8215         }
8216         /* XAUI workaround in 8073 A0: */
8217
8218         /* After loading the boot ROM and restarting Autoneg, poll
8219          * Dev1, Reg $C820:
8220          */
8221
8222         for (cnt = 0; cnt < 1000; cnt++) {
8223                 elink_cl45_read(sc, phy,
8224                                 MDIO_PMA_DEVAD,
8225                                 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
8226                                 &val);
8227                   /* If bit [14] = 0 or bit [13] = 0, continue on with
8228                    * system initialization (XAUI work-around not required, as
8229                    * these bits indicate 2.5G or 1G link up).
8230                    */
8231                 if (!(val & (1 << 14)) || !(val & (1 << 13))) {
8232                         ELINK_DEBUG_P0(sc, "XAUI work-around not required");
8233                         return ELINK_STATUS_OK;
8234                 } else if (!(val & (1 << 15))) {
8235                         ELINK_DEBUG_P0(sc, "bit 15 went off");
8236                         /* If bit 15 is 0, then poll Dev1, Reg $C841 until it's
8237                          * MSB (bit15) goes to 1 (indicating that the XAUI
8238                          * workaround has completed), then continue on with
8239                          * system initialization.
8240                          */
8241                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
8242                                 elink_cl45_read(sc, phy,
8243                                         MDIO_PMA_DEVAD,
8244                                         MDIO_PMA_REG_8073_XAUI_WA, &val);
8245                                 if (val & (1 << 15)) {
8246                                         ELINK_DEBUG_P0(sc,
8247                                           "XAUI workaround has completed");
8248                                         return ELINK_STATUS_OK;
8249                                 }
8250                                 DELAY(1000 * 3);
8251                         }
8252                         break;
8253                 }
8254                 DELAY(1000 * 3);
8255         }
8256         ELINK_DEBUG_P0(sc, "Warning: XAUI work-around timeout !!!");
8257         return ELINK_STATUS_ERROR;
8258 }
8259
8260 static void elink_807x_force_10G(struct bnx2x_softc *sc, struct elink_phy *phy)
8261 {
8262         /* Force KR or KX */
8263         elink_cl45_write(sc, phy,
8264                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
8265         elink_cl45_write(sc, phy,
8266                          MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
8267         elink_cl45_write(sc, phy,
8268                          MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
8269         elink_cl45_write(sc, phy,
8270                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
8271 }
8272
8273 static void elink_8073_set_pause_cl37(struct elink_params *params,
8274                                       struct elink_phy *phy,
8275                                       struct elink_vars *vars)
8276 {
8277         uint16_t cl37_val;
8278         struct bnx2x_softc *sc = params->sc;
8279         elink_cl45_read(sc, phy,
8280                         MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
8281
8282         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
8283         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
8284         elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
8285         if ((vars->ieee_fc &
8286             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
8287             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
8288                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
8289         }
8290         if ((vars->ieee_fc &
8291             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
8292             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
8293                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
8294         }
8295         if ((vars->ieee_fc &
8296             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
8297             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
8298                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
8299         }
8300         ELINK_DEBUG_P1(sc,
8301                  "Ext phy AN advertize cl37 0x%x", cl37_val);
8302
8303         elink_cl45_write(sc, phy,
8304                          MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
8305         DELAY(1000 * 500);
8306 }
8307
8308 static void elink_8073_specific_func(struct elink_phy *phy,
8309                                      struct elink_params *params,
8310                                      uint32_t action)
8311 {
8312         struct bnx2x_softc *sc = params->sc;
8313         switch (action) {
8314         case ELINK_PHY_INIT:
8315                 /* Enable LASI */
8316                 elink_cl45_write(sc, phy,
8317                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8318                                  (1 << 2));
8319                 elink_cl45_write(sc, phy,
8320                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,  0x0004);
8321                 break;
8322         }
8323 }
8324
8325 static uint8_t elink_8073_config_init(struct elink_phy *phy,
8326                                   struct elink_params *params,
8327                                   struct elink_vars *vars)
8328 {
8329         struct bnx2x_softc *sc = params->sc;
8330         uint16_t val = 0, tmp1;
8331         uint8_t gpio_port;
8332         ELINK_DEBUG_P0(sc, "Init 8073");
8333
8334         if (CHIP_IS_E2(sc))
8335                 gpio_port = SC_PATH(sc);
8336         else
8337                 gpio_port = params->port;
8338         /* Restore normal power mode*/
8339         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8340                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
8341
8342         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
8343                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
8344
8345         elink_8073_specific_func(phy, params, ELINK_PHY_INIT);
8346         elink_8073_set_pause_cl37(params, phy, vars);
8347
8348         elink_cl45_read(sc, phy,
8349                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
8350
8351         elink_cl45_read(sc, phy,
8352                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
8353
8354         ELINK_DEBUG_P1(sc, "Before rom RX_ALARM(port1): 0x%x", tmp1);
8355
8356         /* Swap polarity if required - Must be done only in non-1G mode */
8357         if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
8358                 /* Configure the 8073 to swap _P and _N of the KR lines */
8359                 ELINK_DEBUG_P0(sc, "Swapping polarity for the 8073");
8360                 /* 10G Rx/Tx and 1G Tx signal polarity swap */
8361                 elink_cl45_read(sc, phy,
8362                                 MDIO_PMA_DEVAD,
8363                                 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
8364                 elink_cl45_write(sc, phy,
8365                                  MDIO_PMA_DEVAD,
8366                                  MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
8367                                  (val | (3 << 9)));
8368         }
8369
8370
8371         /* Enable CL37 BAM */
8372         if (REG_RD(sc, params->shmem_base +
8373                          offsetof(struct shmem_region, dev_info.
8374                                   port_hw_config[params->port].default_cfg)) &
8375             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
8376
8377                 elink_cl45_read(sc, phy,
8378                                 MDIO_AN_DEVAD,
8379                                 MDIO_AN_REG_8073_BAM, &val);
8380                 elink_cl45_write(sc, phy,
8381                                  MDIO_AN_DEVAD,
8382                                  MDIO_AN_REG_8073_BAM, val | 1);
8383                 ELINK_DEBUG_P0(sc, "Enable CL37 BAM on KR");
8384         }
8385         if (params->loopback_mode == ELINK_LOOPBACK_EXT) {
8386                 elink_807x_force_10G(sc, phy);
8387                 ELINK_DEBUG_P0(sc, "Forced speed 10G on 807X");
8388                 return ELINK_STATUS_OK;
8389         } else {
8390                 elink_cl45_write(sc, phy,
8391                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
8392         }
8393         if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG) {
8394                 if (phy->req_line_speed == ELINK_SPEED_10000) {
8395                         val = (1 << 7);
8396                 } else if (phy->req_line_speed ==  ELINK_SPEED_2500) {
8397                         val = (1 << 5);
8398                         /* Note that 2.5G works only when used with 1G
8399                          * advertisement
8400                          */
8401                 } else
8402                         val = (1 << 5);
8403         } else {
8404                 val = 0;
8405                 if (phy->speed_cap_mask &
8406                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
8407                         val |= (1 << 7);
8408
8409                 /* Note that 2.5G works only when used with 1G advertisement */
8410                 if (phy->speed_cap_mask &
8411                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
8412                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
8413                         val |= (1 << 5);
8414                 ELINK_DEBUG_P1(sc, "807x autoneg val = 0x%x", val);
8415         }
8416
8417         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
8418         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
8419
8420         if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
8421              (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)) ||
8422             (phy->req_line_speed == ELINK_SPEED_2500)) {
8423                 uint16_t phy_ver;
8424                 /* Allow 2.5G for A1 and above */
8425                 elink_cl45_read(sc, phy,
8426                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
8427                                 &phy_ver);
8428                 ELINK_DEBUG_P0(sc, "Add 2.5G");
8429                 if (phy_ver > 0)
8430                         tmp1 |= 1;
8431                 else
8432                         tmp1 &= 0xfffe;
8433         } else {
8434                 ELINK_DEBUG_P0(sc, "Disable 2.5G");
8435                 tmp1 &= 0xfffe;
8436         }
8437
8438         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
8439         /* Add support for CL37 (passive mode) II */
8440
8441         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
8442         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
8443                          (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
8444                                   0x20 : 0x40)));
8445
8446         /* Add support for CL37 (passive mode) III */
8447         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8448
8449         /* The SNR will improve about 2db by changing BW and FEE main
8450          * tap. Rest commands are executed after link is up
8451          * Change FFE main cursor to 5 in EDC register
8452          */
8453         if (elink_8073_is_snr_needed(sc, phy))
8454                 elink_cl45_write(sc, phy,
8455                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
8456                                  0xFB0C);
8457
8458         /* Enable FEC (Forware Error Correction) Request in the AN */
8459         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
8460         tmp1 |= (1 << 15);
8461         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
8462
8463         elink_ext_phy_set_pause(params, phy, vars);
8464
8465         /* Restart autoneg */
8466         DELAY(1000 * 500);
8467         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8468         ELINK_DEBUG_P2(sc, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x",
8469                    ((val & (1 << 5)) > 0), ((val & (1 << 7)) > 0));
8470         return ELINK_STATUS_OK;
8471 }
8472
8473 static uint8_t elink_8073_read_status(struct elink_phy *phy,
8474                                  struct elink_params *params,
8475                                  struct elink_vars *vars)
8476 {
8477         struct bnx2x_softc *sc = params->sc;
8478         uint8_t link_up = 0;
8479         uint16_t val1, val2;
8480         uint16_t link_status = 0;
8481         uint16_t an1000_status = 0;
8482
8483         elink_cl45_read(sc, phy,
8484                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
8485
8486         ELINK_DEBUG_P1(sc, "8703 LASI status 0x%x", val1);
8487
8488         /* Clear the interrupt LASI status register */
8489         elink_cl45_read(sc, phy,
8490                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
8491         elink_cl45_read(sc, phy,
8492                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
8493         ELINK_DEBUG_P2(sc, "807x PCS status 0x%x->0x%x", val2, val1);
8494         /* Clear MSG-OUT */
8495         elink_cl45_read(sc, phy,
8496                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
8497
8498         /* Check the LASI */
8499         elink_cl45_read(sc, phy,
8500                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
8501
8502         ELINK_DEBUG_P1(sc, "KR 0x9003 0x%x", val2);
8503
8504         /* Check the link status */
8505         elink_cl45_read(sc, phy,
8506                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
8507         ELINK_DEBUG_P1(sc, "KR PCS status 0x%x", val2);
8508
8509         elink_cl45_read(sc, phy,
8510                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
8511         elink_cl45_read(sc, phy,
8512                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
8513         link_up = ((val1 & 4) == 4);
8514         ELINK_DEBUG_P1(sc, "PMA_REG_STATUS=0x%x", val1);
8515
8516         if (link_up &&
8517              ((phy->req_line_speed != ELINK_SPEED_10000))) {
8518                 if (elink_8073_xaui_wa(sc, phy) != 0)
8519                         return 0;
8520         }
8521         elink_cl45_read(sc, phy,
8522                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
8523         elink_cl45_read(sc, phy,
8524                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
8525
8526         /* Check the link status on 1.1.2 */
8527         elink_cl45_read(sc, phy,
8528                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
8529         elink_cl45_read(sc, phy,
8530                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
8531         ELINK_DEBUG_P3(sc, "KR PMA status 0x%x->0x%x,"
8532                    "an_link_status=0x%x", val2, val1, an1000_status);
8533
8534         link_up = (((val1 & 4) == 4) || (an1000_status & (1 << 1)));
8535         if (link_up && elink_8073_is_snr_needed(sc, phy)) {
8536                 /* The SNR will improve about 2dbby changing the BW and FEE main
8537                  * tap. The 1st write to change FFE main tap is set before
8538                  * restart AN. Change PLL Bandwidth in EDC register
8539                  */
8540                 elink_cl45_write(sc, phy,
8541                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
8542                                  0x26BC);
8543
8544                 /* Change CDR Bandwidth in EDC register */
8545                 elink_cl45_write(sc, phy,
8546                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
8547                                  0x0333);
8548         }
8549         elink_cl45_read(sc, phy,
8550                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
8551                         &link_status);
8552
8553         /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
8554         if ((link_status & (1 << 2)) && (!(link_status & (1 << 15)))) {
8555                 link_up = 1;
8556                 vars->line_speed = ELINK_SPEED_10000;
8557                 ELINK_DEBUG_P1(sc, "port %x: External link up in 10G",
8558                            params->port);
8559         } else if ((link_status & (1 << 1)) && (!(link_status & (1 << 14)))) {
8560                 link_up = 1;
8561                 vars->line_speed = ELINK_SPEED_2500;
8562                 ELINK_DEBUG_P1(sc, "port %x: External link up in 2.5G",
8563                            params->port);
8564         } else if ((link_status & (1 << 0)) && (!(link_status & (1 << 13)))) {
8565                 link_up = 1;
8566                 vars->line_speed = ELINK_SPEED_1000;
8567                 ELINK_DEBUG_P1(sc, "port %x: External link up in 1G",
8568                            params->port);
8569         } else {
8570                 link_up = 0;
8571                 ELINK_DEBUG_P1(sc, "port %x: External link is down",
8572                            params->port);
8573         }
8574
8575         if (link_up) {
8576                 /* Swap polarity if required */
8577                 if (params->lane_config &
8578                     PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
8579                         /* Configure the 8073 to swap P and N of the KR lines */
8580                         elink_cl45_read(sc, phy,
8581                                         MDIO_XS_DEVAD,
8582                                         MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
8583                         /* Set bit 3 to invert Rx in 1G mode and clear this bit
8584                          * when it`s in 10G mode.
8585                          */
8586                         if (vars->line_speed == ELINK_SPEED_1000) {
8587                                 ELINK_DEBUG_P0(sc, "Swapping 1G polarity for"
8588                                                " the 8073");
8589                                 val1 |= (1 << 3);
8590                         } else
8591                                 val1 &= ~(1 << 3);
8592
8593                         elink_cl45_write(sc, phy,
8594                                          MDIO_XS_DEVAD,
8595                                          MDIO_XS_REG_8073_RX_CTRL_PCIE,
8596                                          val1);
8597                 }
8598                 elink_ext_phy_10G_an_resolve(sc, phy, vars);
8599                 elink_8073_resolve_fc(phy, params, vars);
8600                 vars->duplex = DUPLEX_FULL;
8601         }
8602
8603         if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
8604                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
8605                                 MDIO_AN_REG_LP_AUTO_NEG2, &val1);
8606
8607                 if (val1 & (1 << 5))
8608                         vars->link_status |=
8609                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
8610                 if (val1 & (1 << 7))
8611                         vars->link_status |=
8612                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
8613         }
8614
8615         return link_up;
8616 }
8617
8618 static void elink_8073_link_reset(__rte_unused struct elink_phy *phy,
8619                                   struct elink_params *params)
8620 {
8621         struct bnx2x_softc *sc = params->sc;
8622         uint8_t gpio_port;
8623         if (CHIP_IS_E2(sc))
8624                 gpio_port = SC_PATH(sc);
8625         else
8626                 gpio_port = params->port;
8627         ELINK_DEBUG_P1(sc, "Setting 8073 port %d into low power mode",
8628            gpio_port);
8629         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8630                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
8631                        gpio_port);
8632 }
8633
8634 /******************************************************************/
8635 /*                      BNX2X8705 PHY SECTION                     */
8636 /******************************************************************/
8637 static uint8_t elink_8705_config_init(struct elink_phy *phy,
8638                                   struct elink_params *params,
8639                                   __rte_unused struct elink_vars *vars)
8640 {
8641         struct bnx2x_softc *sc = params->sc;
8642         ELINK_DEBUG_P0(sc, "init 8705");
8643         /* Restore normal power mode*/
8644         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8645                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8646         /* HW reset */
8647         elink_ext_phy_hw_reset(sc, params->port);
8648         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
8649         elink_wait_reset_complete(sc, phy, params);
8650
8651         elink_cl45_write(sc, phy,
8652                          MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
8653         elink_cl45_write(sc, phy,
8654                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
8655         elink_cl45_write(sc, phy,
8656                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
8657         elink_cl45_write(sc, phy,
8658                          MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
8659         /* BNX2X8705 doesn't have microcode, hence the 0 */
8660         elink_save_spirom_version(sc, params->port, params->shmem_base, 0);
8661         return ELINK_STATUS_OK;
8662 }
8663
8664 static uint8_t elink_8705_read_status(struct elink_phy *phy,
8665                                  struct elink_params *params,
8666                                  struct elink_vars *vars)
8667 {
8668         uint8_t link_up = 0;
8669         uint16_t val1, rx_sd;
8670         struct bnx2x_softc *sc = params->sc;
8671         ELINK_DEBUG_P0(sc, "read status 8705");
8672         elink_cl45_read(sc, phy,
8673                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
8674         ELINK_DEBUG_P1(sc, "8705 LASI status 0x%x", val1);
8675
8676         elink_cl45_read(sc, phy,
8677                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
8678         ELINK_DEBUG_P1(sc, "8705 LASI status 0x%x", val1);
8679
8680         elink_cl45_read(sc, phy,
8681                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
8682
8683         elink_cl45_read(sc, phy,
8684                       MDIO_PMA_DEVAD, 0xc809, &val1);
8685         elink_cl45_read(sc, phy,
8686                       MDIO_PMA_DEVAD, 0xc809, &val1);
8687
8688         ELINK_DEBUG_P1(sc, "8705 1.c809 val=0x%x", val1);
8689         link_up = ((rx_sd & 0x1) && (val1 & (1 << 9)) &&
8690                    ((val1 & (1 << 8)) == 0));
8691         if (link_up) {
8692                 vars->line_speed = ELINK_SPEED_10000;
8693                 elink_ext_phy_resolve_fc(phy, params, vars);
8694         }
8695         return link_up;
8696 }
8697
8698 /******************************************************************/
8699 /*                      SFP+ module Section                       */
8700 /******************************************************************/
8701 static void elink_set_disable_pmd_transmit(struct elink_params *params,
8702                                            struct elink_phy *phy,
8703                                            uint8_t pmd_dis)
8704 {
8705         struct bnx2x_softc *sc = params->sc;
8706         /* Disable transmitter only for bootcodes which can enable it afterwards
8707          * (for D3 link)
8708          */
8709         if (pmd_dis) {
8710                 if (params->feature_config_flags &
8711                      ELINK_FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED) {
8712                         ELINK_DEBUG_P0(sc, "Disabling PMD transmitter");
8713                 } else {
8714                         ELINK_DEBUG_P0(sc, "NOT disabling PMD transmitter");
8715                         return;
8716                 }
8717         } else
8718                 ELINK_DEBUG_P0(sc, "Enabling PMD transmitter");
8719         elink_cl45_write(sc, phy,
8720                          MDIO_PMA_DEVAD,
8721                          MDIO_PMA_REG_TX_DISABLE, pmd_dis);
8722 }
8723
8724 static uint8_t elink_get_gpio_port(struct elink_params *params)
8725 {
8726         uint8_t gpio_port;
8727         uint32_t swap_val, swap_override;
8728         struct bnx2x_softc *sc = params->sc;
8729         if (CHIP_IS_E2(sc))
8730                 gpio_port = SC_PATH(sc);
8731         else
8732                 gpio_port = params->port;
8733         swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
8734         swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
8735         return gpio_port ^ (swap_val && swap_override);
8736 }
8737
8738 static void elink_sfp_e1e2_set_transmitter(struct elink_params *params,
8739                                            struct elink_phy *phy,
8740                                            uint8_t tx_en)
8741 {
8742         uint16_t val;
8743         uint8_t port = params->port;
8744         struct bnx2x_softc *sc = params->sc;
8745         uint32_t tx_en_mode;
8746
8747         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
8748         tx_en_mode = REG_RD(sc, params->shmem_base +
8749                             offsetof(struct shmem_region,
8750                                      dev_info.port_hw_config[port].sfp_ctrl)) &
8751                 PORT_HW_CFG_TX_LASER_MASK;
8752         ELINK_DEBUG_P3(sc, "Setting transmitter tx_en=%x for port %x "
8753                            "mode = %x", tx_en, port, tx_en_mode);
8754         switch (tx_en_mode) {
8755         case PORT_HW_CFG_TX_LASER_MDIO:
8756
8757                 elink_cl45_read(sc, phy,
8758                                 MDIO_PMA_DEVAD,
8759                                 MDIO_PMA_REG_PHY_IDENTIFIER,
8760                                 &val);
8761
8762                 if (tx_en)
8763                         val &= ~(1 << 15);
8764                 else
8765                         val |= (1 << 15);
8766
8767                 elink_cl45_write(sc, phy,
8768                                  MDIO_PMA_DEVAD,
8769                                  MDIO_PMA_REG_PHY_IDENTIFIER,
8770                                  val);
8771         break;
8772         case PORT_HW_CFG_TX_LASER_GPIO0:
8773         case PORT_HW_CFG_TX_LASER_GPIO1:
8774         case PORT_HW_CFG_TX_LASER_GPIO2:
8775         case PORT_HW_CFG_TX_LASER_GPIO3:
8776         {
8777                 uint16_t gpio_pin;
8778                 uint8_t gpio_port, gpio_mode;
8779                 if (tx_en)
8780                         gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
8781                 else
8782                         gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
8783
8784                 gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
8785                 gpio_port = elink_get_gpio_port(params);
8786                 elink_cb_gpio_write(sc, gpio_pin, gpio_mode, gpio_port);
8787                 break;
8788         }
8789         default:
8790                 ELINK_DEBUG_P1(sc, "Invalid TX_LASER_MDIO 0x%x", tx_en_mode);
8791                 break;
8792         }
8793 }
8794
8795 static void elink_sfp_set_transmitter(struct elink_params *params,
8796                                       struct elink_phy *phy,
8797                                       uint8_t tx_en)
8798 {
8799         struct bnx2x_softc *sc = params->sc;
8800         ELINK_DEBUG_P1(sc, "Setting SFP+ transmitter to %d", tx_en);
8801         if (CHIP_IS_E3(sc))
8802                 elink_sfp_e3_set_transmitter(params, phy, tx_en);
8803         else
8804                 elink_sfp_e1e2_set_transmitter(params, phy, tx_en);
8805 }
8806
8807 static elink_status_t elink_8726_read_sfp_module_eeprom(struct elink_phy *phy,
8808                              struct elink_params *params,
8809                              uint8_t dev_addr, uint16_t addr,
8810                              uint8_t byte_cnt,
8811                              uint8_t *o_buf, __rte_unused uint8_t is_init)
8812 {
8813         struct bnx2x_softc *sc = params->sc;
8814         uint16_t val = 0;
8815         uint16_t i;
8816         if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8817                 ELINK_DEBUG_P0(sc,
8818                    "Reading from eeprom is limited to 0xf");
8819                 return ELINK_STATUS_ERROR;
8820         }
8821         /* Set the read command byte count */
8822         elink_cl45_write(sc, phy,
8823                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
8824                          (byte_cnt | (dev_addr << 8)));
8825
8826         /* Set the read command address */
8827         elink_cl45_write(sc, phy,
8828                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
8829                          addr);
8830
8831         /* Activate read command */
8832         elink_cl45_write(sc, phy,
8833                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8834                          0x2c0f);
8835
8836         /* Wait up to 500us for command complete status */
8837         for (i = 0; i < 100; i++) {
8838                 elink_cl45_read(sc, phy,
8839                                 MDIO_PMA_DEVAD,
8840                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8841                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8842                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
8843                         break;
8844                 DELAY(5);
8845         }
8846
8847         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
8848                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
8849                 ELINK_DEBUG_P1(sc,
8850                          "Got bad status 0x%x when reading from SFP+ EEPROM",
8851                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
8852                 return ELINK_STATUS_ERROR;
8853         }
8854
8855         /* Read the buffer */
8856         for (i = 0; i < byte_cnt; i++) {
8857                 elink_cl45_read(sc, phy,
8858                                 MDIO_PMA_DEVAD,
8859                                 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
8860                 o_buf[i] = (uint8_t)
8861                                 (val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
8862         }
8863
8864         for (i = 0; i < 100; i++) {
8865                 elink_cl45_read(sc, phy,
8866                                 MDIO_PMA_DEVAD,
8867                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8868                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8869                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
8870                         return ELINK_STATUS_OK;
8871                 DELAY(1000 * 1);
8872         }
8873         return ELINK_STATUS_ERROR;
8874 }
8875
8876 static void elink_warpcore_power_module(struct elink_params *params,
8877                                         uint8_t power)
8878 {
8879         uint32_t pin_cfg;
8880         struct bnx2x_softc *sc = params->sc;
8881
8882         pin_cfg = (REG_RD(sc, params->shmem_base +
8883                           offsetof(struct shmem_region,
8884                         dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
8885                         PORT_HW_CFG_E3_PWR_DIS_MASK) >>
8886                         PORT_HW_CFG_E3_PWR_DIS_SHIFT;
8887
8888         if (pin_cfg == PIN_CFG_NA)
8889                 return;
8890         ELINK_DEBUG_P2(sc, "Setting SFP+ module power to %d using pin cfg %d",
8891                        power, pin_cfg);
8892         /* Low ==> corresponding SFP+ module is powered
8893          * high ==> the SFP+ module is powered down
8894          */
8895         elink_set_cfg_pin(sc, pin_cfg, power ^ 1);
8896 }
8897 static elink_status_t elink_warpcore_read_sfp_module_eeprom(
8898                                          __rte_unused struct elink_phy *phy,
8899                                          struct elink_params *params,
8900                                          uint8_t dev_addr,
8901                                          uint16_t addr,
8902                                          uint8_t byte_cnt,
8903                                          uint8_t *o_buf,
8904                                          uint8_t is_init)
8905 {
8906         elink_status_t rc = ELINK_STATUS_OK;
8907         uint8_t i, j = 0, cnt = 0;
8908         uint32_t data_array[4];
8909         uint16_t addr32;
8910         struct bnx2x_softc *sc = params->sc;
8911
8912         if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8913                 ELINK_DEBUG_P0(sc,
8914                    "Reading from eeprom is limited to 16 bytes");
8915                 return ELINK_STATUS_ERROR;
8916         }
8917
8918         /* 4 byte aligned address */
8919         addr32 = addr & (~0x3);
8920         do {
8921                 if ((!is_init) && (cnt == I2C_WA_PWR_ITER)) {
8922                         elink_warpcore_power_module(params, 0);
8923                         /* Note that 100us are not enough here */
8924                         DELAY(1000 * 1);
8925                         elink_warpcore_power_module(params, 1);
8926                 }
8927
8928                 elink_bsc_module_sel(params);
8929                 rc = elink_bsc_read(sc, dev_addr, addr32, 0, byte_cnt,
8930                                     data_array);
8931         } while ((rc != ELINK_STATUS_OK) && (++cnt < I2C_WA_RETRY_CNT));
8932
8933         if (rc == ELINK_STATUS_OK) {
8934                 for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
8935                         o_buf[j] = *((uint8_t *)data_array + i);
8936                         j++;
8937                 }
8938         }
8939
8940         return rc;
8941 }
8942
8943 static elink_status_t elink_8727_read_sfp_module_eeprom(struct elink_phy *phy,
8944                                              struct elink_params *params,
8945                                              uint8_t dev_addr, uint16_t addr,
8946                                              uint8_t byte_cnt,
8947                                              uint8_t *o_buf,
8948                                              __rte_unused uint8_t is_init)
8949 {
8950         struct bnx2x_softc *sc = params->sc;
8951         uint16_t val, i;
8952
8953         if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8954                 ELINK_DEBUG_P0(sc,
8955                    "Reading from eeprom is limited to 0xf");
8956                 return ELINK_STATUS_ERROR;
8957         }
8958
8959         /* Set 2-wire transfer rate of SFP+ module EEPROM
8960          * to 100Khz since some DACs(direct attached cables) do
8961          * not work at 400Khz.
8962          */
8963         elink_cl45_write(sc, phy,
8964                          MDIO_PMA_DEVAD,
8965                          MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
8966                          ((dev_addr << 8) | 1));
8967
8968         /* Need to read from 1.8000 to clear it */
8969         elink_cl45_read(sc, phy,
8970                         MDIO_PMA_DEVAD,
8971                         MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8972                         &val);
8973
8974         /* Set the read command byte count */
8975         elink_cl45_write(sc, phy,
8976                          MDIO_PMA_DEVAD,
8977                          MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
8978                          ((byte_cnt < 2) ? 2 : byte_cnt));
8979
8980         /* Set the read command address */
8981         elink_cl45_write(sc, phy,
8982                          MDIO_PMA_DEVAD,
8983                          MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
8984                          addr);
8985         /* Set the destination address */
8986         elink_cl45_write(sc, phy,
8987                          MDIO_PMA_DEVAD,
8988                          0x8004,
8989                          MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
8990
8991         /* Activate read command */
8992         elink_cl45_write(sc, phy,
8993                          MDIO_PMA_DEVAD,
8994                          MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8995                          0x8002);
8996         /* Wait appropriate time for two-wire command to finish before
8997          * polling the status register
8998          */
8999         DELAY(1000 * 1);
9000
9001         /* Wait up to 500us for command complete status */
9002         for (i = 0; i < 100; i++) {
9003                 elink_cl45_read(sc, phy,
9004                                 MDIO_PMA_DEVAD,
9005                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
9006                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
9007                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
9008                         break;
9009                 DELAY(5);
9010         }
9011
9012         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
9013                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
9014                 ELINK_DEBUG_P1(sc,
9015                          "Got bad status 0x%x when reading from SFP+ EEPROM",
9016                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
9017                 return ELINK_STATUS_TIMEOUT;
9018         }
9019
9020         /* Read the buffer */
9021         for (i = 0; i < byte_cnt; i++) {
9022                 elink_cl45_read(sc, phy,
9023                                 MDIO_PMA_DEVAD,
9024                                 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
9025                 o_buf[i] = (uint8_t)
9026                                 (val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
9027         }
9028
9029         for (i = 0; i < 100; i++) {
9030                 elink_cl45_read(sc, phy,
9031                                 MDIO_PMA_DEVAD,
9032                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
9033                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
9034                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
9035                         return ELINK_STATUS_OK;
9036                 DELAY(1000 * 1);
9037         }
9038
9039         return ELINK_STATUS_ERROR;
9040 }
9041 elink_status_t elink_read_sfp_module_eeprom(struct elink_phy *phy,
9042                                  struct elink_params *params, uint8_t dev_addr,
9043                                  uint16_t addr, uint16_t byte_cnt,
9044                                  uint8_t *o_buf)
9045 {
9046         elink_status_t rc = 0;
9047         struct bnx2x_softc *sc = params->sc;
9048         uint8_t xfer_size;
9049         uint8_t *user_data = o_buf;
9050         read_sfp_module_eeprom_func_p read_func;
9051         if ((dev_addr != 0xa0) && (dev_addr != 0xa2)) {
9052                 ELINK_DEBUG_P1(sc, "invalid dev_addr 0x%x", dev_addr);
9053                 return ELINK_STATUS_ERROR;
9054         }
9055
9056         switch (phy->type) {
9057         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726:
9058                 read_func = elink_8726_read_sfp_module_eeprom;
9059                 break;
9060         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
9061         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
9062                 read_func = elink_8727_read_sfp_module_eeprom;
9063                 break;
9064         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
9065                 read_func = elink_warpcore_read_sfp_module_eeprom;
9066                 break;
9067         default:
9068                 return ELINK_OP_NOT_SUPPORTED;
9069         }
9070
9071         while (!rc && (byte_cnt > 0)) {
9072                 xfer_size = (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) ?
9073                         ELINK_SFP_EEPROM_PAGE_SIZE : byte_cnt;
9074                 rc = read_func(phy, params, dev_addr, addr, xfer_size,
9075                                user_data, 0);
9076                 byte_cnt -= xfer_size;
9077                 user_data += xfer_size;
9078                 addr += xfer_size;
9079         }
9080         return rc;
9081 }
9082
9083 static elink_status_t elink_get_edc_mode(struct elink_phy *phy,
9084                               struct elink_params *params,
9085                               uint16_t *edc_mode)
9086 {
9087         struct bnx2x_softc *sc = params->sc;
9088         uint32_t sync_offset = 0, phy_idx, media_types;
9089         uint8_t val[ELINK_SFP_EEPROM_FC_TX_TECH_ADDR + 1];
9090         uint8_t check_limiting_mode = 0;
9091         *edc_mode = ELINK_EDC_MODE_LIMITING;
9092         phy->media_type = ELINK_ETH_PHY_UNSPECIFIED;
9093         /* First check for copper cable */
9094         if (elink_read_sfp_module_eeprom(phy,
9095                                          params,
9096                                          ELINK_I2C_DEV_ADDR_A0,
9097                                          0,
9098                                          ELINK_SFP_EEPROM_FC_TX_TECH_ADDR + 1,
9099                                          (uint8_t *)val) != 0) {
9100                 ELINK_DEBUG_P0(sc, "Failed to read from SFP+ module EEPROM");
9101                 return ELINK_STATUS_ERROR;
9102         }
9103         params->link_attr_sync &= ~LINK_SFP_EEPROM_COMP_CODE_MASK;
9104         params->link_attr_sync |= val[ELINK_SFP_EEPROM_10G_COMP_CODE_ADDR] <<
9105                 LINK_SFP_EEPROM_COMP_CODE_SHIFT;
9106         elink_update_link_attr(params, params->link_attr_sync);
9107         switch (val[ELINK_SFP_EEPROM_CON_TYPE_ADDR]) {
9108         case ELINK_SFP_EEPROM_CON_TYPE_VAL_COPPER:
9109         {
9110                 uint8_t copper_module_type;
9111                 phy->media_type = ELINK_ETH_PHY_DA_TWINAX;
9112                 /* Check if its active cable (includes SFP+ module)
9113                  * of passive cable
9114                  */
9115                 copper_module_type = val[ELINK_SFP_EEPROM_FC_TX_TECH_ADDR];
9116                 if (copper_module_type &
9117                     ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
9118                         ELINK_DEBUG_P0(sc, "Active Copper cable detected");
9119                         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
9120                                 *edc_mode = ELINK_EDC_MODE_ACTIVE_DAC;
9121                         else
9122                                 check_limiting_mode = 1;
9123                 } else {
9124                         *edc_mode = ELINK_EDC_MODE_PASSIVE_DAC;
9125                         /* Even in case PASSIVE_DAC indication is not set,
9126                          * treat it as a passive DAC cable, since some cables
9127                          * don't have this indication.
9128                          */
9129                         if (copper_module_type &
9130                            ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
9131                                 ELINK_DEBUG_P0(sc,
9132                                                "Passive Copper cable detected");
9133                         } else {
9134                                 ELINK_DEBUG_P0(sc,
9135                                                "Unknown copper-cable-type");
9136                         }
9137                 }
9138                 break;
9139         }
9140         case ELINK_SFP_EEPROM_CON_TYPE_VAL_UNKNOWN:
9141         case ELINK_SFP_EEPROM_CON_TYPE_VAL_LC:
9142         case ELINK_SFP_EEPROM_CON_TYPE_VAL_RJ45:
9143                 check_limiting_mode = 1;
9144                 /* Module is considered as 1G in case it's NOT compliant with
9145                  * any 10G ethernet protocol, but is 1G Ethernet compliant.
9146                  */
9147                 if (((val[ELINK_SFP_EEPROM_10G_COMP_CODE_ADDR] &
9148                       (ELINK_SFP_EEPROM_10G_COMP_CODE_SR_MASK |
9149                        ELINK_SFP_EEPROM_10G_COMP_CODE_LR_MASK |
9150                        ELINK_SFP_EEPROM_10G_COMP_CODE_LRM_MASK)) == 0) &&
9151                     (val[ELINK_SFP_EEPROM_1G_COMP_CODE_ADDR] != 0)) {
9152                         ELINK_DEBUG_P0(sc, "1G SFP module detected");
9153                         phy->media_type = ELINK_ETH_PHY_SFP_1G_FIBER;
9154                         if (phy->req_line_speed != ELINK_SPEED_1000) {
9155                                 uint8_t gport = params->port;
9156                                 phy->req_line_speed = ELINK_SPEED_1000;
9157                                 if (!CHIP_IS_E1x(sc)) {
9158                                         gport = SC_PATH(sc) +
9159                                         (params->port << 1);
9160                                 }
9161                                 elink_cb_event_log(sc,
9162                                                    ELINK_LOG_ID_NON_10G_MODULE,
9163                                                    gport);
9164                                  /*"Warning: Link speed was forced to 1000Mbps."
9165                                   *" Current SFP module in port %d is not"
9166                                   *" compliant with 10G Ethernet",
9167                                   */
9168                         }
9169
9170                         if (val[ELINK_SFP_EEPROM_1G_COMP_CODE_ADDR] &
9171                             ELINK_SFP_EEPROM_1G_COMP_CODE_BASE_T) {
9172                                 /* Some 1G-baseT modules will not link up,
9173                                  * unless TX_EN is toggled with long delay in
9174                                  * between.
9175                                  */
9176                                 elink_sfp_set_transmitter(params, phy, 0);
9177                                 DELAY(1000 * 40);
9178                                 elink_sfp_set_transmitter(params, phy, 1);
9179                         }
9180                 } else {
9181                         int idx, cfg_idx = 0;
9182                         ELINK_DEBUG_P0(sc, "10G Optic module detected");
9183                         for (idx = ELINK_INT_PHY; idx < ELINK_MAX_PHYS; idx++) {
9184                                 if (params->phy[idx].type == phy->type) {
9185                                         cfg_idx = ELINK_LINK_CONFIG_IDX(idx);
9186                                         break;
9187                                 }
9188                         }
9189                         phy->media_type = ELINK_ETH_PHY_SFPP_10G_FIBER;
9190                         phy->req_line_speed = params->req_line_speed[cfg_idx];
9191                 }
9192                 break;
9193         default:
9194                 ELINK_DEBUG_P1(sc, "Unable to determine module type 0x%x !!!",
9195                          val[ELINK_SFP_EEPROM_CON_TYPE_ADDR]);
9196                 return ELINK_STATUS_ERROR;
9197         }
9198         sync_offset = params->shmem_base +
9199                 offsetof(struct shmem_region,
9200                          dev_info.port_hw_config[params->port].media_type);
9201         media_types = REG_RD(sc, sync_offset);
9202         /* Update media type for non-PMF sync */
9203         for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
9204                 if (&(params->phy[phy_idx]) == phy) {
9205                         media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
9206                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
9207                         media_types |= ((phy->media_type &
9208                                         PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
9209                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
9210                         break;
9211                 }
9212         }
9213         REG_WR(sc, sync_offset, media_types);
9214         if (check_limiting_mode) {
9215                 uint8_t options[ELINK_SFP_EEPROM_OPTIONS_SIZE];
9216                 if (elink_read_sfp_module_eeprom(phy,
9217                                                  params,
9218                                                  ELINK_I2C_DEV_ADDR_A0,
9219                                                  ELINK_SFP_EEPROM_OPTIONS_ADDR,
9220                                                  ELINK_SFP_EEPROM_OPTIONS_SIZE,
9221                                                  options) != 0) {
9222                         ELINK_DEBUG_P0(sc,
9223                            "Failed to read Option field from module EEPROM");
9224                         return ELINK_STATUS_ERROR;
9225                 }
9226                 if ((options[0] & ELINK_SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
9227                         *edc_mode = ELINK_EDC_MODE_LINEAR;
9228                 else
9229                         *edc_mode = ELINK_EDC_MODE_LIMITING;
9230         }
9231         ELINK_DEBUG_P1(sc, "EDC mode is set to 0x%x", *edc_mode);
9232         return ELINK_STATUS_OK;
9233 }
9234 /* This function read the relevant field from the module (SFP+), and verify it
9235  * is compliant with this board
9236  */
9237 static elink_status_t elink_verify_sfp_module(struct elink_phy *phy,
9238                                    struct elink_params *params)
9239 {
9240         struct bnx2x_softc *sc = params->sc;
9241         uint32_t val, cmd;
9242         uint32_t fw_resp, fw_cmd_param;
9243         char vendor_name[ELINK_SFP_EEPROM_VENDOR_NAME_SIZE + 1];
9244         char vendor_pn[ELINK_SFP_EEPROM_PART_NO_SIZE + 1];
9245         phy->flags &= ~ELINK_FLAGS_SFP_NOT_APPROVED;
9246         val = REG_RD(sc, params->shmem_base +
9247                          offsetof(struct shmem_region, dev_info.
9248                                   port_feature_config[params->port].config));
9249         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9250             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
9251                 ELINK_DEBUG_P0(sc, "NOT enforcing module verification");
9252                 return ELINK_STATUS_OK;
9253         }
9254
9255         if (params->feature_config_flags &
9256             ELINK_FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
9257                 /* Use specific phy request */
9258                 cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
9259         } else if (params->feature_config_flags &
9260                    ELINK_FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
9261                 /* Use first phy request only in case of non-dual media*/
9262                 if (ELINK_DUAL_MEDIA(params)) {
9263                         ELINK_DEBUG_P0(sc,
9264                            "FW does not support OPT MDL verification");
9265                         return ELINK_STATUS_ERROR;
9266                 }
9267                 cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
9268         } else {
9269                 /* No support in OPT MDL detection */
9270                 ELINK_DEBUG_P0(sc,
9271                    "FW does not support OPT MDL verification");
9272                 return ELINK_STATUS_ERROR;
9273         }
9274
9275         fw_cmd_param = ELINK_FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
9276         fw_resp = elink_cb_fw_command(sc, cmd, fw_cmd_param);
9277         if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
9278                 ELINK_DEBUG_P0(sc, "Approved module");
9279                 return ELINK_STATUS_OK;
9280         }
9281
9282         /* Format the warning message */
9283         if (elink_read_sfp_module_eeprom(phy,
9284                                          params,
9285                                          ELINK_I2C_DEV_ADDR_A0,
9286                                          ELINK_SFP_EEPROM_VENDOR_NAME_ADDR,
9287                                          ELINK_SFP_EEPROM_VENDOR_NAME_SIZE,
9288                                          (uint8_t *)vendor_name))
9289                 vendor_name[0] = '\0';
9290         else
9291                 vendor_name[ELINK_SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
9292         if (elink_read_sfp_module_eeprom(phy,
9293                                          params,
9294                                          ELINK_I2C_DEV_ADDR_A0,
9295                                          ELINK_SFP_EEPROM_PART_NO_ADDR,
9296                                          ELINK_SFP_EEPROM_PART_NO_SIZE,
9297                                          (uint8_t *)vendor_pn))
9298                 vendor_pn[0] = '\0';
9299         else
9300                 vendor_pn[ELINK_SFP_EEPROM_PART_NO_SIZE] = '\0';
9301
9302         elink_cb_event_log(sc, ELINK_LOG_ID_UNQUAL_IO_MODULE, params->port,
9303                            vendor_name, vendor_pn);
9304                              /* "Warning: Unqualified SFP+ module detected,"
9305                               * " Port %d from %s part number %s",
9306                               */
9307
9308         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
9309             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_WARNING_MSG)
9310                 phy->flags |= ELINK_FLAGS_SFP_NOT_APPROVED;
9311         return ELINK_STATUS_ERROR;
9312 }
9313
9314 static elink_status_t elink_wait_for_sfp_module_initialized(
9315                                                  struct elink_phy *phy,
9316                                                  struct elink_params *params)
9317
9318 {
9319         uint8_t val;
9320         elink_status_t rc;
9321         struct bnx2x_softc *sc = params->sc;
9322         uint16_t timeout;
9323         /* Initialization time after hot-plug may take up to 300ms for
9324          * some phys type ( e.g. JDSU )
9325          */
9326
9327         for (timeout = 0; timeout < 60; timeout++) {
9328                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
9329                         rc = elink_warpcore_read_sfp_module_eeprom(
9330                                 phy, params, ELINK_I2C_DEV_ADDR_A0, 1, 1, &val,
9331                                 1);
9332                 else
9333                         rc = elink_read_sfp_module_eeprom(phy, params,
9334                                                           ELINK_I2C_DEV_ADDR_A0,
9335                                                           1, 1, &val);
9336                 if (rc == 0) {
9337                         ELINK_DEBUG_P1(sc,
9338                            "SFP+ module initialization took %d ms",
9339                            timeout * 5);
9340                         return ELINK_STATUS_OK;
9341                 }
9342                 DELAY(1000 * 5);
9343         }
9344         rc = elink_read_sfp_module_eeprom(phy, params, ELINK_I2C_DEV_ADDR_A0,
9345                                           1, 1, &val);
9346         return rc;
9347 }
9348
9349 static void elink_8727_power_module(struct bnx2x_softc *sc,
9350                                     struct elink_phy *phy,
9351                                     uint8_t is_power_up) {
9352         /* Make sure GPIOs are not using for LED mode */
9353         uint16_t val;
9354         /* In the GPIO register, bit 4 is use to determine if the GPIOs are
9355          * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
9356          * output
9357          * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
9358          * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
9359          * where the 1st bit is the over-current(only input), and 2nd bit is
9360          * for power( only output )
9361          *
9362          * In case of NOC feature is disabled and power is up, set GPIO control
9363          *  as input to enable listening of over-current indication
9364          */
9365         if (phy->flags & ELINK_FLAGS_NOC)
9366                 return;
9367         if (is_power_up)
9368                 val = (1 << 4);
9369         else
9370                 /* Set GPIO control to OUTPUT, and set the power bit
9371                  * to according to the is_power_up
9372                  */
9373                 val = (1 << 1);
9374
9375         elink_cl45_write(sc, phy,
9376                          MDIO_PMA_DEVAD,
9377                          MDIO_PMA_REG_8727_GPIO_CTRL,
9378                          val);
9379 }
9380
9381 static elink_status_t elink_8726_set_limiting_mode(struct bnx2x_softc *sc,
9382                                         struct elink_phy *phy,
9383                                         uint16_t edc_mode)
9384 {
9385         uint16_t cur_limiting_mode;
9386
9387         elink_cl45_read(sc, phy,
9388                         MDIO_PMA_DEVAD,
9389                         MDIO_PMA_REG_ROM_VER2,
9390                         &cur_limiting_mode);
9391         ELINK_DEBUG_P1(sc, "Current Limiting mode is 0x%x",
9392                  cur_limiting_mode);
9393
9394         if (edc_mode == ELINK_EDC_MODE_LIMITING) {
9395                 ELINK_DEBUG_P0(sc, "Setting LIMITING MODE");
9396                 elink_cl45_write(sc, phy,
9397                                  MDIO_PMA_DEVAD,
9398                                  MDIO_PMA_REG_ROM_VER2,
9399                                  ELINK_EDC_MODE_LIMITING);
9400         } else { /* LRM mode ( default )*/
9401
9402                 ELINK_DEBUG_P0(sc, "Setting LRM MODE");
9403
9404                 /* Changing to LRM mode takes quite few seconds. So do it only
9405                  * if current mode is limiting (default is LRM)
9406                  */
9407                 if (cur_limiting_mode != ELINK_EDC_MODE_LIMITING)
9408                         return ELINK_STATUS_OK;
9409
9410                 elink_cl45_write(sc, phy,
9411                                  MDIO_PMA_DEVAD,
9412                                  MDIO_PMA_REG_LRM_MODE,
9413                                  0);
9414                 elink_cl45_write(sc, phy,
9415                                  MDIO_PMA_DEVAD,
9416                                  MDIO_PMA_REG_ROM_VER2,
9417                                  0x128);
9418                 elink_cl45_write(sc, phy,
9419                                  MDIO_PMA_DEVAD,
9420                                  MDIO_PMA_REG_MISC_CTRL0,
9421                                  0x4008);
9422                 elink_cl45_write(sc, phy,
9423                                  MDIO_PMA_DEVAD,
9424                                  MDIO_PMA_REG_LRM_MODE,
9425                                  0xaaaa);
9426         }
9427         return ELINK_STATUS_OK;
9428 }
9429
9430 static elink_status_t elink_8727_set_limiting_mode(struct bnx2x_softc *sc,
9431                                         struct elink_phy *phy,
9432                                         uint16_t edc_mode)
9433 {
9434         uint16_t phy_identifier;
9435         uint16_t rom_ver2_val;
9436         elink_cl45_read(sc, phy,
9437                         MDIO_PMA_DEVAD,
9438                         MDIO_PMA_REG_PHY_IDENTIFIER,
9439                         &phy_identifier);
9440
9441         elink_cl45_write(sc, phy,
9442                          MDIO_PMA_DEVAD,
9443                          MDIO_PMA_REG_PHY_IDENTIFIER,
9444                          (phy_identifier & ~(1 << 9)));
9445
9446         elink_cl45_read(sc, phy,
9447                         MDIO_PMA_DEVAD,
9448                         MDIO_PMA_REG_ROM_VER2,
9449                         &rom_ver2_val);
9450         /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
9451         elink_cl45_write(sc, phy,
9452                          MDIO_PMA_DEVAD,
9453                          MDIO_PMA_REG_ROM_VER2,
9454                          (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
9455
9456         elink_cl45_write(sc, phy,
9457                          MDIO_PMA_DEVAD,
9458                          MDIO_PMA_REG_PHY_IDENTIFIER,
9459                          (phy_identifier | (1 << 9)));
9460
9461         return ELINK_STATUS_OK;
9462 }
9463
9464 static void elink_8727_specific_func(struct elink_phy *phy,
9465                                      struct elink_params *params,
9466                                      uint32_t action)
9467 {
9468         struct bnx2x_softc *sc = params->sc;
9469         uint16_t val;
9470         switch (action) {
9471         case ELINK_DISABLE_TX:
9472                 elink_sfp_set_transmitter(params, phy, 0);
9473                 break;
9474         case ELINK_ENABLE_TX:
9475                 if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED))
9476                         elink_sfp_set_transmitter(params, phy, 1);
9477                 break;
9478         case ELINK_PHY_INIT:
9479                 elink_cl45_write(sc, phy,
9480                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9481                                  (1 << 2) | (1 << 5));
9482                 elink_cl45_write(sc, phy,
9483                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
9484                                  0);
9485                 elink_cl45_write(sc, phy,
9486                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x0006);
9487                 /* Make MOD_ABS give interrupt on change */
9488                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9489                                 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
9490                                 &val);
9491                 val |= (1 << 12);
9492                 if (phy->flags & ELINK_FLAGS_NOC)
9493                         val |= (3 << 5);
9494                 /* Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
9495                  * status which reflect SFP+ module over-current
9496                  */
9497                 if (!(phy->flags & ELINK_FLAGS_NOC))
9498                         val &= 0xff8f; /* Reset bits 4-6 */
9499                 elink_cl45_write(sc, phy,
9500                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
9501                                  val);
9502                 break;
9503         default:
9504                 ELINK_DEBUG_P1(sc, "Function 0x%x not supported by 8727",
9505                    action);
9506                 return;
9507         }
9508 }
9509
9510 static void elink_set_e1e2_module_fault_led(struct elink_params *params,
9511                                            uint8_t gpio_mode)
9512 {
9513         struct bnx2x_softc *sc = params->sc;
9514
9515         uint32_t fault_led_gpio = REG_RD(sc, params->shmem_base +
9516                             offsetof(struct shmem_region,
9517                         dev_info.port_hw_config[params->port].sfp_ctrl)) &
9518                 PORT_HW_CFG_FAULT_MODULE_LED_MASK;
9519         switch (fault_led_gpio) {
9520         case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
9521                 return;
9522         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
9523         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
9524         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
9525         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
9526         {
9527                 uint8_t gpio_port = elink_get_gpio_port(params);
9528                 uint16_t gpio_pin = fault_led_gpio -
9529                         PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
9530                 ELINK_DEBUG_P3(sc, "Set fault module-detected led "
9531                                    "pin %x port %x mode %x",
9532                                gpio_pin, gpio_port, gpio_mode);
9533                 elink_cb_gpio_write(sc, gpio_pin, gpio_mode, gpio_port);
9534         }
9535         break;
9536         default:
9537                 ELINK_DEBUG_P1(sc, "Error: Invalid fault led mode 0x%x",
9538                                fault_led_gpio);
9539         }
9540 }
9541
9542 static void elink_set_e3_module_fault_led(struct elink_params *params,
9543                                           uint8_t gpio_mode)
9544 {
9545         uint32_t pin_cfg;
9546         uint8_t port = params->port;
9547         struct bnx2x_softc *sc = params->sc;
9548         pin_cfg = (REG_RD(sc, params->shmem_base +
9549                          offsetof(struct shmem_region,
9550                                   dev_info.port_hw_config[port].e3_sfp_ctrl)) &
9551                 PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >>
9552                 PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT;
9553         ELINK_DEBUG_P2(sc, "Setting Fault LED to %d using pin cfg %d",
9554                        gpio_mode, pin_cfg);
9555         elink_set_cfg_pin(sc, pin_cfg, gpio_mode);
9556 }
9557
9558 static void elink_set_sfp_module_fault_led(struct elink_params *params,
9559                                            uint8_t gpio_mode)
9560 {
9561         struct bnx2x_softc *sc = params->sc;
9562         ELINK_DEBUG_P1(sc, "Setting SFP+ module fault LED to %d", gpio_mode);
9563         if (CHIP_IS_E3(sc)) {
9564                 /* Low ==> if SFP+ module is supported otherwise
9565                  * High ==> if SFP+ module is not on the approved vendor list
9566                  */
9567                 elink_set_e3_module_fault_led(params, gpio_mode);
9568         } else
9569                 elink_set_e1e2_module_fault_led(params, gpio_mode);
9570 }
9571
9572 static void elink_warpcore_hw_reset(__rte_unused struct elink_phy *phy,
9573                                     struct elink_params *params)
9574 {
9575         struct bnx2x_softc *sc = params->sc;
9576         elink_warpcore_power_module(params, 0);
9577         /* Put Warpcore in low power mode */
9578         REG_WR(sc, MISC_REG_WC0_RESET, 0x0c0e);
9579
9580         /* Put LCPLL in low power mode */
9581         REG_WR(sc, MISC_REG_LCPLL_E40_PWRDWN, 1);
9582         REG_WR(sc, MISC_REG_LCPLL_E40_RESETB_ANA, 0);
9583         REG_WR(sc, MISC_REG_LCPLL_E40_RESETB_DIG, 0);
9584 }
9585
9586 static void elink_power_sfp_module(struct elink_params *params,
9587                                    struct elink_phy *phy,
9588                                    uint8_t power)
9589 {
9590         struct bnx2x_softc *sc = params->sc;
9591         ELINK_DEBUG_P1(sc, "Setting SFP+ power to %x", power);
9592
9593         switch (phy->type) {
9594         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
9595         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
9596                 elink_8727_power_module(params->sc, phy, power);
9597                 break;
9598         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
9599                 elink_warpcore_power_module(params, power);
9600                 break;
9601         default:
9602                 break;
9603         }
9604 }
9605 static void elink_warpcore_set_limiting_mode(struct elink_params *params,
9606                                              struct elink_phy *phy,
9607                                              uint16_t edc_mode)
9608 {
9609         uint16_t val = 0;
9610         uint16_t mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
9611         struct bnx2x_softc *sc = params->sc;
9612
9613         uint8_t lane = elink_get_warpcore_lane(phy, params);
9614         /* This is a global register which controls all lanes */
9615         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
9616                         MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
9617         val &= ~(0xf << (lane << 2));
9618
9619         switch (edc_mode) {
9620         case ELINK_EDC_MODE_LINEAR:
9621         case ELINK_EDC_MODE_LIMITING:
9622                 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
9623                 break;
9624         case ELINK_EDC_MODE_PASSIVE_DAC:
9625         case ELINK_EDC_MODE_ACTIVE_DAC:
9626                 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC;
9627                 break;
9628         default:
9629                 break;
9630         }
9631
9632         val |= (mode << (lane << 2));
9633         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
9634                          MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val);
9635         /* A must read */
9636         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
9637                         MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
9638
9639         /* Restart microcode to re-read the new mode */
9640         elink_warpcore_reset_lane(sc, phy, 1);
9641         elink_warpcore_reset_lane(sc, phy, 0);
9642
9643 }
9644
9645 static void elink_set_limiting_mode(struct elink_params *params,
9646                                     struct elink_phy *phy,
9647                                     uint16_t edc_mode)
9648 {
9649         switch (phy->type) {
9650         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726:
9651                 elink_8726_set_limiting_mode(params->sc, phy, edc_mode);
9652                 break;
9653         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
9654         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
9655                 elink_8727_set_limiting_mode(params->sc, phy, edc_mode);
9656                 break;
9657         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
9658                 elink_warpcore_set_limiting_mode(params, phy, edc_mode);
9659                 break;
9660         }
9661 }
9662
9663 elink_status_t elink_sfp_module_detection(struct elink_phy *phy,
9664                                struct elink_params *params)
9665 {
9666         struct bnx2x_softc *sc = params->sc;
9667         uint16_t edc_mode;
9668         elink_status_t rc = ELINK_STATUS_OK;
9669
9670         uint32_t val = REG_RD(sc, params->shmem_base +
9671                              offsetof(struct shmem_region, dev_info.
9672                                      port_feature_config[params->port].config));
9673         /* Enabled transmitter by default */
9674         elink_sfp_set_transmitter(params, phy, 1);
9675         ELINK_DEBUG_P1(sc, "SFP+ module plugged in/out detected on port %d",
9676                  params->port);
9677         /* Power up module */
9678         elink_power_sfp_module(params, phy, 1);
9679         if (elink_get_edc_mode(phy, params, &edc_mode) != 0) {
9680                 ELINK_DEBUG_P0(sc, "Failed to get valid module type");
9681                 return ELINK_STATUS_ERROR;
9682         } else if (elink_verify_sfp_module(phy, params) != 0) {
9683                 /* Check SFP+ module compatibility */
9684                 ELINK_DEBUG_P0(sc, "Module verification failed!!");
9685                 rc = ELINK_STATUS_ERROR;
9686                 /* Turn on fault module-detected led */
9687                 elink_set_sfp_module_fault_led(params,
9688                                                MISC_REGISTERS_GPIO_HIGH);
9689
9690                 /* Check if need to power down the SFP+ module */
9691                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9692                      PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) {
9693                         ELINK_DEBUG_P0(sc, "Shutdown SFP+ module!!");
9694                         elink_power_sfp_module(params, phy, 0);
9695                         return rc;
9696                 }
9697         } else {
9698                 /* Turn off fault module-detected led */
9699                 elink_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
9700         }
9701
9702         /* Check and set limiting mode / LRM mode on 8726. On 8727 it
9703          * is done automatically
9704          */
9705         elink_set_limiting_mode(params, phy, edc_mode);
9706
9707         /* Disable transmit for this module if the module is not approved, and
9708          * laser needs to be disabled.
9709          */
9710         if ((rc != 0) &&
9711             ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9712              PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER))
9713                 elink_sfp_set_transmitter(params, phy, 0);
9714
9715         return rc;
9716 }
9717
9718 void elink_handle_module_detect_int(struct elink_params *params)
9719 {
9720         struct bnx2x_softc *sc = params->sc;
9721         struct elink_phy *phy;
9722         uint32_t gpio_val;
9723         uint8_t gpio_num, gpio_port;
9724         if (CHIP_IS_E3(sc)) {
9725                 phy = &params->phy[ELINK_INT_PHY];
9726                 /* Always enable TX laser, will be disabled in case of fault */
9727                 elink_sfp_set_transmitter(params, phy, 1);
9728         } else {
9729                 phy = &params->phy[ELINK_EXT_PHY1];
9730         }
9731         if (elink_get_mod_abs_int_cfg(sc, params->chip_id, params->shmem_base,
9732                                       params->port, &gpio_num, &gpio_port) ==
9733             ELINK_STATUS_ERROR) {
9734                 ELINK_DEBUG_P0(sc, "Failed to get MOD_ABS interrupt config");
9735                 return;
9736         }
9737
9738         /* Set valid module led off */
9739         elink_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
9740
9741         /* Get current gpio val reflecting module plugged in / out*/
9742         gpio_val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
9743
9744         /* Call the handling function in case module is detected */
9745         if (gpio_val == 0) {
9746                 elink_set_mdio_emac_per_phy(sc, params);
9747                 elink_set_aer_mmd(params, phy);
9748
9749                 elink_power_sfp_module(params, phy, 1);
9750                 elink_cb_gpio_int_write(sc, gpio_num,
9751                                    MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
9752                                    gpio_port);
9753                 if (elink_wait_for_sfp_module_initialized(phy, params) == 0) {
9754                         elink_sfp_module_detection(phy, params);
9755                         if (CHIP_IS_E3(sc)) {
9756                                 uint16_t rx_tx_in_reset;
9757                                 /* In case WC is out of reset, reconfigure the
9758                                  * link speed while taking into account 1G
9759                                  * module limitation.
9760                                  */
9761                                 elink_cl45_read(sc, phy,
9762                                                 MDIO_WC_DEVAD,
9763                                                 MDIO_WC_REG_DIGITAL5_MISC6,
9764                                                 &rx_tx_in_reset);
9765                                 if ((!rx_tx_in_reset) &&
9766                                     (params->link_flags &
9767                                      ELINK_PHY_INITIALIZED)) {
9768                                         elink_warpcore_reset_lane(sc, phy, 1);
9769                                         elink_warpcore_config_sfi(phy, params);
9770                                         elink_warpcore_reset_lane(sc, phy, 0);
9771                                 }
9772                         }
9773                 } else {
9774                         ELINK_DEBUG_P0(sc, "SFP+ module is not initialized");
9775                 }
9776         } else {
9777                 elink_cb_gpio_int_write(sc, gpio_num,
9778                                    MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
9779                                    gpio_port);
9780                 /* Module was plugged out.
9781                  * Disable transmit for this module
9782                  */
9783                 phy->media_type = ELINK_ETH_PHY_NOT_PRESENT;
9784         }
9785 }
9786
9787 /******************************************************************/
9788 /*              Used by 8706 and 8727                             */
9789 /******************************************************************/
9790 static void elink_sfp_mask_fault(struct bnx2x_softc *sc,
9791                                  struct elink_phy *phy,
9792                                  uint16_t alarm_status_offset,
9793                                  uint16_t alarm_ctrl_offset)
9794 {
9795         uint16_t alarm_status, val;
9796         elink_cl45_read(sc, phy,
9797                         MDIO_PMA_DEVAD, alarm_status_offset,
9798                         &alarm_status);
9799         elink_cl45_read(sc, phy,
9800                         MDIO_PMA_DEVAD, alarm_status_offset,
9801                         &alarm_status);
9802         /* Mask or enable the fault event. */
9803         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
9804         if (alarm_status & (1 << 0))
9805                 val &= ~(1 << 0);
9806         else
9807                 val |= (1 << 0);
9808         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
9809 }
9810 /******************************************************************/
9811 /*              common BNX2X8706/BNX2X8726 PHY SECTION            */
9812 /******************************************************************/
9813 static uint8_t elink_8706_8726_read_status(struct elink_phy *phy,
9814                                       struct elink_params *params,
9815                                       struct elink_vars *vars)
9816 {
9817         uint8_t link_up = 0;
9818         uint16_t val1, val2, rx_sd, pcs_status;
9819         struct bnx2x_softc *sc = params->sc;
9820         ELINK_DEBUG_P0(sc, "XGXS 8706/8726");
9821         /* Clear RX Alarm*/
9822         elink_cl45_read(sc, phy,
9823                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
9824
9825         elink_sfp_mask_fault(sc, phy, MDIO_PMA_LASI_TXSTAT,
9826                              MDIO_PMA_LASI_TXCTRL);
9827
9828         /* Clear LASI indication*/
9829         elink_cl45_read(sc, phy,
9830                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
9831         elink_cl45_read(sc, phy,
9832                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
9833         ELINK_DEBUG_P2(sc, "8706/8726 LASI status 0x%x--> 0x%x", val1, val2);
9834
9835         elink_cl45_read(sc, phy,
9836                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
9837         elink_cl45_read(sc, phy,
9838                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
9839         elink_cl45_read(sc, phy,
9840                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
9841         elink_cl45_read(sc, phy,
9842                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
9843
9844         ELINK_DEBUG_P3(sc, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
9845                         " link_status 0x%x", rx_sd, pcs_status, val2);
9846         /* Link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
9847          * are set, or if the autoneg bit 1 is set
9848          */
9849         link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1 << 1)));
9850         if (link_up) {
9851                 if (val2 & (1 << 1))
9852                         vars->line_speed = ELINK_SPEED_1000;
9853                 else
9854                         vars->line_speed = ELINK_SPEED_10000;
9855                 elink_ext_phy_resolve_fc(phy, params, vars);
9856                 vars->duplex = DUPLEX_FULL;
9857         }
9858
9859         /* Capture 10G link fault. Read twice to clear stale value. */
9860         if (vars->line_speed == ELINK_SPEED_10000) {
9861                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9862                             MDIO_PMA_LASI_TXSTAT, &val1);
9863                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9864                             MDIO_PMA_LASI_TXSTAT, &val1);
9865                 if (val1 & (1 << 0))
9866                         vars->fault_detected = 1;
9867         }
9868
9869         return link_up;
9870 }
9871
9872 /******************************************************************/
9873 /*                      BNX2X8706 PHY SECTION                     */
9874 /******************************************************************/
9875 static uint8_t elink_8706_config_init(struct elink_phy *phy,
9876                                  struct elink_params *params,
9877                                  __rte_unused struct elink_vars *vars)
9878 {
9879         uint32_t tx_en_mode;
9880         uint16_t cnt, val, tmp1;
9881         struct bnx2x_softc *sc = params->sc;
9882
9883         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
9884                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
9885         /* HW reset */
9886         elink_ext_phy_hw_reset(sc, params->port);
9887         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
9888         elink_wait_reset_complete(sc, phy, params);
9889
9890         /* Wait until fw is loaded */
9891         for (cnt = 0; cnt < 100; cnt++) {
9892                 elink_cl45_read(sc, phy,
9893                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
9894                 if (val)
9895                         break;
9896                 DELAY(1000 * 10);
9897         }
9898         ELINK_DEBUG_P1(sc, "XGXS 8706 is initialized after %d ms", cnt);
9899         if ((params->feature_config_flags &
9900              ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
9901                 uint8_t i;
9902                 uint16_t reg;
9903                 for (i = 0; i < 4; i++) {
9904                         reg = MDIO_XS_8706_REG_BANK_RX0 +
9905                                 i * (MDIO_XS_8706_REG_BANK_RX1 -
9906                                      MDIO_XS_8706_REG_BANK_RX0);
9907                         elink_cl45_read(sc, phy, MDIO_XS_DEVAD, reg, &val);
9908                         /* Clear first 3 bits of the control */
9909                         val &= ~0x7;
9910                         /* Set control bits according to configuration */
9911                         val |= (phy->rx_preemphasis[i] & 0x7);
9912                         ELINK_DEBUG_P2(sc, "Setting RX Equalizer to BNX2X8706"
9913                                    " reg 0x%x <-- val 0x%x", reg, val);
9914                         elink_cl45_write(sc, phy, MDIO_XS_DEVAD, reg, val);
9915                 }
9916         }
9917         /* Force speed */
9918         if (phy->req_line_speed == ELINK_SPEED_10000) {
9919                 ELINK_DEBUG_P0(sc, "XGXS 8706 force 10Gbps");
9920
9921                 elink_cl45_write(sc, phy,
9922                                  MDIO_PMA_DEVAD,
9923                                  MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
9924                 elink_cl45_write(sc, phy,
9925                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
9926                                  0);
9927                 /* Arm LASI for link and Tx fault. */
9928                 elink_cl45_write(sc, phy,
9929                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 3);
9930         } else {
9931                 /* Force 1Gbps using autoneg with 1G advertisement */
9932
9933                 /* Allow CL37 through CL73 */
9934                 ELINK_DEBUG_P0(sc, "XGXS 8706 AutoNeg");
9935                 elink_cl45_write(sc, phy,
9936                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
9937
9938                 /* Enable Full-Duplex advertisement on CL37 */
9939                 elink_cl45_write(sc, phy,
9940                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
9941                 /* Enable CL37 AN */
9942                 elink_cl45_write(sc, phy,
9943                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
9944                 /* 1G support */
9945                 elink_cl45_write(sc, phy,
9946                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1 << 5));
9947
9948                 /* Enable clause 73 AN */
9949                 elink_cl45_write(sc, phy,
9950                                  MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
9951                 elink_cl45_write(sc, phy,
9952                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9953                                  0x0400);
9954                 elink_cl45_write(sc, phy,
9955                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
9956                                  0x0004);
9957         }
9958         elink_save_bnx2x_spirom_ver(sc, phy, params->port);
9959
9960         /* If TX Laser is controlled by GPIO_0, do not let PHY go into low
9961          * power mode, if TX Laser is disabled
9962          */
9963
9964         tx_en_mode = REG_RD(sc, params->shmem_base +
9965                             offsetof(struct shmem_region,
9966                                 dev_info.port_hw_config[params->port].sfp_ctrl))
9967                         & PORT_HW_CFG_TX_LASER_MASK;
9968
9969         if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
9970                 ELINK_DEBUG_P0(sc, "Enabling TXONOFF_PWRDN_DIS");
9971                 elink_cl45_read(sc, phy,
9972                         MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
9973                 tmp1 |= 0x1;
9974                 elink_cl45_write(sc, phy,
9975                         MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
9976         }
9977
9978         return ELINK_STATUS_OK;
9979 }
9980
9981 static uint8_t elink_8706_read_status(struct elink_phy *phy,
9982                                   struct elink_params *params,
9983                                   struct elink_vars *vars)
9984 {
9985         return elink_8706_8726_read_status(phy, params, vars);
9986 }
9987
9988 /******************************************************************/
9989 /*                      BNX2X8726 PHY SECTION                     */
9990 /******************************************************************/
9991 static void elink_8726_config_loopback(struct elink_phy *phy,
9992                                        struct elink_params *params)
9993 {
9994         struct bnx2x_softc *sc = params->sc;
9995         ELINK_DEBUG_P0(sc, "PMA/PMD ext_phy_loopback: 8726");
9996         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
9997 }
9998
9999 static void elink_8726_external_rom_boot(struct elink_phy *phy,
10000                                          struct elink_params *params)
10001 {
10002         struct bnx2x_softc *sc = params->sc;
10003         /* Need to wait 100ms after reset */
10004         DELAY(1000 * 100);
10005
10006         /* Micro controller re-boot */
10007         elink_cl45_write(sc, phy,
10008                          MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
10009
10010         /* Set soft reset */
10011         elink_cl45_write(sc, phy,
10012                          MDIO_PMA_DEVAD,
10013                          MDIO_PMA_REG_GEN_CTRL,
10014                          MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
10015
10016         elink_cl45_write(sc, phy,
10017                          MDIO_PMA_DEVAD,
10018                          MDIO_PMA_REG_MISC_CTRL1, 0x0001);
10019
10020         elink_cl45_write(sc, phy,
10021                          MDIO_PMA_DEVAD,
10022                          MDIO_PMA_REG_GEN_CTRL,
10023                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
10024
10025         /* Wait for 150ms for microcode load */
10026         DELAY(1000 * 150);
10027
10028         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
10029         elink_cl45_write(sc, phy,
10030                          MDIO_PMA_DEVAD,
10031                          MDIO_PMA_REG_MISC_CTRL1, 0x0000);
10032
10033         DELAY(1000 * 200);
10034         elink_save_bnx2x_spirom_ver(sc, phy, params->port);
10035 }
10036
10037 static uint8_t elink_8726_read_status(struct elink_phy *phy,
10038                                  struct elink_params *params,
10039                                  struct elink_vars *vars)
10040 {
10041         struct bnx2x_softc *sc = params->sc;
10042         uint16_t val1;
10043         uint8_t link_up = elink_8706_8726_read_status(phy, params, vars);
10044         if (link_up) {
10045                 elink_cl45_read(sc, phy,
10046                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
10047                                 &val1);
10048                 if (val1 & (1 << 15)) {
10049                         ELINK_DEBUG_P0(sc, "Tx is disabled");
10050                         link_up = 0;
10051                         vars->line_speed = 0;
10052                 }
10053         }
10054         return link_up;
10055 }
10056
10057
10058 static uint8_t elink_8726_config_init(struct elink_phy *phy,
10059                                   struct elink_params *params,
10060                                   struct elink_vars *vars)
10061 {
10062         struct bnx2x_softc *sc = params->sc;
10063         ELINK_DEBUG_P0(sc, "Initializing BNX2X8726");
10064
10065         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1 << 15);
10066         elink_wait_reset_complete(sc, phy, params);
10067
10068         elink_8726_external_rom_boot(phy, params);
10069
10070         /* Need to call module detected on initialization since the module
10071          * detection triggered by actual module insertion might occur before
10072          * driver is loaded, and when driver is loaded, it reset all
10073          * registers, including the transmitter
10074          */
10075         elink_sfp_module_detection(phy, params);
10076
10077         if (phy->req_line_speed == ELINK_SPEED_1000) {
10078                 ELINK_DEBUG_P0(sc, "Setting 1G force");
10079                 elink_cl45_write(sc, phy,
10080                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
10081                 elink_cl45_write(sc, phy,
10082                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
10083                 elink_cl45_write(sc, phy,
10084                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x5);
10085                 elink_cl45_write(sc, phy,
10086                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
10087                                  0x400);
10088         } else if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10089                    (phy->speed_cap_mask &
10090                       PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
10091                    ((phy->speed_cap_mask &
10092                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
10093                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
10094                 ELINK_DEBUG_P0(sc, "Setting 1G clause37");
10095                 /* Set Flow control */
10096                 elink_ext_phy_set_pause(params, phy, vars);
10097                 elink_cl45_write(sc, phy,
10098                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
10099                 elink_cl45_write(sc, phy,
10100                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
10101                 elink_cl45_write(sc, phy,
10102                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
10103                 elink_cl45_write(sc, phy,
10104                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
10105                 elink_cl45_write(sc, phy,
10106                                 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
10107                 /* Enable RX-ALARM control to receive interrupt for 1G speed
10108                  * change
10109                  */
10110                 elink_cl45_write(sc, phy,
10111                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x4);
10112                 elink_cl45_write(sc, phy,
10113                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
10114                                  0x400);
10115
10116         } else { /* Default 10G. Set only LASI control */
10117                 elink_cl45_write(sc, phy,
10118                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 1);
10119         }
10120
10121         /* Set TX PreEmphasis if needed */
10122         if ((params->feature_config_flags &
10123              ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
10124                 ELINK_DEBUG_P2(sc,
10125                    "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x",
10126                          phy->tx_preemphasis[0],
10127                          phy->tx_preemphasis[1]);
10128                 elink_cl45_write(sc, phy,
10129                                  MDIO_PMA_DEVAD,
10130                                  MDIO_PMA_REG_8726_TX_CTRL1,
10131                                  phy->tx_preemphasis[0]);
10132
10133                 elink_cl45_write(sc, phy,
10134                                  MDIO_PMA_DEVAD,
10135                                  MDIO_PMA_REG_8726_TX_CTRL2,
10136                                  phy->tx_preemphasis[1]);
10137         }
10138
10139         return ELINK_STATUS_OK;
10140
10141 }
10142
10143 static void elink_8726_link_reset(struct elink_phy *phy,
10144                                   struct elink_params *params)
10145 {
10146         struct bnx2x_softc *sc = params->sc;
10147         ELINK_DEBUG_P1(sc, "elink_8726_link_reset port %d", params->port);
10148         /* Set serial boot control for external load */
10149         elink_cl45_write(sc, phy,
10150                          MDIO_PMA_DEVAD,
10151                          MDIO_PMA_REG_GEN_CTRL, 0x0001);
10152 }
10153
10154 /******************************************************************/
10155 /*                      BNX2X8727 PHY SECTION                     */
10156 /******************************************************************/
10157
10158 static void elink_8727_set_link_led(struct elink_phy *phy,
10159                                     struct elink_params *params, uint8_t mode)
10160 {
10161         struct bnx2x_softc *sc = params->sc;
10162         uint16_t led_mode_bitmask = 0;
10163         uint16_t gpio_pins_bitmask = 0;
10164         uint16_t val;
10165         /* Only NOC flavor requires to set the LED specifically */
10166         if (!(phy->flags & ELINK_FLAGS_NOC))
10167                 return;
10168         switch (mode) {
10169         case ELINK_LED_MODE_FRONT_PANEL_OFF:
10170         case ELINK_LED_MODE_OFF:
10171                 led_mode_bitmask = 0;
10172                 gpio_pins_bitmask = 0x03;
10173                 break;
10174         case ELINK_LED_MODE_ON:
10175                 led_mode_bitmask = 0;
10176                 gpio_pins_bitmask = 0x02;
10177                 break;
10178         case ELINK_LED_MODE_OPER:
10179                 led_mode_bitmask = 0x60;
10180                 gpio_pins_bitmask = 0x11;
10181                 break;
10182         }
10183         elink_cl45_read(sc, phy,
10184                         MDIO_PMA_DEVAD,
10185                         MDIO_PMA_REG_8727_PCS_OPT_CTRL,
10186                         &val);
10187         val &= 0xff8f;
10188         val |= led_mode_bitmask;
10189         elink_cl45_write(sc, phy,
10190                          MDIO_PMA_DEVAD,
10191                          MDIO_PMA_REG_8727_PCS_OPT_CTRL,
10192                          val);
10193         elink_cl45_read(sc, phy,
10194                         MDIO_PMA_DEVAD,
10195                         MDIO_PMA_REG_8727_GPIO_CTRL,
10196                         &val);
10197         val &= 0xffe0;
10198         val |= gpio_pins_bitmask;
10199         elink_cl45_write(sc, phy,
10200                          MDIO_PMA_DEVAD,
10201                          MDIO_PMA_REG_8727_GPIO_CTRL,
10202                          val);
10203 }
10204 static void elink_8727_hw_reset(__rte_unused struct elink_phy *phy,
10205                                 struct elink_params *params) {
10206         uint32_t swap_val, swap_override;
10207         uint8_t port;
10208         /* The PHY reset is controlled by GPIO 1. Fake the port number
10209          * to cancel the swap done in set_gpio()
10210          */
10211         struct bnx2x_softc *sc = params->sc;
10212         swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
10213         swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
10214         port = (swap_val && swap_override) ^ 1;
10215         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
10216                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
10217 }
10218
10219 static void elink_8727_config_speed(struct elink_phy *phy,
10220                                     struct elink_params *params)
10221 {
10222         struct bnx2x_softc *sc = params->sc;
10223         uint16_t tmp1, val;
10224         /* Set option 1G speed */
10225         if ((phy->req_line_speed == ELINK_SPEED_1000) ||
10226             (phy->media_type == ELINK_ETH_PHY_SFP_1G_FIBER)) {
10227                 ELINK_DEBUG_P0(sc, "Setting 1G force");
10228                 elink_cl45_write(sc, phy,
10229                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
10230                 elink_cl45_write(sc, phy,
10231                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
10232                 elink_cl45_read(sc, phy,
10233                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
10234                 ELINK_DEBUG_P1(sc, "1.7 = 0x%x", tmp1);
10235                 /* Power down the XAUI until link is up in case of dual-media
10236                  * and 1G
10237                  */
10238                 if (ELINK_DUAL_MEDIA(params)) {
10239                         elink_cl45_read(sc, phy,
10240                                         MDIO_PMA_DEVAD,
10241                                         MDIO_PMA_REG_8727_PCS_GP, &val);
10242                         val |= (3 << 10);
10243                         elink_cl45_write(sc, phy,
10244                                          MDIO_PMA_DEVAD,
10245                                          MDIO_PMA_REG_8727_PCS_GP, val);
10246                 }
10247         } else if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10248                    ((phy->speed_cap_mask &
10249                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
10250                    ((phy->speed_cap_mask &
10251                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
10252                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
10253
10254                 ELINK_DEBUG_P0(sc, "Setting 1G clause37");
10255                 elink_cl45_write(sc, phy,
10256                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
10257                 elink_cl45_write(sc, phy,
10258                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
10259         } else {
10260                 /* Since the 8727 has only single reset pin, need to set the 10G
10261                  * registers although it is default
10262                  */
10263                 elink_cl45_write(sc, phy,
10264                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
10265                                  0x0020);
10266                 elink_cl45_write(sc, phy,
10267                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
10268                 elink_cl45_write(sc, phy,
10269                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
10270                 elink_cl45_write(sc, phy,
10271                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
10272                                  0x0008);
10273         }
10274 }
10275
10276 static uint8_t elink_8727_config_init(struct elink_phy *phy,
10277                                   struct elink_params *params,
10278                                   __rte_unused struct elink_vars *vars)
10279 {
10280         uint32_t tx_en_mode;
10281         uint16_t tmp1, mod_abs, tmp2;
10282         struct bnx2x_softc *sc = params->sc;
10283         /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
10284
10285         elink_wait_reset_complete(sc, phy, params);
10286
10287         ELINK_DEBUG_P0(sc, "Initializing BNX2X8727");
10288
10289         elink_8727_specific_func(phy, params, ELINK_PHY_INIT);
10290         /* Initially configure MOD_ABS to interrupt when module is
10291          * presence( bit 8)
10292          */
10293         elink_cl45_read(sc, phy,
10294                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
10295         /* Set EDC off by setting OPTXLOS signal input to low (bit 9).
10296          * When the EDC is off it locks onto a reference clock and avoids
10297          * becoming 'lost'
10298          */
10299         mod_abs &= ~(1 << 8);
10300         if (!(phy->flags & ELINK_FLAGS_NOC))
10301                 mod_abs &= ~(1 << 9);
10302         elink_cl45_write(sc, phy,
10303                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10304
10305         /* Enable/Disable PHY transmitter output */
10306         elink_set_disable_pmd_transmit(params, phy, 0);
10307
10308         elink_8727_power_module(sc, phy, 1);
10309
10310         elink_cl45_read(sc, phy,
10311                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
10312
10313         elink_cl45_read(sc, phy,
10314                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
10315
10316         elink_8727_config_speed(phy, params);
10317
10318
10319         /* Set TX PreEmphasis if needed */
10320         if ((params->feature_config_flags &
10321              ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
10322                 ELINK_DEBUG_P2(sc, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x",
10323                            phy->tx_preemphasis[0],
10324                            phy->tx_preemphasis[1]);
10325                 elink_cl45_write(sc, phy,
10326                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
10327                                  phy->tx_preemphasis[0]);
10328
10329                 elink_cl45_write(sc, phy,
10330                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
10331                                  phy->tx_preemphasis[1]);
10332         }
10333
10334         /* If TX Laser is controlled by GPIO_0, do not let PHY go into low
10335          * power mode, if TX Laser is disabled
10336          */
10337         tx_en_mode = REG_RD(sc, params->shmem_base +
10338                             offsetof(struct shmem_region,
10339                                 dev_info.port_hw_config[params->port].sfp_ctrl))
10340                         & PORT_HW_CFG_TX_LASER_MASK;
10341
10342         if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
10343
10344                 ELINK_DEBUG_P0(sc, "Enabling TXONOFF_PWRDN_DIS");
10345                 elink_cl45_read(sc, phy,
10346                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
10347                 tmp2 |= 0x1000;
10348                 tmp2 &= 0xFFEF;
10349                 elink_cl45_write(sc, phy,
10350                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
10351                 elink_cl45_read(sc, phy,
10352                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
10353                                 &tmp2);
10354                 elink_cl45_write(sc, phy,
10355                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
10356                                  (tmp2 & 0x7fff));
10357         }
10358
10359         return ELINK_STATUS_OK;
10360 }
10361
10362 static void elink_8727_handle_mod_abs(struct elink_phy *phy,
10363                                       struct elink_params *params)
10364 {
10365         struct bnx2x_softc *sc = params->sc;
10366         uint16_t mod_abs, rx_alarm_status;
10367         uint32_t val = REG_RD(sc, params->shmem_base +
10368                              offsetof(struct shmem_region, dev_info.
10369                                       port_feature_config[params->port].
10370                                       config));
10371         elink_cl45_read(sc, phy,
10372                         MDIO_PMA_DEVAD,
10373                         MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
10374         if (mod_abs & (1 << 8)) {
10375
10376                 /* Module is absent */
10377                 ELINK_DEBUG_P0(sc,
10378                    "MOD_ABS indication show module is absent");
10379                 phy->media_type = ELINK_ETH_PHY_NOT_PRESENT;
10380                 /* 1. Set mod_abs to detect next module
10381                  *    presence event
10382                  * 2. Set EDC off by setting OPTXLOS signal input to low
10383                  *    (bit 9).
10384                  *    When the EDC is off it locks onto a reference clock and
10385                  *    avoids becoming 'lost'.
10386                  */
10387                 mod_abs &= ~(1 << 8);
10388                 if (!(phy->flags & ELINK_FLAGS_NOC))
10389                         mod_abs &= ~(1 << 9);
10390                 elink_cl45_write(sc, phy,
10391                                  MDIO_PMA_DEVAD,
10392                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10393
10394                 /* Clear RX alarm since it stays up as long as
10395                  * the mod_abs wasn't changed
10396                  */
10397                 elink_cl45_read(sc, phy,
10398                                 MDIO_PMA_DEVAD,
10399                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10400
10401         } else {
10402                 /* Module is present */
10403                 ELINK_DEBUG_P0(sc,
10404                    "MOD_ABS indication show module is present");
10405                 /* First disable transmitter, and if the module is ok, the
10406                  * module_detection will enable it
10407                  * 1. Set mod_abs to detect next module absent event ( bit 8)
10408                  * 2. Restore the default polarity of the OPRXLOS signal and
10409                  * this signal will then correctly indicate the presence or
10410                  * absence of the Rx signal. (bit 9)
10411                  */
10412                 mod_abs |= (1 << 8);
10413                 if (!(phy->flags & ELINK_FLAGS_NOC))
10414                         mod_abs |= (1 << 9);
10415                 elink_cl45_write(sc, phy,
10416                                  MDIO_PMA_DEVAD,
10417                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10418
10419                 /* Clear RX alarm since it stays up as long as the mod_abs
10420                  * wasn't changed. This is need to be done before calling the
10421                  * module detection, otherwise it will clear* the link update
10422                  * alarm
10423                  */
10424                 elink_cl45_read(sc, phy,
10425                                 MDIO_PMA_DEVAD,
10426                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10427
10428
10429                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
10430                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
10431                         elink_sfp_set_transmitter(params, phy, 0);
10432
10433                 if (elink_wait_for_sfp_module_initialized(phy, params) == 0)
10434                         elink_sfp_module_detection(phy, params);
10435                 else
10436                         ELINK_DEBUG_P0(sc, "SFP+ module is not initialized");
10437
10438                 /* Reconfigure link speed based on module type limitations */
10439                 elink_8727_config_speed(phy, params);
10440         }
10441
10442         ELINK_DEBUG_P1(sc, "8727 RX_ALARM_STATUS 0x%x",
10443                    rx_alarm_status);
10444         /* No need to check link status in case of module plugged in/out */
10445 }
10446
10447 static uint8_t elink_8727_read_status(struct elink_phy *phy,
10448                                  struct elink_params *params,
10449                                  struct elink_vars *vars)
10450
10451 {
10452         struct bnx2x_softc *sc = params->sc;
10453         uint8_t link_up = 0;
10454         uint16_t link_status = 0;
10455         uint16_t rx_alarm_status, lasi_ctrl, val1;
10456
10457         /* If PHY is not initialized, do not check link status */
10458         elink_cl45_read(sc, phy,
10459                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
10460                         &lasi_ctrl);
10461         if (!lasi_ctrl)
10462                 return 0;
10463
10464         /* Check the LASI on Rx */
10465         elink_cl45_read(sc, phy,
10466                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT,
10467                         &rx_alarm_status);
10468         vars->line_speed = 0;
10469         ELINK_DEBUG_P1(sc, "8727 RX_ALARM_STATUS  0x%x", rx_alarm_status);
10470
10471         elink_sfp_mask_fault(sc, phy, MDIO_PMA_LASI_TXSTAT,
10472                              MDIO_PMA_LASI_TXCTRL);
10473
10474         elink_cl45_read(sc, phy,
10475                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
10476
10477         ELINK_DEBUG_P1(sc, "8727 LASI status 0x%x", val1);
10478
10479         /* Clear MSG-OUT */
10480         elink_cl45_read(sc, phy,
10481                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
10482
10483         /* If a module is present and there is need to check
10484          * for over current
10485          */
10486         if (!(phy->flags & ELINK_FLAGS_NOC) && !(rx_alarm_status & (1 << 5))) {
10487                 /* Check over-current using 8727 GPIO0 input*/
10488                 elink_cl45_read(sc, phy,
10489                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
10490                                 &val1);
10491
10492                 if ((val1 & (1 << 8)) == 0) {
10493                         uint8_t oc_port = params->port;
10494                         if (!CHIP_IS_E1x(sc))
10495                                 oc_port = SC_PATH(sc) + (params->port << 1);
10496                         ELINK_DEBUG_P1(sc,
10497                            "8727 Power fault has been detected on port %d",
10498                            oc_port);
10499                         elink_cb_event_log(sc, ELINK_LOG_ID_OVER_CURRENT,
10500                                            oc_port);
10501                                         /* "Error: Power fault on Port %d has "
10502                                          *  "been detected and the power to "
10503                                          *  "that SFP+ module has been removed "
10504                                          *  "to prevent failure of the card. "
10505                                          *  "Please remove the SFP+ module and "
10506                                          *  "restart the system to clear this "
10507                                          *  "error.",
10508                                          */
10509                         /* Disable all RX_ALARMs except for mod_abs */
10510                         elink_cl45_write(sc, phy,
10511                                          MDIO_PMA_DEVAD,
10512                                          MDIO_PMA_LASI_RXCTRL, (1 << 5));
10513
10514                         elink_cl45_read(sc, phy,
10515                                         MDIO_PMA_DEVAD,
10516                                         MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
10517                         /* Wait for module_absent_event */
10518                         val1 |= (1 << 8);
10519                         elink_cl45_write(sc, phy,
10520                                          MDIO_PMA_DEVAD,
10521                                          MDIO_PMA_REG_PHY_IDENTIFIER, val1);
10522                         /* Clear RX alarm */
10523                         elink_cl45_read(sc, phy,
10524                                 MDIO_PMA_DEVAD,
10525                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10526                         elink_8727_power_module(params->sc, phy, 0);
10527                         return 0;
10528                 }
10529         } /* Over current check */
10530
10531         /* When module absent bit is set, check module */
10532         if (rx_alarm_status & (1 << 5)) {
10533                 elink_8727_handle_mod_abs(phy, params);
10534                 /* Enable all mod_abs and link detection bits */
10535                 elink_cl45_write(sc, phy,
10536                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
10537                                  ((1 << 5) | (1 << 2)));
10538         }
10539
10540         if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED)) {
10541                 ELINK_DEBUG_P0(sc, "Enabling 8727 TX laser");
10542                 elink_sfp_set_transmitter(params, phy, 1);
10543         } else {
10544                 ELINK_DEBUG_P0(sc, "Tx is disabled");
10545                 return 0;
10546         }
10547
10548         elink_cl45_read(sc, phy,
10549                         MDIO_PMA_DEVAD,
10550                         MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
10551
10552         /* Bits 0..2 --> speed detected,
10553          * Bits 13..15--> link is down
10554          */
10555         if ((link_status & (1 << 2)) && (!(link_status & (1 << 15)))) {
10556                 link_up = 1;
10557                 vars->line_speed = ELINK_SPEED_10000;
10558                 ELINK_DEBUG_P1(sc, "port %x: External link up in 10G",
10559                            params->port);
10560         } else if ((link_status & (1 << 0)) && (!(link_status & (1 << 13)))) {
10561                 link_up = 1;
10562                 vars->line_speed = ELINK_SPEED_1000;
10563                 ELINK_DEBUG_P1(sc, "port %x: External link up in 1G",
10564                            params->port);
10565         } else {
10566                 link_up = 0;
10567                 ELINK_DEBUG_P1(sc, "port %x: External link is down",
10568                            params->port);
10569         }
10570
10571         /* Capture 10G link fault. */
10572         if (vars->line_speed == ELINK_SPEED_10000) {
10573                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
10574                             MDIO_PMA_LASI_TXSTAT, &val1);
10575
10576                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
10577                             MDIO_PMA_LASI_TXSTAT, &val1);
10578
10579                 if (val1 & (1 << 0)) {
10580                         vars->fault_detected = 1;
10581                 }
10582         }
10583
10584         if (link_up) {
10585                 elink_ext_phy_resolve_fc(phy, params, vars);
10586                 vars->duplex = DUPLEX_FULL;
10587                 ELINK_DEBUG_P1(sc, "duplex = 0x%x", vars->duplex);
10588         }
10589
10590         if ((ELINK_DUAL_MEDIA(params)) &&
10591             (phy->req_line_speed == ELINK_SPEED_1000)) {
10592                 elink_cl45_read(sc, phy,
10593                                 MDIO_PMA_DEVAD,
10594                                 MDIO_PMA_REG_8727_PCS_GP, &val1);
10595                 /* In case of dual-media board and 1G, power up the XAUI side,
10596                  * otherwise power it down. For 10G it is done automatically
10597                  */
10598                 if (link_up)
10599                         val1 &= ~(3 << 10);
10600                 else
10601                         val1 |= (3 << 10);
10602                 elink_cl45_write(sc, phy,
10603                                  MDIO_PMA_DEVAD,
10604                                  MDIO_PMA_REG_8727_PCS_GP, val1);
10605         }
10606         return link_up;
10607 }
10608
10609 static void elink_8727_link_reset(struct elink_phy *phy,
10610                                   struct elink_params *params)
10611 {
10612         struct bnx2x_softc *sc = params->sc;
10613
10614         /* Enable/Disable PHY transmitter output */
10615         elink_set_disable_pmd_transmit(params, phy, 1);
10616
10617         /* Disable Transmitter */
10618         elink_sfp_set_transmitter(params, phy, 0);
10619         /* Clear LASI */
10620         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0);
10621
10622 }
10623
10624 /******************************************************************/
10625 /*              BNX2X8481/BNX2X84823/BNX2X84833 PHY SECTION               */
10626 /******************************************************************/
10627 static int elink_is_8483x_8485x(struct elink_phy *phy)
10628 {
10629         return ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84833) ||
10630                 (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834) ||
10631                 (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858));
10632 }
10633
10634 static void elink_save_848xx_spirom_version(struct elink_phy *phy,
10635                                             struct bnx2x_softc *sc,
10636                                             uint8_t port)
10637 {
10638         uint16_t val, fw_ver2, cnt, i;
10639         static struct elink_reg_set reg_set[] = {
10640                 {MDIO_PMA_DEVAD, 0xA819, 0x0014},
10641                 {MDIO_PMA_DEVAD, 0xA81A, 0xc200},
10642                 {MDIO_PMA_DEVAD, 0xA81B, 0x0000},
10643                 {MDIO_PMA_DEVAD, 0xA81C, 0x0300},
10644                 {MDIO_PMA_DEVAD, 0xA817, 0x0009}
10645         };
10646         uint16_t fw_ver1;
10647
10648         if (elink_is_8483x_8485x(phy)) {
10649                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1);
10650                 elink_save_spirom_version(sc, port, fw_ver1 & 0xfff,
10651                                 phy->ver_addr);
10652         } else {
10653                 /* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */
10654                 /* (1) set reg 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
10655                 for (i = 0; i < ARRAY_SIZE(reg_set); i++)
10656                         elink_cl45_write(sc, phy, reg_set[i].devad,
10657                                          reg_set[i].reg, reg_set[i].val);
10658
10659                 for (cnt = 0; cnt < 100; cnt++) {
10660                         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA818, &val);
10661                         if (val & 1)
10662                                 break;
10663                         DELAY(5);
10664                 }
10665                 if (cnt == 100) {
10666                         ELINK_DEBUG_P0(sc, "Unable to read 848xx "
10667                                         "phy fw version(1)");
10668                         elink_save_spirom_version(sc, port, 0,
10669                                                   phy->ver_addr);
10670                         return;
10671                 }
10672
10673
10674                 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
10675                 elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
10676                 elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
10677                 elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
10678                 for (cnt = 0; cnt < 100; cnt++) {
10679                         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA818, &val);
10680                         if (val & 1)
10681                                 break;
10682                         DELAY(5);
10683                 }
10684                 if (cnt == 100) {
10685                         ELINK_DEBUG_P0(sc, "Unable to read 848xx phy fw "
10686                                         "version(2)");
10687                         elink_save_spirom_version(sc, port, 0,
10688                                                   phy->ver_addr);
10689                         return;
10690                 }
10691
10692                 /* lower 16 bits of the register SPI_FW_STATUS */
10693                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
10694                 /* upper 16 bits of register SPI_FW_STATUS */
10695                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
10696
10697                 elink_save_spirom_version(sc, port, (fw_ver2 << 16) | fw_ver1,
10698                                           phy->ver_addr);
10699         }
10700
10701 }
10702 static void elink_848xx_set_led(struct bnx2x_softc *sc,
10703                                 struct elink_phy *phy)
10704 {
10705         uint16_t val, offset, i;
10706         static struct elink_reg_set reg_set[] = {
10707                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, 0x0080},
10708                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED2_MASK, 0x0018},
10709                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_MASK, 0x0006},
10710                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_BLINK, 0x0000},
10711                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH,
10712                         MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ},
10713                 {MDIO_AN_DEVAD, 0xFFFB, 0xFFFD}
10714         };
10715         /* PHYC_CTL_LED_CTL */
10716         elink_cl45_read(sc, phy,
10717                         MDIO_PMA_DEVAD,
10718                         MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
10719         val &= 0xFE00;
10720         val |= 0x0092;
10721
10722         elink_cl45_write(sc, phy,
10723                          MDIO_PMA_DEVAD,
10724                          MDIO_PMA_REG_8481_LINK_SIGNAL, val);
10725
10726         for (i = 0; i < ARRAY_SIZE(reg_set); i++)
10727                 elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
10728                                  reg_set[i].val);
10729
10730         if (elink_is_8483x_8485x(phy))
10731                 offset = MDIO_PMA_REG_84833_CTL_LED_CTL_1;
10732         else
10733                 offset = MDIO_PMA_REG_84823_CTL_LED_CTL_1;
10734
10735         /* stretch_en for LED3*/
10736         elink_cl45_read_or_write(sc, phy,
10737                                  MDIO_PMA_DEVAD, offset,
10738                                  MDIO_PMA_REG_84823_LED3_STRETCH_EN);
10739 }
10740
10741 static void elink_848xx_specific_func(struct elink_phy *phy,
10742                                       struct elink_params *params,
10743                                       uint32_t action)
10744 {
10745         struct bnx2x_softc *sc = params->sc;
10746         switch (action) {
10747         case ELINK_PHY_INIT:
10748                 if (!elink_is_8483x_8485x(phy)) {
10749                         /* Save spirom version */
10750                         elink_save_848xx_spirom_version(phy, sc, params->port);
10751                 }
10752                 /* This phy uses the NIG latch mechanism since link indication
10753                  * arrives through its LED4 and not via its LASI signal, so we
10754                  * get steady signal instead of clear on read
10755                  */
10756                 elink_bits_en(sc, NIG_REG_LATCH_BC_0 + params->port * 4,
10757                               1 << ELINK_NIG_LATCH_BC_ENABLE_MI_INT);
10758
10759                 elink_848xx_set_led(sc, phy);
10760                 break;
10761         }
10762 }
10763
10764 static elink_status_t elink_848xx_cmn_config_init(struct elink_phy *phy,
10765                                        struct elink_params *params,
10766                                        struct elink_vars *vars)
10767 {
10768         struct bnx2x_softc *sc = params->sc;
10769         uint16_t autoneg_val, an_1000_val, an_10_100_val;
10770
10771         elink_848xx_specific_func(phy, params, ELINK_PHY_INIT);
10772         elink_cl45_write(sc, phy,
10773                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
10774
10775         /* set 1000 speed advertisement */
10776         elink_cl45_read(sc, phy,
10777                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
10778                         &an_1000_val);
10779
10780         elink_ext_phy_set_pause(params, phy, vars);
10781         elink_cl45_read(sc, phy,
10782                         MDIO_AN_DEVAD,
10783                         MDIO_AN_REG_8481_LEGACY_AN_ADV,
10784                         &an_10_100_val);
10785         elink_cl45_read(sc, phy,
10786                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
10787                         &autoneg_val);
10788         /* Disable forced speed */
10789         autoneg_val &= ~((1 << 6) | (1 << 8) | (1 << 9) | (1 << 12) |
10790                          (1 << 13));
10791         an_10_100_val &= ~((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8));
10792
10793         if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10794              (phy->speed_cap_mask &
10795              PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
10796             (phy->req_line_speed == ELINK_SPEED_1000)) {
10797                 an_1000_val |= (1 << 8);
10798                 autoneg_val |= (1 << 9 | 1 << 12);
10799                 if (phy->req_duplex == DUPLEX_FULL)
10800                         an_1000_val |= (1 << 9);
10801                 ELINK_DEBUG_P0(sc, "Advertising 1G");
10802         } else
10803                 an_1000_val &= ~((1 << 8) | (1 << 9));
10804
10805         elink_cl45_write(sc, phy,
10806                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
10807                          an_1000_val);
10808
10809         /* Set 10/100 speed advertisement */
10810         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
10811                 if (phy->speed_cap_mask &
10812                     PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
10813                         /* Enable autoneg and restart autoneg for legacy speeds
10814                          */
10815                         autoneg_val |= (1 << 9 | 1 << 12);
10816                         an_10_100_val |= (1 << 8);
10817                         ELINK_DEBUG_P0(sc, "Advertising 100M-FD");
10818                 }
10819
10820                 if (phy->speed_cap_mask &
10821                     PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
10822                         /* Enable autoneg and restart autoneg for legacy speeds
10823                          */
10824                         autoneg_val |= (1 << 9 | 1 << 12);
10825                         an_10_100_val |= (1 << 7);
10826                         ELINK_DEBUG_P0(sc, "Advertising 100M-HD");
10827                 }
10828
10829                 if ((phy->speed_cap_mask &
10830                      PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
10831                     (phy->supported & ELINK_SUPPORTED_10baseT_Full)) {
10832                         an_10_100_val |= (1 << 6);
10833                         autoneg_val |= (1 << 9 | 1 << 12);
10834                         ELINK_DEBUG_P0(sc, "Advertising 10M-FD");
10835                 }
10836
10837                 if ((phy->speed_cap_mask &
10838                      PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) &&
10839                     (phy->supported & ELINK_SUPPORTED_10baseT_Half)) {
10840                         an_10_100_val |= (1 << 5);
10841                         autoneg_val |= (1 << 9 | 1 << 12);
10842                         ELINK_DEBUG_P0(sc, "Advertising 10M-HD");
10843                 }
10844         }
10845
10846         /* Only 10/100 are allowed to work in FORCE mode */
10847         if ((phy->req_line_speed == ELINK_SPEED_100) &&
10848             (phy->supported &
10849              (ELINK_SUPPORTED_100baseT_Half |
10850               ELINK_SUPPORTED_100baseT_Full))) {
10851                 autoneg_val |= (1 << 13);
10852                 /* Enabled AUTO-MDIX when autoneg is disabled */
10853                 elink_cl45_write(sc, phy,
10854                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
10855                                  (1 << 15 | 1 << 9 | 7 << 0));
10856                 /* The PHY needs this set even for forced link. */
10857                 an_10_100_val |= (1 << 8) | (1 << 7);
10858                 ELINK_DEBUG_P0(sc, "Setting 100M force");
10859         }
10860         if ((phy->req_line_speed == ELINK_SPEED_10) &&
10861             (phy->supported &
10862              (ELINK_SUPPORTED_10baseT_Half |
10863               ELINK_SUPPORTED_10baseT_Full))) {
10864                 /* Enabled AUTO-MDIX when autoneg is disabled */
10865                 elink_cl45_write(sc, phy,
10866                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
10867                                  (1 << 15 | 1 << 9 | 7 << 0));
10868                 ELINK_DEBUG_P0(sc, "Setting 10M force");
10869         }
10870
10871         elink_cl45_write(sc, phy,
10872                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
10873                          an_10_100_val);
10874
10875         if (phy->req_duplex == DUPLEX_FULL)
10876                 autoneg_val |= (1 << 8);
10877
10878         /* Always write this if this is not 84833/4.
10879          * For 84833/4, write it only when it's a forced speed.
10880          */
10881         if (!elink_is_8483x_8485x(phy) ||
10882             ((autoneg_val & (1 << 12)) == 0))
10883                 elink_cl45_write(sc, phy,
10884                          MDIO_AN_DEVAD,
10885                          MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
10886
10887         if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10888              (phy->speed_cap_mask &
10889               PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
10890             (phy->req_line_speed == ELINK_SPEED_10000)) {
10891                 ELINK_DEBUG_P0(sc, "Advertising 10G");
10892                 /* Restart autoneg for 10G*/
10893
10894                 elink_cl45_read_or_write(
10895                         sc, phy,
10896                         MDIO_AN_DEVAD,
10897                         MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
10898                         0x1000);
10899                 elink_cl45_write(sc, phy,
10900                                  MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
10901                                  0x3200);
10902         } else
10903                 elink_cl45_write(sc, phy,
10904                                  MDIO_AN_DEVAD,
10905                                  MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
10906                                  1);
10907
10908         return ELINK_STATUS_OK;
10909 }
10910
10911 static uint8_t elink_8481_config_init(struct elink_phy *phy,
10912                                   struct elink_params *params,
10913                                   struct elink_vars *vars)
10914 {
10915         struct bnx2x_softc *sc = params->sc;
10916         /* Restore normal power mode*/
10917         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
10918                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
10919
10920         /* HW reset */
10921         elink_ext_phy_hw_reset(sc, params->port);
10922         elink_wait_reset_complete(sc, phy, params);
10923
10924         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1 << 15);
10925         return elink_848xx_cmn_config_init(phy, params, vars);
10926 }
10927
10928 #define PHY848xx_CMDHDLR_WAIT 300
10929 #define PHY848xx_CMDHDLR_MAX_ARGS 5
10930
10931 static elink_status_t elink_84858_cmd_hdlr(struct elink_phy *phy,
10932                                            struct elink_params *params,
10933                                            uint16_t fw_cmd,
10934                                            uint16_t cmd_args[], int argc)
10935 {
10936         int idx;
10937         uint16_t val;
10938         struct bnx2x_softc *sc = params->sc;
10939
10940         /* Step 1: Poll the STATUS register to see whether the previous command
10941          * is in progress or the system is busy (CMD_IN_PROGRESS or
10942          * SYSTEM_BUSY). If previous command is in progress or system is busy,
10943          * check again until the previous command finishes execution and the
10944          * system is available for taking command
10945          */
10946
10947         for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
10948                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10949                                 MDIO_848xx_CMD_HDLR_STATUS, &val);
10950                 if ((val != PHY84858_STATUS_CMD_IN_PROGRESS) &&
10951                     (val != PHY84858_STATUS_CMD_SYSTEM_BUSY))
10952                         break;
10953                 DELAY(1000 * 1);
10954         }
10955         if (idx >= PHY848xx_CMDHDLR_WAIT) {
10956                 ELINK_DEBUG_P0(sc, "FW cmd: FW not ready.");
10957                 return ELINK_STATUS_ERROR;
10958         }
10959
10960         /* Step2: If any parameters are required for the function, write them
10961          * to the required DATA registers
10962          */
10963
10964         for (idx = 0; idx < argc; idx++) {
10965                 elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10966                                  MDIO_848xx_CMD_HDLR_DATA1 + idx,
10967                                  cmd_args[idx]);
10968         }
10969
10970         /* Step3: When the firmware is ready for commands, write the 'Command
10971          * code' to the CMD register
10972          */
10973         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10974                          MDIO_848xx_CMD_HDLR_COMMAND, fw_cmd);
10975
10976         /* Step4: Once the command has been written, poll the STATUS register
10977          * to check whether the command has completed (CMD_COMPLETED_PASS/
10978          * CMD_FOR_CMDS or CMD_COMPLETED_ERROR).
10979          */
10980
10981         for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
10982                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10983                                 MDIO_848xx_CMD_HDLR_STATUS, &val);
10984                 if ((val == PHY84858_STATUS_CMD_COMPLETE_PASS) ||
10985                     (val == PHY84858_STATUS_CMD_COMPLETE_ERROR))
10986                         break;
10987                 DELAY(1000 * 1);
10988         }
10989         if ((idx >= PHY848xx_CMDHDLR_WAIT) ||
10990             (val == PHY84858_STATUS_CMD_COMPLETE_ERROR)) {
10991                 ELINK_DEBUG_P0(sc, "FW cmd failed.");
10992                 return ELINK_STATUS_ERROR;
10993         }
10994         /* Step5: Once the command has completed, read the specficied DATA
10995          * registers for any saved results for the command, if applicable
10996          */
10997
10998         /* Gather returning data */
10999         for (idx = 0; idx < argc; idx++) {
11000                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11001                                 MDIO_848xx_CMD_HDLR_DATA1 + idx,
11002                                 &cmd_args[idx]);
11003         }
11004
11005         return ELINK_STATUS_OK;
11006 }
11007
11008 static elink_status_t elink_84833_cmd_hdlr(struct elink_phy *phy,
11009                                 struct elink_params *params, uint16_t fw_cmd,
11010                                 uint16_t cmd_args[], int argc, int process)
11011 {
11012         int idx;
11013         uint16_t val;
11014         struct bnx2x_softc *sc = params->sc;
11015         elink_status_t rc = ELINK_STATUS_OK;
11016
11017         if (process == PHY84833_MB_PROCESS2) {
11018         /* Write CMD_OPEN_OVERRIDE to STATUS reg */
11019         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11020                                  MDIO_848xx_CMD_HDLR_STATUS,
11021                         PHY84833_STATUS_CMD_OPEN_OVERRIDE);
11022         }
11023
11024         for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
11025                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11026                                MDIO_848xx_CMD_HDLR_STATUS, &val);
11027                 if (val == PHY84833_STATUS_CMD_OPEN_FOR_CMDS)
11028                         break;
11029                 DELAY(1000 * 1);
11030         }
11031         if (idx >= PHY848xx_CMDHDLR_WAIT) {
11032                 ELINK_DEBUG_P0(sc, "FW cmd: FW not ready.");
11033                 /* if the status is CMD_COMPLETE_PASS or CMD_COMPLETE_ERROR
11034                  * clear the status to CMD_CLEAR_COMPLETE
11035                  */
11036                 if (val == PHY84833_STATUS_CMD_COMPLETE_PASS ||
11037                     val == PHY84833_STATUS_CMD_COMPLETE_ERROR) {
11038                         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11039                                          MDIO_848xx_CMD_HDLR_STATUS,
11040                                          PHY84833_STATUS_CMD_CLEAR_COMPLETE);
11041                 }
11042                 return ELINK_STATUS_ERROR;
11043         }
11044         if (process == PHY84833_MB_PROCESS1 ||
11045             process == PHY84833_MB_PROCESS2) {
11046                 /* Prepare argument(s) */
11047         for (idx = 0; idx < argc; idx++) {
11048                 elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11049                                          MDIO_848xx_CMD_HDLR_DATA1 + idx,
11050                                 cmd_args[idx]);
11051         }
11052         }
11053
11054         /* Issue command */
11055         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11056                         MDIO_848xx_CMD_HDLR_COMMAND, fw_cmd);
11057         for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
11058                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11059                                MDIO_848xx_CMD_HDLR_STATUS, &val);
11060                 if ((val == PHY84833_STATUS_CMD_COMPLETE_PASS) ||
11061                         (val == PHY84833_STATUS_CMD_COMPLETE_ERROR))
11062                         break;
11063                 DELAY(1000 * 1);
11064         }
11065         if ((idx >= PHY848xx_CMDHDLR_WAIT) ||
11066                 (val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) {
11067                 ELINK_DEBUG_P0(sc, "FW cmd failed.");
11068                 rc = ELINK_STATUS_ERROR;
11069         }
11070         if (process == PHY84833_MB_PROCESS3 && rc == ELINK_STATUS_OK) {
11071         /* Gather returning data */
11072         for (idx = 0; idx < argc; idx++) {
11073                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11074                                         MDIO_848xx_CMD_HDLR_DATA1 + idx,
11075                                 &cmd_args[idx]);
11076         }
11077         }
11078         if (val == PHY84833_STATUS_CMD_COMPLETE_ERROR ||
11079             val == PHY84833_STATUS_CMD_COMPLETE_PASS) {
11080         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11081                                  MDIO_848xx_CMD_HDLR_STATUS,
11082                         PHY84833_STATUS_CMD_CLEAR_COMPLETE);
11083         }
11084         return rc;
11085 }
11086
11087 static elink_status_t elink_848xx_cmd_hdlr(struct elink_phy *phy,
11088                                            struct elink_params *params,
11089                                            uint16_t fw_cmd,
11090                                            uint16_t cmd_args[], int argc,
11091                                            int process)
11092 {
11093         struct bnx2x_softc *sc = params->sc;
11094
11095         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858) ||
11096             (REG_RD(sc, params->shmem2_base +
11097                     offsetof(struct shmem2_region,
11098                              link_attr_sync[params->port])) &
11099                              LINK_ATTR_84858)) {
11100                 return elink_84858_cmd_hdlr(phy, params, fw_cmd, cmd_args,
11101                                             argc);
11102         } else {
11103                 return elink_84833_cmd_hdlr(phy, params, fw_cmd, cmd_args,
11104                                             argc, process);
11105         }
11106 }
11107
11108 static elink_status_t elink_848xx_pair_swap_cfg(struct elink_phy *phy,
11109                                    struct elink_params *params,
11110                                    __rte_unused struct elink_vars *vars)
11111 {
11112         uint32_t pair_swap;
11113         uint16_t data[PHY848xx_CMDHDLR_MAX_ARGS];
11114         elink_status_t status;
11115         struct bnx2x_softc *sc = params->sc;
11116
11117         /* Check for configuration. */
11118         pair_swap = REG_RD(sc, params->shmem_base +
11119                            offsetof(struct shmem_region,
11120                         dev_info.port_hw_config[params->port].xgbt_phy_cfg)) &
11121                 PORT_HW_CFG_RJ45_PAIR_SWAP_MASK;
11122
11123         if (pair_swap == 0)
11124                 return ELINK_STATUS_OK;
11125
11126         /* Only the second argument is used for this command */
11127         data[1] = (uint16_t)pair_swap;
11128
11129         status = elink_848xx_cmd_hdlr(phy, params,
11130                                       PHY848xx_CMD_SET_PAIR_SWAP, data,
11131                                       2, PHY84833_MB_PROCESS2);
11132         if (status == ELINK_STATUS_OK)
11133                 ELINK_DEBUG_P1(sc, "Pairswap OK, val=0x%x", data[1]);
11134
11135         return status;
11136 }
11137
11138 static uint8_t elink_84833_get_reset_gpios(struct bnx2x_softc *sc,
11139                                       uint32_t shmem_base_path[],
11140                                       __rte_unused uint32_t chip_id)
11141 {
11142         uint32_t reset_pin[2];
11143         uint32_t idx;
11144         uint8_t reset_gpios;
11145         if (CHIP_IS_E3(sc)) {
11146                 /* Assume that these will be GPIOs, not EPIOs. */
11147                 for (idx = 0; idx < 2; idx++) {
11148                         /* Map config param to register bit. */
11149                         reset_pin[idx] = REG_RD(sc, shmem_base_path[idx] +
11150                                 offsetof(struct shmem_region,
11151                                 dev_info.port_hw_config[0].e3_cmn_pin_cfg));
11152                         reset_pin[idx] = (reset_pin[idx] &
11153                                 PORT_HW_CFG_E3_PHY_RESET_MASK) >>
11154                                 PORT_HW_CFG_E3_PHY_RESET_SHIFT;
11155                         reset_pin[idx] -= PIN_CFG_GPIO0_P0;
11156                         reset_pin[idx] = (1 << reset_pin[idx]);
11157                 }
11158                 reset_gpios = (uint8_t)(reset_pin[0] | reset_pin[1]);
11159         } else {
11160                 /* E2, look from diff place of shmem. */
11161                 for (idx = 0; idx < 2; idx++) {
11162                         reset_pin[idx] = REG_RD(sc, shmem_base_path[idx] +
11163                                 offsetof(struct shmem_region,
11164                                 dev_info.port_hw_config[0].default_cfg));
11165                         reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK;
11166                         reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0;
11167                         reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT;
11168                         reset_pin[idx] = (1 << reset_pin[idx]);
11169                 }
11170                 reset_gpios = (uint8_t)(reset_pin[0] | reset_pin[1]);
11171         }
11172
11173         return reset_gpios;
11174 }
11175
11176 static void elink_84833_hw_reset_phy(struct elink_phy *phy,
11177                                 struct elink_params *params)
11178 {
11179         struct bnx2x_softc *sc = params->sc;
11180         uint8_t reset_gpios;
11181         uint32_t other_shmem_base_addr = REG_RD(sc, params->shmem2_base +
11182                                 offsetof(struct shmem2_region,
11183                                 other_shmem_base_addr));
11184
11185         uint32_t shmem_base_path[2];
11186
11187         /* Work around for 84833 LED failure inside RESET status */
11188         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
11189                 MDIO_AN_REG_8481_LEGACY_MII_CTRL,
11190                 MDIO_AN_REG_8481_MII_CTRL_FORCE_1G);
11191         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
11192                 MDIO_AN_REG_8481_1G_100T_EXT_CTRL,
11193                 MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF);
11194
11195         shmem_base_path[0] = params->shmem_base;
11196         shmem_base_path[1] = other_shmem_base_addr;
11197
11198         reset_gpios = elink_84833_get_reset_gpios(sc, shmem_base_path,
11199                                                   params->chip_id);
11200
11201         elink_cb_gpio_mult_write(sc, reset_gpios,
11202                                  MISC_REGISTERS_GPIO_OUTPUT_LOW);
11203         DELAY(10);
11204         ELINK_DEBUG_P1(sc, "84833 hw reset on pin values 0x%x",
11205                 reset_gpios);
11206 }
11207
11208 static elink_status_t elink_8483x_disable_eee(struct elink_phy *phy,
11209                                    struct elink_params *params,
11210                                    struct elink_vars *vars)
11211 {
11212         elink_status_t rc;
11213         struct bnx2x_softc *sc = params->sc;
11214         uint16_t cmd_args = 0;
11215
11216         ELINK_DEBUG_P0(sc, "Don't Advertise 10GBase-T EEE");
11217
11218         /* Prevent Phy from working in EEE and advertising it */
11219         rc = elink_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE,
11220                                   &cmd_args, 1, PHY84833_MB_PROCESS1);
11221         if (rc != ELINK_STATUS_OK) {
11222                 ELINK_DEBUG_P0(sc, "EEE disable failed.");
11223                 return rc;
11224         }
11225
11226         return elink_eee_disable(phy, params, vars);
11227 }
11228
11229 static elink_status_t elink_8483x_enable_eee(struct elink_phy *phy,
11230                                    struct elink_params *params,
11231                                    struct elink_vars *vars)
11232 {
11233         elink_status_t rc;
11234         struct bnx2x_softc *sc = params->sc;
11235         uint16_t cmd_args = 1;
11236
11237         rc = elink_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE,
11238                                   &cmd_args, 1, PHY84833_MB_PROCESS1);
11239         if (rc != ELINK_STATUS_OK) {
11240                 ELINK_DEBUG_P0(sc, "EEE enable failed.");
11241                 return rc;
11242         }
11243
11244         return elink_eee_advertise(phy, params, vars, SHMEM_EEE_10G_ADV);
11245 }
11246
11247 #define PHY84833_CONSTANT_LATENCY 1193
11248 static uint8_t elink_848x3_config_init(struct elink_phy *phy,
11249                                    struct elink_params *params,
11250                                    struct elink_vars *vars)
11251 {
11252         struct bnx2x_softc *sc = params->sc;
11253         uint8_t port, initialize = 1;
11254         uint16_t val;
11255         uint32_t actual_phy_selection;
11256         uint16_t cmd_args[PHY848xx_CMDHDLR_MAX_ARGS];
11257         elink_status_t rc = ELINK_STATUS_OK;
11258
11259         DELAY(1000 * 1);
11260
11261         if (!(CHIP_IS_E1x(sc)))
11262                 port = SC_PATH(sc);
11263         else
11264                 port = params->port;
11265
11266         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823) {
11267                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_3,
11268                                MISC_REGISTERS_GPIO_OUTPUT_HIGH,
11269                                port);
11270         } else {
11271                 /* MDIO reset */
11272                 elink_cl45_write(sc, phy,
11273                                 MDIO_PMA_DEVAD,
11274                                 MDIO_PMA_REG_CTRL, 0x8000);
11275         }
11276
11277         elink_wait_reset_complete(sc, phy, params);
11278
11279         /* Wait for GPHY to come out of reset */
11280         DELAY(1000 * 50);
11281         if (!elink_is_8483x_8485x(phy)) {
11282                 /* BNX2X84823 requires that XGXS links up first @ 10G for normal
11283                  * behavior.
11284                  */
11285                 uint16_t temp;
11286                 temp = vars->line_speed;
11287                 vars->line_speed = ELINK_SPEED_10000;
11288                 elink_set_autoneg(&params->phy[ELINK_INT_PHY], params, vars, 0);
11289                 elink_program_serdes(&params->phy[ELINK_INT_PHY], params, vars);
11290                 vars->line_speed = temp;
11291         }
11292         /* Check if this is actually BNX2X84858 */
11293         if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858) {
11294                 uint16_t hw_rev;
11295
11296                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11297                                 MDIO_AN_REG_848xx_ID_MSB, &hw_rev);
11298                 if (hw_rev == BNX2X84858_PHY_ID) {
11299                         params->link_attr_sync |= LINK_ATTR_84858;
11300                         elink_update_link_attr(params, params->link_attr_sync);
11301                 }
11302         }
11303
11304         /* Set dual-media configuration according to configuration */
11305         elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11306                         MDIO_CTL_REG_84823_MEDIA, &val);
11307         val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
11308                  MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
11309                  MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
11310                  MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
11311                  MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
11312
11313         if (CHIP_IS_E3(sc)) {
11314                 val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
11315                          MDIO_CTL_REG_84823_MEDIA_LINE_MASK);
11316         } else {
11317                 val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI |
11318                         MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L);
11319         }
11320
11321         actual_phy_selection = elink_phy_selection(params);
11322
11323         switch (actual_phy_selection) {
11324         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
11325                 /* Do nothing. Essentially this is like the priority copper */
11326                 break;
11327         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
11328                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
11329                 break;
11330         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
11331                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
11332                 break;
11333         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
11334                 /* Do nothing here. The first PHY won't be initialized at all */
11335                 break;
11336         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
11337                 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
11338                 initialize = 0;
11339                 break;
11340         }
11341         if (params->phy[ELINK_EXT_PHY2].req_line_speed == ELINK_SPEED_1000)
11342                 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
11343
11344         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11345                          MDIO_CTL_REG_84823_MEDIA, val);
11346         ELINK_DEBUG_P2(sc, "Multi_phy config = 0x%x, Media control = 0x%x",
11347                    params->multi_phy_config, val);
11348
11349         if (elink_is_8483x_8485x(phy)) {
11350                 elink_848xx_pair_swap_cfg(phy, params, vars);
11351
11352                 /* Keep AutogrEEEn disabled. */
11353                 cmd_args[0] = 0x0;
11354                 cmd_args[1] = 0x0;
11355                 cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1;
11356                 cmd_args[3] = PHY84833_CONSTANT_LATENCY;
11357                 rc = elink_848xx_cmd_hdlr(phy, params,
11358                                           PHY848xx_CMD_SET_EEE_MODE, cmd_args,
11359                                           4, PHY84833_MB_PROCESS1);
11360                 if (rc != ELINK_STATUS_OK)
11361                         ELINK_DEBUG_P0(sc, "Cfg AutogrEEEn failed.");
11362         }
11363         if (initialize)
11364                 rc = elink_848xx_cmn_config_init(phy, params, vars);
11365         else
11366                 elink_save_848xx_spirom_version(phy, sc, params->port);
11367         /* 84833 PHY has a better feature and doesn't need to support this. */
11368         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823) {
11369                 uint32_t cms_enable = REG_RD(sc, params->shmem_base +
11370                         offsetof(struct shmem_region,
11371                         dev_info.port_hw_config[params->port].default_cfg)) &
11372                         PORT_HW_CFG_ENABLE_CMS_MASK;
11373
11374                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11375                                 MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
11376                 if (cms_enable)
11377                         val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
11378                 else
11379                         val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
11380                 elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11381                                  MDIO_CTL_REG_84823_USER_CTRL_REG, val);
11382         }
11383
11384         elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11385                         MDIO_84833_TOP_CFG_FW_REV, &val);
11386
11387         /* Configure EEE support */
11388         if ((val >= MDIO_84833_TOP_CFG_FW_EEE) &&
11389             (val != MDIO_84833_TOP_CFG_FW_NO_EEE) &&
11390             elink_eee_has_cap(params)) {
11391                 rc = elink_eee_initial_config(params, vars, SHMEM_EEE_10G_ADV);
11392                 if (rc != ELINK_STATUS_OK) {
11393                         ELINK_DEBUG_P0(sc, "Failed to configure EEE timers");
11394                         elink_8483x_disable_eee(phy, params, vars);
11395                         return rc;
11396                 }
11397
11398                 if ((phy->req_duplex == DUPLEX_FULL) &&
11399                     (params->eee_mode & ELINK_EEE_MODE_ADV_LPI) &&
11400                     (elink_eee_calc_timer(params) ||
11401                      !(params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)))
11402                         rc = elink_8483x_enable_eee(phy, params, vars);
11403                 else
11404                         rc = elink_8483x_disable_eee(phy, params, vars);
11405                 if (rc != ELINK_STATUS_OK) {
11406                         ELINK_DEBUG_P0(sc, "Failed to set EEE advertisement");
11407                         return rc;
11408                 }
11409         } else {
11410                 vars->eee_status &= ~SHMEM_EEE_SUPPORTED_MASK;
11411         }
11412
11413         if (elink_is_8483x_8485x(phy)) {
11414                 /* Bring PHY out of super isolate mode as the final step. */
11415                 elink_cl45_read_and_write(sc, phy,
11416                                           MDIO_CTL_DEVAD,
11417                                           MDIO_84833_TOP_CFG_XGPHY_STRAP1,
11418                                           (uint16_t)~MDIO_84833_SUPER_ISOLATE);
11419         }
11420         return rc;
11421 }
11422
11423 static uint8_t elink_848xx_read_status(struct elink_phy *phy,
11424                                   struct elink_params *params,
11425                                   struct elink_vars *vars)
11426 {
11427         struct bnx2x_softc *sc = params->sc;
11428         uint16_t val, val1, val2;
11429         uint8_t link_up = 0;
11430
11431
11432         /* Check 10G-BaseT link status */
11433         /* Check PMD signal ok */
11434         elink_cl45_read(sc, phy,
11435                         MDIO_AN_DEVAD, 0xFFFA, &val1);
11436         elink_cl45_read(sc, phy,
11437                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
11438                         &val2);
11439         ELINK_DEBUG_P1(sc, "BNX2X848xx: PMD_SIGNAL 1.a811 = 0x%x", val2);
11440
11441         /* Check link 10G */
11442         if (val2 & (1 << 11)) {
11443                 vars->line_speed = ELINK_SPEED_10000;
11444                 vars->duplex = DUPLEX_FULL;
11445                 link_up = 1;
11446                 elink_ext_phy_10G_an_resolve(sc, phy, vars);
11447         } else { /* Check Legacy speed link */
11448                 uint16_t legacy_status, legacy_speed;
11449
11450                 /* Enable expansion register 0x42 (Operation mode status) */
11451                 elink_cl45_write(sc, phy,
11452                                  MDIO_AN_DEVAD,
11453                                  MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
11454
11455                 /* Get legacy speed operation status */
11456                 elink_cl45_read(sc, phy,
11457                                 MDIO_AN_DEVAD,
11458                                 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
11459                                 &legacy_status);
11460
11461                 ELINK_DEBUG_P1(sc, "Legacy speed status = 0x%x",
11462                    legacy_status);
11463                 link_up = ((legacy_status & (1 << 11)) == (1 << 11));
11464                 legacy_speed = (legacy_status & (3 << 9));
11465                 if (legacy_speed == (0 << 9))
11466                         vars->line_speed = ELINK_SPEED_10;
11467                 else if (legacy_speed == (1 << 9))
11468                         vars->line_speed = ELINK_SPEED_100;
11469                 else if (legacy_speed == (2 << 9))
11470                         vars->line_speed = ELINK_SPEED_1000;
11471                 else { /* Should not happen: Treat as link down */
11472                         vars->line_speed = 0;
11473                         link_up = 0;
11474                 }
11475
11476                 if (params->feature_config_flags &
11477                         ELINK_FEATURE_CONFIG_IEEE_PHY_TEST) {
11478                         uint16_t mii_ctrl;
11479
11480                         elink_cl45_read(sc, phy,
11481                                         MDIO_AN_DEVAD,
11482                                         MDIO_AN_REG_8481_LEGACY_MII_CTRL,
11483                                         &mii_ctrl);
11484                         /* For IEEE testing, check for a fake link. */
11485                         link_up |= ((mii_ctrl & 0x3040) == 0x40);
11486                 }
11487
11488                 if (link_up) {
11489                         if (legacy_status & (1 << 8))
11490                                 vars->duplex = DUPLEX_FULL;
11491                         else
11492                                 vars->duplex = DUPLEX_HALF;
11493
11494                         ELINK_DEBUG_P2(sc,
11495                            "Link is up in %dMbps, is_duplex_full= %d",
11496                            vars->line_speed,
11497                            (vars->duplex == DUPLEX_FULL));
11498                         /* Check legacy speed AN resolution */
11499                         elink_cl45_read(sc, phy,
11500                                         MDIO_AN_DEVAD,
11501                                         MDIO_AN_REG_8481_LEGACY_MII_STATUS,
11502                                         &val);
11503                         if (val & (1 << 5))
11504                                 vars->link_status |=
11505                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
11506                         elink_cl45_read(sc, phy,
11507                                         MDIO_AN_DEVAD,
11508                                         MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
11509                                         &val);
11510                         if ((val & (1 << 0)) == 0)
11511                                 vars->link_status |=
11512                                         LINK_STATUS_PARALLEL_DETECTION_USED;
11513                 }
11514         }
11515         if (link_up) {
11516                 ELINK_DEBUG_P1(sc, "BNX2X848x3: link speed is %d",
11517                            vars->line_speed);
11518                 elink_ext_phy_resolve_fc(phy, params, vars);
11519
11520                 /* Read LP advertised speeds */
11521                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11522                                 MDIO_AN_REG_CL37_FC_LP, &val);
11523                 if (val & (1 << 5))
11524                         vars->link_status |=
11525                                 LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
11526                 if (val & (1 << 6))
11527                         vars->link_status |=
11528                                 LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
11529                 if (val & (1 << 7))
11530                         vars->link_status |=
11531                                 LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
11532                 if (val & (1 << 8))
11533                         vars->link_status |=
11534                                 LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
11535                 if (val & (1 << 9))
11536                         vars->link_status |=
11537                                 LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
11538
11539                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11540                                 MDIO_AN_REG_1000T_STATUS, &val);
11541
11542                 if (val & (1 << 10))
11543                         vars->link_status |=
11544                                 LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
11545                 if (val & (1 << 11))
11546                         vars->link_status |=
11547                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
11548
11549                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11550                                 MDIO_AN_REG_MASTER_STATUS, &val);
11551
11552                 if (val & (1 << 11))
11553                         vars->link_status |=
11554                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
11555
11556                 /* Determine if EEE was negotiated */
11557                 if (elink_is_8483x_8485x(phy))
11558                         elink_eee_an_resolve(phy, params, vars);
11559         }
11560
11561         return link_up;
11562 }
11563
11564 static elink_status_t elink_848xx_format_ver(uint32_t raw_ver, uint8_t *str,
11565                                              uint16_t *len)
11566 {
11567         elink_status_t status = ELINK_STATUS_OK;
11568         uint32_t spirom_ver;
11569         spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
11570         status = elink_format_ver(spirom_ver, str, len);
11571         return status;
11572 }
11573
11574 static void elink_8481_hw_reset(__rte_unused struct elink_phy *phy,
11575                                 struct elink_params *params)
11576 {
11577         elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
11578                        MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
11579         elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
11580                        MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
11581 }
11582
11583 static void elink_8481_link_reset(struct elink_phy *phy,
11584                                         struct elink_params *params)
11585 {
11586         elink_cl45_write(params->sc, phy,
11587                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
11588         elink_cl45_write(params->sc, phy,
11589                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
11590 }
11591
11592 static void elink_848x3_link_reset(struct elink_phy *phy,
11593                                    struct elink_params *params)
11594 {
11595         struct bnx2x_softc *sc = params->sc;
11596         uint8_t port;
11597         uint16_t val16;
11598
11599         if (!(CHIP_IS_E1x(sc)))
11600                 port = SC_PATH(sc);
11601         else
11602                 port = params->port;
11603
11604         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823) {
11605                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_3,
11606                                MISC_REGISTERS_GPIO_OUTPUT_LOW,
11607                                port);
11608         } else {
11609                 elink_cl45_read(sc, phy,
11610                                 MDIO_CTL_DEVAD,
11611                                 MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val16);
11612                 val16 |= MDIO_84833_SUPER_ISOLATE;
11613                 elink_cl45_write(sc, phy,
11614                                  MDIO_CTL_DEVAD,
11615                                  MDIO_84833_TOP_CFG_XGPHY_STRAP1, val16);
11616         }
11617 }
11618
11619 static void elink_848xx_set_link_led(struct elink_phy *phy,
11620                                      struct elink_params *params, uint8_t mode)
11621 {
11622         struct bnx2x_softc *sc = params->sc;
11623         uint16_t val;
11624         uint8_t port;
11625
11626         if (!(CHIP_IS_E1x(sc)))
11627                 port = SC_PATH(sc);
11628         else
11629                 port = params->port;
11630         switch (mode) {
11631         case ELINK_LED_MODE_OFF:
11632
11633                 ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE OFF", port);
11634
11635                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11636                     SHARED_HW_CFG_LED_EXTPHY1) {
11637
11638                         /* Set LED masks */
11639                         elink_cl45_write(sc, phy,
11640                                         MDIO_PMA_DEVAD,
11641                                         MDIO_PMA_REG_8481_LED1_MASK,
11642                                         0x0);
11643
11644                         elink_cl45_write(sc, phy,
11645                                         MDIO_PMA_DEVAD,
11646                                         MDIO_PMA_REG_8481_LED2_MASK,
11647                                         0x0);
11648
11649                         elink_cl45_write(sc, phy,
11650                                         MDIO_PMA_DEVAD,
11651                                         MDIO_PMA_REG_8481_LED3_MASK,
11652                                         0x0);
11653
11654                         elink_cl45_write(sc, phy,
11655                                         MDIO_PMA_DEVAD,
11656                                         MDIO_PMA_REG_8481_LED5_MASK,
11657                                         0x0);
11658
11659                 } else {
11660                         elink_cl45_write(sc, phy,
11661                                          MDIO_PMA_DEVAD,
11662                                          MDIO_PMA_REG_8481_LED1_MASK,
11663                                          0x0);
11664                 }
11665                 break;
11666         case ELINK_LED_MODE_FRONT_PANEL_OFF:
11667
11668                 ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE FRONT PANEL OFF",
11669                    port);
11670
11671                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11672                     SHARED_HW_CFG_LED_EXTPHY1) {
11673
11674                         /* Set LED masks */
11675                         elink_cl45_write(sc, phy,
11676                                          MDIO_PMA_DEVAD,
11677                                          MDIO_PMA_REG_8481_LED1_MASK,
11678                                          0x0);
11679
11680                         elink_cl45_write(sc, phy,
11681                                          MDIO_PMA_DEVAD,
11682                                          MDIO_PMA_REG_8481_LED2_MASK,
11683                                          0x0);
11684
11685                         elink_cl45_write(sc, phy,
11686                                          MDIO_PMA_DEVAD,
11687                                          MDIO_PMA_REG_8481_LED3_MASK,
11688                                          0x0);
11689
11690                         elink_cl45_write(sc, phy,
11691                                          MDIO_PMA_DEVAD,
11692                                          MDIO_PMA_REG_8481_LED5_MASK,
11693                                          0x20);
11694
11695                 } else {
11696                         elink_cl45_write(sc, phy,
11697                                          MDIO_PMA_DEVAD,
11698                                          MDIO_PMA_REG_8481_LED1_MASK,
11699                                          0x0);
11700                         if (phy->type ==
11701                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834) {
11702                                 /* Disable MI_INT interrupt before setting LED4
11703                                  * source to constant off.
11704                                  */
11705                                 if (REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
11706                                            params->port * 4) &
11707                                     ELINK_NIG_MASK_MI_INT) {
11708                                         params->link_flags |=
11709                                         ELINK_LINK_FLAGS_INT_DISABLED;
11710
11711                                         elink_bits_dis(
11712                                                 sc,
11713                                                 NIG_REG_MASK_INTERRUPT_PORT0 +
11714                                                 params->port * 4,
11715                                                 ELINK_NIG_MASK_MI_INT);
11716                                 }
11717                                 elink_cl45_write(sc, phy,
11718                                                  MDIO_PMA_DEVAD,
11719                                                  MDIO_PMA_REG_8481_SIGNAL_MASK,
11720                                                  0x0);
11721                         }
11722                 }
11723                 break;
11724         case ELINK_LED_MODE_ON:
11725
11726                 ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE ON", port);
11727
11728                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11729                     SHARED_HW_CFG_LED_EXTPHY1) {
11730                         /* Set control reg */
11731                         elink_cl45_read(sc, phy,
11732                                         MDIO_PMA_DEVAD,
11733                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
11734                                         &val);
11735                         val &= 0x8000;
11736                         val |= 0x2492;
11737
11738                         elink_cl45_write(sc, phy,
11739                                          MDIO_PMA_DEVAD,
11740                                          MDIO_PMA_REG_8481_LINK_SIGNAL,
11741                                          val);
11742
11743                         /* Set LED masks */
11744                         elink_cl45_write(sc, phy,
11745                                          MDIO_PMA_DEVAD,
11746                                          MDIO_PMA_REG_8481_LED1_MASK,
11747                                          0x0);
11748
11749                         elink_cl45_write(sc, phy,
11750                                          MDIO_PMA_DEVAD,
11751                                          MDIO_PMA_REG_8481_LED2_MASK,
11752                                          0x20);
11753
11754                         elink_cl45_write(sc, phy,
11755                                          MDIO_PMA_DEVAD,
11756                                          MDIO_PMA_REG_8481_LED3_MASK,
11757                                          0x20);
11758
11759                         elink_cl45_write(sc, phy,
11760                                          MDIO_PMA_DEVAD,
11761                                          MDIO_PMA_REG_8481_LED5_MASK,
11762                                          0x0);
11763                 } else {
11764                         elink_cl45_write(sc, phy,
11765                                          MDIO_PMA_DEVAD,
11766                                          MDIO_PMA_REG_8481_LED1_MASK,
11767                                          0x20);
11768                         if (phy->type ==
11769                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834) {
11770                                 /* Disable MI_INT interrupt before setting LED4
11771                                  * source to constant on.
11772                                  */
11773                                 if (REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
11774                                            params->port * 4) &
11775                                     ELINK_NIG_MASK_MI_INT) {
11776                                         params->link_flags |=
11777                                         ELINK_LINK_FLAGS_INT_DISABLED;
11778
11779                                         elink_bits_dis(
11780                                                 sc,
11781                                                 NIG_REG_MASK_INTERRUPT_PORT0 +
11782                                                 params->port * 4,
11783                                                 ELINK_NIG_MASK_MI_INT);
11784                                 }
11785                                 elink_cl45_write(sc, phy,
11786                                                  MDIO_PMA_DEVAD,
11787                                                  MDIO_PMA_REG_8481_SIGNAL_MASK,
11788                                                  0x20);
11789                         }
11790                 }
11791                 break;
11792
11793         case ELINK_LED_MODE_OPER:
11794
11795                 ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE OPER", port);
11796
11797                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11798                     SHARED_HW_CFG_LED_EXTPHY1) {
11799
11800                         /* Set control reg */
11801                         elink_cl45_read(sc, phy,
11802                                         MDIO_PMA_DEVAD,
11803                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
11804                                         &val);
11805
11806                         if (!((val &
11807                                MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
11808                           >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
11809                                 ELINK_DEBUG_P0(sc, "Setting LINK_SIGNAL");
11810                                 elink_cl45_write(sc, phy,
11811                                                  MDIO_PMA_DEVAD,
11812                                                  MDIO_PMA_REG_8481_LINK_SIGNAL,
11813                                                  0xa492);
11814                         }
11815
11816                         /* Set LED masks */
11817                         elink_cl45_write(sc, phy,
11818                                          MDIO_PMA_DEVAD,
11819                                          MDIO_PMA_REG_8481_LED1_MASK,
11820                                          0x10);
11821
11822                         elink_cl45_write(sc, phy,
11823                                          MDIO_PMA_DEVAD,
11824                                          MDIO_PMA_REG_8481_LED2_MASK,
11825                                          0x80);
11826
11827                         elink_cl45_write(sc, phy,
11828                                          MDIO_PMA_DEVAD,
11829                                          MDIO_PMA_REG_8481_LED3_MASK,
11830                                          0x98);
11831
11832                         elink_cl45_write(sc, phy,
11833                                          MDIO_PMA_DEVAD,
11834                                          MDIO_PMA_REG_8481_LED5_MASK,
11835                                          0x40);
11836
11837                 } else {
11838                         /* EXTPHY2 LED mode indicate that the 100M/1G/10G LED
11839                          * sources are all wired through LED1, rather than only
11840                          * 10G in other modes.
11841                          */
11842                         val = ((params->hw_led_mode <<
11843                                 SHARED_HW_CFG_LED_MODE_SHIFT) ==
11844                                SHARED_HW_CFG_LED_EXTPHY2) ? 0x98 : 0x80;
11845
11846                         elink_cl45_write(sc, phy,
11847                                          MDIO_PMA_DEVAD,
11848                                          MDIO_PMA_REG_8481_LED1_MASK,
11849                                          val);
11850
11851                         /* Tell LED3 to blink on source */
11852                         elink_cl45_read(sc, phy,
11853                                         MDIO_PMA_DEVAD,
11854                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
11855                                         &val);
11856                         val &= ~(7 << 6);
11857                         val |= (1 << 6); /* A83B[8:6]= 1 */
11858                         elink_cl45_write(sc, phy,
11859                                          MDIO_PMA_DEVAD,
11860                                          MDIO_PMA_REG_8481_LINK_SIGNAL,
11861                                          val);
11862                         if (phy->type ==
11863                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834) {
11864                                 /* Restore LED4 source to external link,
11865                                  * and re-enable interrupts.
11866                                  */
11867                                 elink_cl45_write(sc, phy,
11868                                                  MDIO_PMA_DEVAD,
11869                                                  MDIO_PMA_REG_8481_SIGNAL_MASK,
11870                                                  0x40);
11871                                 if (params->link_flags &
11872                                     ELINK_LINK_FLAGS_INT_DISABLED) {
11873                                         elink_link_int_enable(params);
11874                                         params->link_flags &=
11875                                                 ~ELINK_LINK_FLAGS_INT_DISABLED;
11876                                 }
11877                         }
11878                 }
11879                 break;
11880         }
11881
11882         /* This is a workaround for E3 + 84833 until autoneg
11883          * restart is fixed in f/w
11884          */
11885         if (CHIP_IS_E3(sc)) {
11886                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
11887                                 MDIO_WC_REG_GP2_STATUS_GP_2_1, &val);
11888         }
11889 }
11890
11891 /******************************************************************/
11892 /*                      54618SE PHY SECTION                       */
11893 /******************************************************************/
11894 static void elink_54618se_specific_func(struct elink_phy *phy,
11895                                         struct elink_params *params,
11896                                         uint32_t action)
11897 {
11898         struct bnx2x_softc *sc = params->sc;
11899         uint16_t temp;
11900         switch (action) {
11901         case ELINK_PHY_INIT:
11902                 /* Configure LED4: set to INTR (0x6). */
11903                 /* Accessing shadow register 0xe. */
11904                 elink_cl22_write(sc, phy,
11905                                  MDIO_REG_GPHY_SHADOW,
11906                                  MDIO_REG_GPHY_SHADOW_LED_SEL2);
11907                 elink_cl22_read(sc, phy,
11908                                 MDIO_REG_GPHY_SHADOW,
11909                                 &temp);
11910                 temp &= ~(0xf << 4);
11911                 temp |= (0x6 << 4);
11912                 elink_cl22_write(sc, phy,
11913                                  MDIO_REG_GPHY_SHADOW,
11914                                  MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
11915                 /* Configure INTR based on link status change. */
11916                 elink_cl22_write(sc, phy,
11917                                  MDIO_REG_INTR_MASK,
11918                                  ~MDIO_REG_INTR_MASK_LINK_STATUS);
11919                 break;
11920         }
11921 }
11922
11923 static uint8_t elink_54618se_config_init(struct elink_phy *phy,
11924                                                struct elink_params *params,
11925                                                struct elink_vars *vars)
11926 {
11927         struct bnx2x_softc *sc = params->sc;
11928         uint8_t port;
11929         uint16_t autoneg_val, an_1000_val, an_10_100_val, fc_val, temp;
11930         uint32_t cfg_pin;
11931
11932         ELINK_DEBUG_P0(sc, "54618SE cfg init");
11933         DELAY(1000 * 1);
11934
11935         /* This works with E3 only, no need to check the chip
11936          * before determining the port.
11937          */
11938         port = params->port;
11939
11940         cfg_pin = (REG_RD(sc, params->shmem_base +
11941                         offsetof(struct shmem_region,
11942                         dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
11943                         PORT_HW_CFG_E3_PHY_RESET_MASK) >>
11944                         PORT_HW_CFG_E3_PHY_RESET_SHIFT;
11945
11946         /* Drive pin high to bring the GPHY out of reset. */
11947         elink_set_cfg_pin(sc, cfg_pin, 1);
11948
11949         /* wait for GPHY to reset */
11950         DELAY(1000 * 50);
11951
11952         /* reset phy */
11953         elink_cl22_write(sc, phy,
11954                          MDIO_PMA_REG_CTRL, 0x8000);
11955         elink_wait_reset_complete(sc, phy, params);
11956
11957         /* Wait for GPHY to reset */
11958         DELAY(1000 * 50);
11959
11960
11961         elink_54618se_specific_func(phy, params, ELINK_PHY_INIT);
11962         /* Flip the signal detect polarity (set 0x1c.0x1e[8]). */
11963         elink_cl22_write(sc, phy,
11964                         MDIO_REG_GPHY_SHADOW,
11965                         MDIO_REG_GPHY_SHADOW_AUTO_DET_MED);
11966         elink_cl22_read(sc, phy,
11967                         MDIO_REG_GPHY_SHADOW,
11968                         &temp);
11969         temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD;
11970         elink_cl22_write(sc, phy,
11971                         MDIO_REG_GPHY_SHADOW,
11972                         MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
11973
11974         /* Set up fc */
11975         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
11976         elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
11977         fc_val = 0;
11978         if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
11979                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC)
11980                 fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
11981
11982         if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
11983                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
11984                 fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
11985
11986         /* Read all advertisement */
11987         elink_cl22_read(sc, phy,
11988                         0x09,
11989                         &an_1000_val);
11990
11991         elink_cl22_read(sc, phy,
11992                         0x04,
11993                         &an_10_100_val);
11994
11995         elink_cl22_read(sc, phy,
11996                         MDIO_PMA_REG_CTRL,
11997                         &autoneg_val);
11998
11999         /* Disable forced speed */
12000         autoneg_val &= ~((1 << 6) | (1 << 8) | (1 << 9) | (1 << 12) |
12001                          (1 << 13));
12002         an_10_100_val &= ~((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) |
12003                            (1 << 10) | (1 << 11));
12004
12005         if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
12006                         (phy->speed_cap_mask &
12007                         PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
12008                         (phy->req_line_speed == ELINK_SPEED_1000)) {
12009                 an_1000_val |= (1 << 8);
12010                 autoneg_val |= (1 << 9 | 1 << 12);
12011                 if (phy->req_duplex == DUPLEX_FULL)
12012                         an_1000_val |= (1 << 9);
12013                 ELINK_DEBUG_P0(sc, "Advertising 1G");
12014         } else
12015                 an_1000_val &= ~((1 << 8) | (1 << 9));
12016
12017         elink_cl22_write(sc, phy,
12018                         0x09,
12019                         an_1000_val);
12020         elink_cl22_read(sc, phy,
12021                         0x09,
12022                         &an_1000_val);
12023
12024         /* Advertise 10/100 link speed */
12025         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
12026                 if (phy->speed_cap_mask &
12027                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) {
12028                         an_10_100_val |= (1 << 5);
12029                         autoneg_val |= (1 << 9 | 1 << 12);
12030                         ELINK_DEBUG_P0(sc, "Advertising 10M-HD");
12031                 }
12032                 if (phy->speed_cap_mask &
12033                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) {
12034                         an_10_100_val |= (1 << 6);
12035                         autoneg_val |= (1 << 9 | 1 << 12);
12036                         ELINK_DEBUG_P0(sc, "Advertising 10M-FD");
12037                 }
12038                 if (phy->speed_cap_mask &
12039                     PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
12040                         an_10_100_val |= (1 << 7);
12041                         autoneg_val |= (1 << 9 | 1 << 12);
12042                         ELINK_DEBUG_P0(sc, "Advertising 100M-HD");
12043                 }
12044                 if (phy->speed_cap_mask &
12045                     PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
12046                         an_10_100_val |= (1 << 8);
12047                         autoneg_val |= (1 << 9 | 1 << 12);
12048                         ELINK_DEBUG_P0(sc, "Advertising 100M-FD");
12049                 }
12050         }
12051
12052         /* Only 10/100 are allowed to work in FORCE mode */
12053         if (phy->req_line_speed == ELINK_SPEED_100) {
12054                 autoneg_val |= (1 << 13);
12055                 /* Enabled AUTO-MDIX when autoneg is disabled */
12056                 elink_cl22_write(sc, phy,
12057                                 0x18,
12058                                 (1 << 15 | 1 << 9 | 7 << 0));
12059                 ELINK_DEBUG_P0(sc, "Setting 100M force");
12060         }
12061         if (phy->req_line_speed == ELINK_SPEED_10) {
12062                 /* Enabled AUTO-MDIX when autoneg is disabled */
12063                 elink_cl22_write(sc, phy,
12064                                 0x18,
12065                                 (1 << 15 | 1 << 9 | 7 << 0));
12066                 ELINK_DEBUG_P0(sc, "Setting 10M force");
12067         }
12068
12069         if ((phy->flags & ELINK_FLAGS_EEE) && elink_eee_has_cap(params)) {
12070                 elink_status_t rc;
12071
12072                 elink_cl22_write(sc, phy, MDIO_REG_GPHY_EXP_ACCESS,
12073                                  MDIO_REG_GPHY_EXP_ACCESS_TOP |
12074                                  MDIO_REG_GPHY_EXP_TOP_2K_BUF);
12075                 elink_cl22_read(sc, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, &temp);
12076                 temp &= 0xfffe;
12077                 elink_cl22_write(sc, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, temp);
12078
12079                 rc = elink_eee_initial_config(params, vars, SHMEM_EEE_1G_ADV);
12080                 if (rc != ELINK_STATUS_OK) {
12081                         ELINK_DEBUG_P0(sc, "Failed to configure EEE timers");
12082                         elink_eee_disable(phy, params, vars);
12083                 } else if ((params->eee_mode & ELINK_EEE_MODE_ADV_LPI) &&
12084                            (phy->req_duplex == DUPLEX_FULL) &&
12085                            (elink_eee_calc_timer(params) ||
12086                             !(params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI))) {
12087                         /* Need to advertise EEE only when requested,
12088                          * and either no LPI assertion was requested,
12089                          * or it was requested and a valid timer was set.
12090                          * Also notice full duplex is required for EEE.
12091                          */
12092                         elink_eee_advertise(phy, params, vars,
12093                                             SHMEM_EEE_1G_ADV);
12094                 } else {
12095                         ELINK_DEBUG_P0(sc, "Don't Advertise 1GBase-T EEE");
12096                         elink_eee_disable(phy, params, vars);
12097                 }
12098         } else {
12099                 vars->eee_status &= ((uint32_t)(~SHMEM_EEE_1G_ADV) <<
12100                                     SHMEM_EEE_SUPPORTED_SHIFT);
12101
12102                 if (phy->flags & ELINK_FLAGS_EEE) {
12103                         /* Handle legacy auto-grEEEn */
12104                         if (params->feature_config_flags &
12105                             ELINK_FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
12106                                 temp = 6;
12107                                 ELINK_DEBUG_P0(sc, "Enabling Auto-GrEEEn");
12108                         } else {
12109                                 temp = 0;
12110                                 ELINK_DEBUG_P0(sc, "Don't Adv. EEE");
12111                         }
12112                         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
12113                                          MDIO_AN_REG_EEE_ADV, temp);
12114                 }
12115         }
12116
12117         elink_cl22_write(sc, phy,
12118                         0x04,
12119                         an_10_100_val | fc_val);
12120
12121         if (phy->req_duplex == DUPLEX_FULL)
12122                 autoneg_val |= (1 << 8);
12123
12124         elink_cl22_write(sc, phy,
12125                         MDIO_PMA_REG_CTRL, autoneg_val);
12126
12127         return ELINK_STATUS_OK;
12128 }
12129
12130
12131 static void elink_5461x_set_link_led(struct elink_phy *phy,
12132                                      struct elink_params *params, uint8_t mode)
12133 {
12134         struct bnx2x_softc *sc = params->sc;
12135         uint16_t temp;
12136
12137         elink_cl22_write(sc, phy,
12138                 MDIO_REG_GPHY_SHADOW,
12139                 MDIO_REG_GPHY_SHADOW_LED_SEL1);
12140         elink_cl22_read(sc, phy,
12141                 MDIO_REG_GPHY_SHADOW,
12142                 &temp);
12143         temp &= 0xff00;
12144
12145         ELINK_DEBUG_P1(sc, "54618x set link led (mode=%x)", mode);
12146         switch (mode) {
12147         case ELINK_LED_MODE_FRONT_PANEL_OFF:
12148         case ELINK_LED_MODE_OFF:
12149                 temp |= 0x00ee;
12150                 break;
12151         case ELINK_LED_MODE_OPER:
12152                 temp |= 0x0001;
12153                 break;
12154         case ELINK_LED_MODE_ON:
12155                 temp |= 0x00ff;
12156                 break;
12157         default:
12158                 break;
12159         }
12160         elink_cl22_write(sc, phy,
12161                 MDIO_REG_GPHY_SHADOW,
12162                 MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
12163         return;
12164 }
12165
12166
12167 static void elink_54618se_link_reset(struct elink_phy *phy,
12168                                      struct elink_params *params)
12169 {
12170         struct bnx2x_softc *sc = params->sc;
12171         uint32_t cfg_pin;
12172         uint8_t port;
12173
12174         /* In case of no EPIO routed to reset the GPHY, put it
12175          * in low power mode.
12176          */
12177         elink_cl22_write(sc, phy, MDIO_PMA_REG_CTRL, 0x800);
12178         /* This works with E3 only, no need to check the chip
12179          * before determining the port.
12180          */
12181         port = params->port;
12182         cfg_pin = (REG_RD(sc, params->shmem_base +
12183                         offsetof(struct shmem_region,
12184                         dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
12185                         PORT_HW_CFG_E3_PHY_RESET_MASK) >>
12186                         PORT_HW_CFG_E3_PHY_RESET_SHIFT;
12187
12188         /* Drive pin low to put GPHY in reset. */
12189         elink_set_cfg_pin(sc, cfg_pin, 0);
12190 }
12191
12192 static uint8_t elink_54618se_read_status(struct elink_phy *phy,
12193                                     struct elink_params *params,
12194                                     struct elink_vars *vars)
12195 {
12196         struct bnx2x_softc *sc = params->sc;
12197         uint16_t val;
12198         uint8_t link_up = 0;
12199         uint16_t legacy_status, legacy_speed;
12200
12201         /* Get speed operation status */
12202         elink_cl22_read(sc, phy,
12203                         MDIO_REG_GPHY_AUX_STATUS,
12204                         &legacy_status);
12205         ELINK_DEBUG_P1(sc, "54618SE read_status: 0x%x", legacy_status);
12206
12207         /* Read status to clear the PHY interrupt. */
12208         elink_cl22_read(sc, phy,
12209                         MDIO_REG_INTR_STATUS,
12210                         &val);
12211
12212         link_up = ((legacy_status & (1 << 2)) == (1 << 2));
12213
12214         if (link_up) {
12215                 legacy_speed = (legacy_status & (7 << 8));
12216                 if (legacy_speed == (7 << 8)) {
12217                         vars->line_speed = ELINK_SPEED_1000;
12218                         vars->duplex = DUPLEX_FULL;
12219                 } else if (legacy_speed == (6 << 8)) {
12220                         vars->line_speed = ELINK_SPEED_1000;
12221                         vars->duplex = DUPLEX_HALF;
12222                 } else if (legacy_speed == (5 << 8)) {
12223                         vars->line_speed = ELINK_SPEED_100;
12224                         vars->duplex = DUPLEX_FULL;
12225                 }
12226                 /* Omitting 100Base-T4 for now */
12227                 else if (legacy_speed == (3 << 8)) {
12228                         vars->line_speed = ELINK_SPEED_100;
12229                         vars->duplex = DUPLEX_HALF;
12230                 } else if (legacy_speed == (2 << 8)) {
12231                         vars->line_speed = ELINK_SPEED_10;
12232                         vars->duplex = DUPLEX_FULL;
12233                 } else if (legacy_speed == (1 << 8)) {
12234                         vars->line_speed = ELINK_SPEED_10;
12235                         vars->duplex = DUPLEX_HALF;
12236                 } else /* Should not happen */
12237                         vars->line_speed = 0;
12238
12239                 ELINK_DEBUG_P2(sc,
12240                    "Link is up in %dMbps, is_duplex_full= %d",
12241                    vars->line_speed,
12242                    (vars->duplex == DUPLEX_FULL));
12243
12244                 /* Check legacy speed AN resolution */
12245                 elink_cl22_read(sc, phy,
12246                                 0x01,
12247                                 &val);
12248                 if (val & (1 << 5))
12249                         vars->link_status |=
12250                                 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
12251                 elink_cl22_read(sc, phy,
12252                                 0x06,
12253                                 &val);
12254                 if ((val & (1 << 0)) == 0)
12255                         vars->link_status |=
12256                                 LINK_STATUS_PARALLEL_DETECTION_USED;
12257
12258                 ELINK_DEBUG_P1(sc, "BNX2X4618SE: link speed is %d",
12259                            vars->line_speed);
12260
12261                 elink_ext_phy_resolve_fc(phy, params, vars);
12262
12263                 if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
12264                         /* Report LP advertised speeds */
12265                         elink_cl22_read(sc, phy, 0x5, &val);
12266
12267                         if (val & (1 << 5))
12268                                 vars->link_status |=
12269                                   LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
12270                         if (val & (1 << 6))
12271                                 vars->link_status |=
12272                                   LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
12273                         if (val & (1 << 7))
12274                                 vars->link_status |=
12275                                   LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
12276                         if (val & (1 << 8))
12277                                 vars->link_status |=
12278                                   LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
12279                         if (val & (1 << 9))
12280                                 vars->link_status |=
12281                                   LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
12282
12283                         elink_cl22_read(sc, phy, 0xa, &val);
12284                         if (val & (1 << 10))
12285                                 vars->link_status |=
12286                                   LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
12287                         if (val & (1 << 11))
12288                                 vars->link_status |=
12289                                   LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
12290
12291                         if ((phy->flags & ELINK_FLAGS_EEE) &&
12292                             elink_eee_has_cap(params))
12293                                 elink_eee_an_resolve(phy, params, vars);
12294                 }
12295         }
12296         return link_up;
12297 }
12298
12299 static void elink_54618se_config_loopback(struct elink_phy *phy,
12300                                           struct elink_params *params)
12301 {
12302         struct bnx2x_softc *sc = params->sc;
12303         uint16_t val;
12304         uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
12305
12306         ELINK_DEBUG_P0(sc, "2PMA/PMD ext_phy_loopback: 54618se");
12307
12308         /* Enable master/slave manual mmode and set to master */
12309         /* mii write 9 [bits set 11 12] */
12310         elink_cl22_write(sc, phy, 0x09, 3 << 11);
12311
12312         /* forced 1G and disable autoneg */
12313         /* set val [mii read 0] */
12314         /* set val [expr $val & [bits clear 6 12 13]] */
12315         /* set val [expr $val | [bits set 6 8]] */
12316         /* mii write 0 $val */
12317         elink_cl22_read(sc, phy, 0x00, &val);
12318         val &= ~((1 << 6) | (1 << 12) | (1 << 13));
12319         val |= (1 << 6) | (1 << 8);
12320         elink_cl22_write(sc, phy, 0x00, val);
12321
12322         /* Set external loopback and Tx using 6dB coding */
12323         /* mii write 0x18 7 */
12324         /* set val [mii read 0x18] */
12325         /* mii write 0x18 [expr $val | [bits set 10 15]] */
12326         elink_cl22_write(sc, phy, 0x18, 7);
12327         elink_cl22_read(sc, phy, 0x18, &val);
12328         elink_cl22_write(sc, phy, 0x18, val | (1 << 10) | (1 << 15));
12329
12330         /* This register opens the gate for the UMAC despite its name */
12331         REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port * 4, 1);
12332
12333         /* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
12334          * length used by the MAC receive logic to check frames.
12335          */
12336         REG_WR(sc, umac_base + UMAC_REG_MAXFR, 0x2710);
12337 }
12338
12339 /******************************************************************/
12340 /*                      SFX7101 PHY SECTION                       */
12341 /******************************************************************/
12342 static void elink_7101_config_loopback(struct elink_phy *phy,
12343                                        struct elink_params *params)
12344 {
12345         struct bnx2x_softc *sc = params->sc;
12346         /* SFX7101_XGXS_TEST1 */
12347         elink_cl45_write(sc, phy,
12348                          MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
12349 }
12350
12351 static uint8_t elink_7101_config_init(struct elink_phy *phy,
12352                                   struct elink_params *params,
12353                                   struct elink_vars *vars)
12354 {
12355         uint16_t fw_ver1, fw_ver2, val;
12356         struct bnx2x_softc *sc = params->sc;
12357         ELINK_DEBUG_P0(sc, "Setting the SFX7101 LASI indication");
12358
12359         /* Restore normal power mode*/
12360         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
12361                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
12362         /* HW reset */
12363         elink_ext_phy_hw_reset(sc, params->port);
12364         elink_wait_reset_complete(sc, phy, params);
12365
12366         elink_cl45_write(sc, phy,
12367                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x1);
12368         ELINK_DEBUG_P0(sc, "Setting the SFX7101 LED to blink on traffic");
12369         elink_cl45_write(sc, phy,
12370                          MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1 << 3));
12371
12372         elink_ext_phy_set_pause(params, phy, vars);
12373         /* Restart autoneg */
12374         elink_cl45_read(sc, phy,
12375                         MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
12376         val |= 0x200;
12377         elink_cl45_write(sc, phy,
12378                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
12379
12380         /* Save spirom version */
12381         elink_cl45_read(sc, phy,
12382                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
12383
12384         elink_cl45_read(sc, phy,
12385                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
12386         elink_save_spirom_version(sc, params->port,
12387                                   (uint32_t)(fw_ver1 << 16 | fw_ver2),
12388                                   phy->ver_addr);
12389         return ELINK_STATUS_OK;
12390 }
12391
12392 static uint8_t elink_7101_read_status(struct elink_phy *phy,
12393                                  struct elink_params *params,
12394                                  struct elink_vars *vars)
12395 {
12396         struct bnx2x_softc *sc = params->sc;
12397         uint8_t link_up;
12398         uint16_t val1, val2;
12399         elink_cl45_read(sc, phy,
12400                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
12401         elink_cl45_read(sc, phy,
12402                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
12403         ELINK_DEBUG_P2(sc, "10G-base-T LASI status 0x%x->0x%x",
12404                    val2, val1);
12405         elink_cl45_read(sc, phy,
12406                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
12407         elink_cl45_read(sc, phy,
12408                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
12409         ELINK_DEBUG_P2(sc, "10G-base-T PMA status 0x%x->0x%x",
12410                    val2, val1);
12411         link_up = ((val1 & 4) == 4);
12412         /* If link is up print the AN outcome of the SFX7101 PHY */
12413         if (link_up) {
12414                 elink_cl45_read(sc, phy,
12415                                 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
12416                                 &val2);
12417                 vars->line_speed = ELINK_SPEED_10000;
12418                 vars->duplex = DUPLEX_FULL;
12419                 ELINK_DEBUG_P2(sc, "SFX7101 AN status 0x%x->Master=%x",
12420                            val2, (val2 & (1 << 14)));
12421                 elink_ext_phy_10G_an_resolve(sc, phy, vars);
12422                 elink_ext_phy_resolve_fc(phy, params, vars);
12423
12424                 /* Read LP advertised speeds */
12425                 if (val2 & (1 << 11))
12426                         vars->link_status |=
12427                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
12428         }
12429         return link_up;
12430 }
12431
12432 static elink_status_t elink_7101_format_ver(uint32_t spirom_ver, uint8_t *str,
12433                                             uint16_t *len)
12434 {
12435         if (*len < 5)
12436                 return ELINK_STATUS_ERROR;
12437         str[0] = (spirom_ver & 0xFF);
12438         str[1] = (spirom_ver & 0xFF00) >> 8;
12439         str[2] = (spirom_ver & 0xFF0000) >> 16;
12440         str[3] = (spirom_ver & 0xFF000000) >> 24;
12441         str[4] = '\0';
12442         *len -= 5;
12443         return ELINK_STATUS_OK;
12444 }
12445
12446 void elink_sfx7101_sp_sw_reset(struct bnx2x_softc *sc, struct elink_phy *phy)
12447 {
12448         uint16_t val, cnt;
12449
12450         elink_cl45_read(sc, phy,
12451                         MDIO_PMA_DEVAD,
12452                         MDIO_PMA_REG_7101_RESET, &val);
12453
12454         for (cnt = 0; cnt < 10; cnt++) {
12455                 DELAY(1000 * 50);
12456                 /* Writes a self-clearing reset */
12457                 elink_cl45_write(sc, phy,
12458                                  MDIO_PMA_DEVAD,
12459                                  MDIO_PMA_REG_7101_RESET,
12460                                  (val | (1 << 15)));
12461                 /* Wait for clear */
12462                 elink_cl45_read(sc, phy,
12463                                 MDIO_PMA_DEVAD,
12464                                 MDIO_PMA_REG_7101_RESET, &val);
12465
12466                 if ((val & (1 << 15)) == 0)
12467                         break;
12468         }
12469 }
12470
12471 static void elink_7101_hw_reset(__rte_unused struct elink_phy *phy,
12472                                 struct elink_params *params) {
12473         /* Low power mode is controlled by GPIO 2 */
12474         elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_2,
12475                        MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
12476         /* The PHY reset is controlled by GPIO 1 */
12477         elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
12478                        MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
12479 }
12480
12481 static void elink_7101_set_link_led(struct elink_phy *phy,
12482                                     struct elink_params *params, uint8_t mode)
12483 {
12484         uint16_t val = 0;
12485         struct bnx2x_softc *sc = params->sc;
12486         switch (mode) {
12487         case ELINK_LED_MODE_FRONT_PANEL_OFF:
12488         case ELINK_LED_MODE_OFF:
12489                 val = 2;
12490                 break;
12491         case ELINK_LED_MODE_ON:
12492                 val = 1;
12493                 break;
12494         case ELINK_LED_MODE_OPER:
12495                 val = 0;
12496                 break;
12497         }
12498         elink_cl45_write(sc, phy,
12499                          MDIO_PMA_DEVAD,
12500                          MDIO_PMA_REG_7107_LINK_LED_CNTL,
12501                          val);
12502 }
12503
12504 /******************************************************************/
12505 /*                      STATIC PHY DECLARATION                    */
12506 /******************************************************************/
12507
12508 static const struct elink_phy phy_null = {
12509         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
12510         .addr           = 0,
12511         .def_md_devad   = 0,
12512         .flags          = ELINK_FLAGS_INIT_XGXS_FIRST,
12513         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12514         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12515         .mdio_ctrl      = 0,
12516         .supported      = 0,
12517         .media_type     = ELINK_ETH_PHY_NOT_PRESENT,
12518         .ver_addr       = 0,
12519         .req_flow_ctrl  = 0,
12520         .req_line_speed = 0,
12521         .speed_cap_mask = 0,
12522         .req_duplex     = 0,
12523         .rsrv           = 0,
12524         .config_init    = (config_init_t)NULL,
12525         .read_status    = (read_status_t)NULL,
12526         .link_reset     = (link_reset_t)NULL,
12527         .config_loopback = (config_loopback_t)NULL,
12528         .format_fw_ver  = (format_fw_ver_t)NULL,
12529         .hw_reset       = (hw_reset_t)NULL,
12530         .set_link_led   = (set_link_led_t)NULL,
12531         .phy_specific_func = (phy_specific_func_t)NULL
12532 };
12533
12534 static const struct elink_phy phy_serdes = {
12535         .type           = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
12536         .addr           = 0xff,
12537         .def_md_devad   = 0,
12538         .flags          = 0,
12539         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12540         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12541         .mdio_ctrl      = 0,
12542         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12543                            ELINK_SUPPORTED_10baseT_Full |
12544                            ELINK_SUPPORTED_100baseT_Half |
12545                            ELINK_SUPPORTED_100baseT_Full |
12546                            ELINK_SUPPORTED_1000baseT_Full |
12547                            ELINK_SUPPORTED_2500baseX_Full |
12548                            ELINK_SUPPORTED_TP |
12549                            ELINK_SUPPORTED_Autoneg |
12550                            ELINK_SUPPORTED_Pause |
12551                            ELINK_SUPPORTED_Asym_Pause),
12552         .media_type     = ELINK_ETH_PHY_BASE_T,
12553         .ver_addr       = 0,
12554         .req_flow_ctrl  = 0,
12555         .req_line_speed = 0,
12556         .speed_cap_mask = 0,
12557         .req_duplex     = 0,
12558         .rsrv           = 0,
12559         .config_init    = (config_init_t)elink_xgxs_config_init,
12560         .read_status    = (read_status_t)elink_link_settings_status,
12561         .link_reset     = (link_reset_t)elink_int_link_reset,
12562         .config_loopback = (config_loopback_t)NULL,
12563         .format_fw_ver  = (format_fw_ver_t)NULL,
12564         .hw_reset       = (hw_reset_t)NULL,
12565         .set_link_led   = (set_link_led_t)NULL,
12566         .phy_specific_func = (phy_specific_func_t)NULL
12567 };
12568
12569 static const struct elink_phy phy_xgxs = {
12570         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
12571         .addr           = 0xff,
12572         .def_md_devad   = 0,
12573         .flags          = 0,
12574         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12575         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12576         .mdio_ctrl      = 0,
12577         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12578                            ELINK_SUPPORTED_10baseT_Full |
12579                            ELINK_SUPPORTED_100baseT_Half |
12580                            ELINK_SUPPORTED_100baseT_Full |
12581                            ELINK_SUPPORTED_1000baseT_Full |
12582                            ELINK_SUPPORTED_2500baseX_Full |
12583                            ELINK_SUPPORTED_10000baseT_Full |
12584                            ELINK_SUPPORTED_FIBRE |
12585                            ELINK_SUPPORTED_Autoneg |
12586                            ELINK_SUPPORTED_Pause |
12587                            ELINK_SUPPORTED_Asym_Pause),
12588         .media_type     = ELINK_ETH_PHY_CX4,
12589         .ver_addr       = 0,
12590         .req_flow_ctrl  = 0,
12591         .req_line_speed = 0,
12592         .speed_cap_mask = 0,
12593         .req_duplex     = 0,
12594         .rsrv           = 0,
12595         .config_init    = (config_init_t)elink_xgxs_config_init,
12596         .read_status    = (read_status_t)elink_link_settings_status,
12597         .link_reset     = (link_reset_t)elink_int_link_reset,
12598         .config_loopback = (config_loopback_t)elink_set_xgxs_loopback,
12599         .format_fw_ver  = (format_fw_ver_t)NULL,
12600         .hw_reset       = (hw_reset_t)NULL,
12601         .set_link_led   = (set_link_led_t)NULL,
12602         .phy_specific_func = (phy_specific_func_t)elink_xgxs_specific_func
12603 };
12604 static const struct elink_phy phy_warpcore = {
12605         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
12606         .addr           = 0xff,
12607         .def_md_devad   = 0,
12608         .flags          = ELINK_FLAGS_TX_ERROR_CHECK,
12609         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12610         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12611         .mdio_ctrl      = 0,
12612         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12613                            ELINK_SUPPORTED_10baseT_Full |
12614                            ELINK_SUPPORTED_100baseT_Half |
12615                            ELINK_SUPPORTED_100baseT_Full |
12616                            ELINK_SUPPORTED_1000baseT_Full |
12617                            ELINK_SUPPORTED_1000baseKX_Full |
12618                            ELINK_SUPPORTED_10000baseT_Full |
12619                            ELINK_SUPPORTED_10000baseKR_Full |
12620                            ELINK_SUPPORTED_20000baseKR2_Full |
12621                            ELINK_SUPPORTED_20000baseMLD2_Full |
12622                            ELINK_SUPPORTED_FIBRE |
12623                            ELINK_SUPPORTED_Autoneg |
12624                            ELINK_SUPPORTED_Pause |
12625                            ELINK_SUPPORTED_Asym_Pause),
12626         .media_type     = ELINK_ETH_PHY_UNSPECIFIED,
12627         .ver_addr       = 0,
12628         .req_flow_ctrl  = 0,
12629         .req_line_speed = 0,
12630         .speed_cap_mask = 0,
12631         /* req_duplex = */0,
12632         /* rsrv = */0,
12633         .config_init    = (config_init_t)elink_warpcore_config_init,
12634         .read_status    = (read_status_t)elink_warpcore_read_status,
12635         .link_reset     = (link_reset_t)elink_warpcore_link_reset,
12636         .config_loopback = (config_loopback_t)elink_set_warpcore_loopback,
12637         .format_fw_ver  = (format_fw_ver_t)NULL,
12638         .hw_reset       = (hw_reset_t)elink_warpcore_hw_reset,
12639         .set_link_led   = (set_link_led_t)NULL,
12640         .phy_specific_func = (phy_specific_func_t)NULL
12641 };
12642
12643
12644 static const struct elink_phy phy_7101 = {
12645         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
12646         .addr           = 0xff,
12647         .def_md_devad   = 0,
12648         .flags          = ELINK_FLAGS_FAN_FAILURE_DET_REQ,
12649         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12650         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12651         .mdio_ctrl      = 0,
12652         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12653                            ELINK_SUPPORTED_TP |
12654                            ELINK_SUPPORTED_Autoneg |
12655                            ELINK_SUPPORTED_Pause |
12656                            ELINK_SUPPORTED_Asym_Pause),
12657         .media_type     = ELINK_ETH_PHY_BASE_T,
12658         .ver_addr       = 0,
12659         .req_flow_ctrl  = 0,
12660         .req_line_speed = 0,
12661         .speed_cap_mask = 0,
12662         .req_duplex     = 0,
12663         .rsrv           = 0,
12664         .config_init    = (config_init_t)elink_7101_config_init,
12665         .read_status    = (read_status_t)elink_7101_read_status,
12666         .link_reset     = (link_reset_t)elink_common_ext_link_reset,
12667         .config_loopback = (config_loopback_t)elink_7101_config_loopback,
12668         .format_fw_ver  = (format_fw_ver_t)elink_7101_format_ver,
12669         .hw_reset       = (hw_reset_t)elink_7101_hw_reset,
12670         .set_link_led   = (set_link_led_t)elink_7101_set_link_led,
12671         .phy_specific_func = (phy_specific_func_t)NULL
12672 };
12673 static const struct elink_phy phy_8073 = {
12674         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8073,
12675         .addr           = 0xff,
12676         .def_md_devad   = 0,
12677         .flags          = 0,
12678         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12679         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12680         .mdio_ctrl      = 0,
12681         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12682                            ELINK_SUPPORTED_2500baseX_Full |
12683                            ELINK_SUPPORTED_1000baseT_Full |
12684                            ELINK_SUPPORTED_FIBRE |
12685                            ELINK_SUPPORTED_Autoneg |
12686                            ELINK_SUPPORTED_Pause |
12687                            ELINK_SUPPORTED_Asym_Pause),
12688         .media_type     = ELINK_ETH_PHY_KR,
12689         .ver_addr       = 0,
12690         .req_flow_ctrl  = 0,
12691         .req_line_speed = 0,
12692         .speed_cap_mask = 0,
12693         .req_duplex     = 0,
12694         .rsrv           = 0,
12695         .config_init    = (config_init_t)elink_8073_config_init,
12696         .read_status    = (read_status_t)elink_8073_read_status,
12697         .link_reset     = (link_reset_t)elink_8073_link_reset,
12698         .config_loopback = (config_loopback_t)NULL,
12699         .format_fw_ver  = (format_fw_ver_t)elink_format_ver,
12700         .hw_reset       = (hw_reset_t)NULL,
12701         .set_link_led   = (set_link_led_t)NULL,
12702         .phy_specific_func = (phy_specific_func_t)elink_8073_specific_func
12703 };
12704 static const struct elink_phy phy_8705 = {
12705         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8705,
12706         .addr           = 0xff,
12707         .def_md_devad   = 0,
12708         .flags          = ELINK_FLAGS_INIT_XGXS_FIRST,
12709         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12710         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12711         .mdio_ctrl      = 0,
12712         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12713                            ELINK_SUPPORTED_FIBRE |
12714                            ELINK_SUPPORTED_Pause |
12715                            ELINK_SUPPORTED_Asym_Pause),
12716         .media_type     = ELINK_ETH_PHY_XFP_FIBER,
12717         .ver_addr       = 0,
12718         .req_flow_ctrl  = 0,
12719         .req_line_speed = 0,
12720         .speed_cap_mask = 0,
12721         .req_duplex     = 0,
12722         .rsrv           = 0,
12723         .config_init    = (config_init_t)elink_8705_config_init,
12724         .read_status    = (read_status_t)elink_8705_read_status,
12725         .link_reset     = (link_reset_t)elink_common_ext_link_reset,
12726         .config_loopback = (config_loopback_t)NULL,
12727         .format_fw_ver  = (format_fw_ver_t)elink_null_format_ver,
12728         .hw_reset       = (hw_reset_t)NULL,
12729         .set_link_led   = (set_link_led_t)NULL,
12730         .phy_specific_func = (phy_specific_func_t)NULL
12731 };
12732 static const struct elink_phy phy_8706 = {
12733         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8706,
12734         .addr           = 0xff,
12735         .def_md_devad   = 0,
12736         .flags          = ELINK_FLAGS_INIT_XGXS_FIRST,
12737         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12738         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12739         .mdio_ctrl      = 0,
12740         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12741                            ELINK_SUPPORTED_1000baseT_Full |
12742                            ELINK_SUPPORTED_FIBRE |
12743                            ELINK_SUPPORTED_Pause |
12744                            ELINK_SUPPORTED_Asym_Pause),
12745         .media_type     = ELINK_ETH_PHY_SFPP_10G_FIBER,
12746         .ver_addr       = 0,
12747         .req_flow_ctrl  = 0,
12748         .req_line_speed = 0,
12749         .speed_cap_mask = 0,
12750         .req_duplex     = 0,
12751         .rsrv           = 0,
12752         .config_init    = (config_init_t)elink_8706_config_init,
12753         .read_status    = (read_status_t)elink_8706_read_status,
12754         .link_reset     = (link_reset_t)elink_common_ext_link_reset,
12755         .config_loopback = (config_loopback_t)NULL,
12756         .format_fw_ver  = (format_fw_ver_t)elink_format_ver,
12757         .hw_reset       = (hw_reset_t)NULL,
12758         .set_link_led   = (set_link_led_t)NULL,
12759         .phy_specific_func = (phy_specific_func_t)NULL
12760 };
12761
12762 static const struct elink_phy phy_8726 = {
12763         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726,
12764         .addr           = 0xff,
12765         .def_md_devad   = 0,
12766         .flags          = (ELINK_FLAGS_INIT_XGXS_FIRST |
12767                            ELINK_FLAGS_TX_ERROR_CHECK),
12768         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12769         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12770         .mdio_ctrl      = 0,
12771         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12772                            ELINK_SUPPORTED_1000baseT_Full |
12773                            ELINK_SUPPORTED_Autoneg |
12774                            ELINK_SUPPORTED_FIBRE |
12775                            ELINK_SUPPORTED_Pause |
12776                            ELINK_SUPPORTED_Asym_Pause),
12777         .media_type     = ELINK_ETH_PHY_NOT_PRESENT,
12778         .ver_addr       = 0,
12779         .req_flow_ctrl  = 0,
12780         .req_line_speed = 0,
12781         .speed_cap_mask = 0,
12782         .req_duplex     = 0,
12783         .rsrv           = 0,
12784         .config_init    = (config_init_t)elink_8726_config_init,
12785         .read_status    = (read_status_t)elink_8726_read_status,
12786         .link_reset     = (link_reset_t)elink_8726_link_reset,
12787         .config_loopback = (config_loopback_t)elink_8726_config_loopback,
12788         .format_fw_ver  = (format_fw_ver_t)elink_format_ver,
12789         .hw_reset       = (hw_reset_t)NULL,
12790         .set_link_led   = (set_link_led_t)NULL,
12791         .phy_specific_func = (phy_specific_func_t)NULL
12792 };
12793
12794 static const struct elink_phy phy_8727 = {
12795         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727,
12796         .addr           = 0xff,
12797         .def_md_devad   = 0,
12798         .flags          = (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12799                            ELINK_FLAGS_TX_ERROR_CHECK),
12800         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12801         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12802         .mdio_ctrl      = 0,
12803         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12804                            ELINK_SUPPORTED_1000baseT_Full |
12805                            ELINK_SUPPORTED_FIBRE |
12806                            ELINK_SUPPORTED_Pause |
12807                            ELINK_SUPPORTED_Asym_Pause),
12808         .media_type     = ELINK_ETH_PHY_NOT_PRESENT,
12809         .ver_addr       = 0,
12810         .req_flow_ctrl  = 0,
12811         .req_line_speed = 0,
12812         .speed_cap_mask = 0,
12813         .req_duplex     = 0,
12814         .rsrv           = 0,
12815         .config_init    = (config_init_t)elink_8727_config_init,
12816         .read_status    = (read_status_t)elink_8727_read_status,
12817         .link_reset     = (link_reset_t)elink_8727_link_reset,
12818         .config_loopback = (config_loopback_t)NULL,
12819         .format_fw_ver  = (format_fw_ver_t)elink_format_ver,
12820         .hw_reset       = (hw_reset_t)elink_8727_hw_reset,
12821         .set_link_led   = (set_link_led_t)elink_8727_set_link_led,
12822         .phy_specific_func = (phy_specific_func_t)elink_8727_specific_func
12823 };
12824 static const struct elink_phy phy_8481 = {
12825         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8481,
12826         .addr           = 0xff,
12827         .def_md_devad   = 0,
12828         .flags          = ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12829                           ELINK_FLAGS_REARM_LATCH_SIGNAL,
12830         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12831         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12832         .mdio_ctrl      = 0,
12833         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12834                            ELINK_SUPPORTED_10baseT_Full |
12835                            ELINK_SUPPORTED_100baseT_Half |
12836                            ELINK_SUPPORTED_100baseT_Full |
12837                            ELINK_SUPPORTED_1000baseT_Full |
12838                            ELINK_SUPPORTED_10000baseT_Full |
12839                            ELINK_SUPPORTED_TP |
12840                            ELINK_SUPPORTED_Autoneg |
12841                            ELINK_SUPPORTED_Pause |
12842                            ELINK_SUPPORTED_Asym_Pause),
12843         .media_type     = ELINK_ETH_PHY_BASE_T,
12844         .ver_addr       = 0,
12845         .req_flow_ctrl  = 0,
12846         .req_line_speed = 0,
12847         .speed_cap_mask = 0,
12848         .req_duplex     = 0,
12849         .rsrv           = 0,
12850         .config_init    = (config_init_t)elink_8481_config_init,
12851         .read_status    = (read_status_t)elink_848xx_read_status,
12852         .link_reset     = (link_reset_t)elink_8481_link_reset,
12853         .config_loopback = (config_loopback_t)NULL,
12854         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12855         .hw_reset       = (hw_reset_t)elink_8481_hw_reset,
12856         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12857         .phy_specific_func = (phy_specific_func_t)NULL
12858 };
12859
12860 static const struct elink_phy phy_84823 = {
12861         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823,
12862         .addr           = 0xff,
12863         .def_md_devad   = 0,
12864         .flags          = (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12865                            ELINK_FLAGS_REARM_LATCH_SIGNAL |
12866                            ELINK_FLAGS_TX_ERROR_CHECK),
12867         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12868         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12869         .mdio_ctrl      = 0,
12870         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12871                            ELINK_SUPPORTED_10baseT_Full |
12872                            ELINK_SUPPORTED_100baseT_Half |
12873                            ELINK_SUPPORTED_100baseT_Full |
12874                            ELINK_SUPPORTED_1000baseT_Full |
12875                            ELINK_SUPPORTED_10000baseT_Full |
12876                            ELINK_SUPPORTED_TP |
12877                            ELINK_SUPPORTED_Autoneg |
12878                            ELINK_SUPPORTED_Pause |
12879                            ELINK_SUPPORTED_Asym_Pause),
12880         .media_type     = ELINK_ETH_PHY_BASE_T,
12881         .ver_addr       = 0,
12882         .req_flow_ctrl  = 0,
12883         .req_line_speed = 0,
12884         .speed_cap_mask = 0,
12885         .req_duplex     = 0,
12886         .rsrv           = 0,
12887         .config_init    = (config_init_t)elink_848x3_config_init,
12888         .read_status    = (read_status_t)elink_848xx_read_status,
12889         .link_reset     = (link_reset_t)elink_848x3_link_reset,
12890         .config_loopback = (config_loopback_t)NULL,
12891         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12892         .hw_reset       = (hw_reset_t)NULL,
12893         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12894         .phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12895 };
12896
12897 static const struct elink_phy phy_84833 = {
12898         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84833,
12899         .addr           = 0xff,
12900         .def_md_devad   = 0,
12901         .flags          = (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12902                            ELINK_FLAGS_REARM_LATCH_SIGNAL |
12903                            ELINK_FLAGS_TX_ERROR_CHECK |
12904                            ELINK_FLAGS_TEMPERATURE),
12905         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12906         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12907         .mdio_ctrl      = 0,
12908         .supported      = (ELINK_SUPPORTED_100baseT_Half |
12909                            ELINK_SUPPORTED_100baseT_Full |
12910                            ELINK_SUPPORTED_1000baseT_Full |
12911                            ELINK_SUPPORTED_10000baseT_Full |
12912                            ELINK_SUPPORTED_TP |
12913                            ELINK_SUPPORTED_Autoneg |
12914                            ELINK_SUPPORTED_Pause |
12915                            ELINK_SUPPORTED_Asym_Pause),
12916         .media_type     = ELINK_ETH_PHY_BASE_T,
12917         .ver_addr       = 0,
12918         .req_flow_ctrl  = 0,
12919         .req_line_speed = 0,
12920         .speed_cap_mask = 0,
12921         .req_duplex     = 0,
12922         .rsrv           = 0,
12923         .config_init    = (config_init_t)elink_848x3_config_init,
12924         .read_status    = (read_status_t)elink_848xx_read_status,
12925         .link_reset     = (link_reset_t)elink_848x3_link_reset,
12926         .config_loopback = (config_loopback_t)NULL,
12927         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12928         .hw_reset       = (hw_reset_t)elink_84833_hw_reset_phy,
12929         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12930         .phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12931 };
12932
12933 static const struct elink_phy phy_84834 = {
12934         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834,
12935         .addr           = 0xff,
12936         .def_md_devad   = 0,
12937         .flags          = ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12938                             ELINK_FLAGS_REARM_LATCH_SIGNAL,
12939         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12940         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12941         .mdio_ctrl      = 0,
12942         .supported      = (ELINK_SUPPORTED_100baseT_Half |
12943                            ELINK_SUPPORTED_100baseT_Full |
12944                            ELINK_SUPPORTED_1000baseT_Full |
12945                            ELINK_SUPPORTED_10000baseT_Full |
12946                            ELINK_SUPPORTED_TP |
12947                            ELINK_SUPPORTED_Autoneg |
12948                            ELINK_SUPPORTED_Pause |
12949                            ELINK_SUPPORTED_Asym_Pause),
12950         .media_type     = ELINK_ETH_PHY_BASE_T,
12951         .ver_addr       = 0,
12952         .req_flow_ctrl  = 0,
12953         .req_line_speed = 0,
12954         .speed_cap_mask = 0,
12955         .req_duplex     = 0,
12956         .rsrv           = 0,
12957         .config_init    = (config_init_t)elink_848x3_config_init,
12958         .read_status    = (read_status_t)elink_848xx_read_status,
12959         .link_reset     = (link_reset_t)elink_848x3_link_reset,
12960         .config_loopback = (config_loopback_t)NULL,
12961         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12962         .hw_reset       = (hw_reset_t)elink_84833_hw_reset_phy,
12963         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12964         .phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12965 };
12966
12967 static const struct elink_phy phy_84858 = {
12968         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858,
12969         .addr           = 0xff,
12970         .def_md_devad   = 0,
12971         .flags          = ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12972                             ELINK_FLAGS_REARM_LATCH_SIGNAL,
12973         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12974         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12975         .mdio_ctrl      = 0,
12976         .supported      = (ELINK_SUPPORTED_100baseT_Half |
12977                            ELINK_SUPPORTED_100baseT_Full |
12978                            ELINK_SUPPORTED_1000baseT_Full |
12979                            ELINK_SUPPORTED_10000baseT_Full |
12980                            ELINK_SUPPORTED_TP |
12981                            ELINK_SUPPORTED_Autoneg |
12982                            ELINK_SUPPORTED_Pause |
12983                            ELINK_SUPPORTED_Asym_Pause),
12984         .media_type     = ELINK_ETH_PHY_BASE_T,
12985         .ver_addr       = 0,
12986         .req_flow_ctrl  = 0,
12987         .req_line_speed = 0,
12988         .speed_cap_mask = 0,
12989         .req_duplex     = 0,
12990         .rsrv           = 0,
12991         .config_init    = (config_init_t)elink_848x3_config_init,
12992         .read_status    = (read_status_t)elink_848xx_read_status,
12993         .link_reset     = (link_reset_t)elink_848x3_link_reset,
12994         .config_loopback = (config_loopback_t)NULL,
12995         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12996         .hw_reset       = (hw_reset_t)elink_84833_hw_reset_phy,
12997         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12998         .phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12999 };
13000
13001
13002 static const struct elink_phy phy_54618se = {
13003         .type           = PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE,
13004         .addr           = 0xff,
13005         .def_md_devad   = 0,
13006         .flags          = ELINK_FLAGS_INIT_XGXS_FIRST,
13007         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
13008         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
13009         .mdio_ctrl      = 0,
13010         .supported      = (ELINK_SUPPORTED_10baseT_Half |
13011                            ELINK_SUPPORTED_10baseT_Full |
13012                            ELINK_SUPPORTED_100baseT_Half |
13013                            ELINK_SUPPORTED_100baseT_Full |
13014                            ELINK_SUPPORTED_1000baseT_Full |
13015                            ELINK_SUPPORTED_TP |
13016                            ELINK_SUPPORTED_Autoneg |
13017                            ELINK_SUPPORTED_Pause |
13018                            ELINK_SUPPORTED_Asym_Pause),
13019         .media_type     = ELINK_ETH_PHY_BASE_T,
13020         .ver_addr       = 0,
13021         .req_flow_ctrl  = 0,
13022         .req_line_speed = 0,
13023         .speed_cap_mask = 0,
13024         /* req_duplex = */0,
13025         /* rsrv = */0,
13026         .config_init    = (config_init_t)elink_54618se_config_init,
13027         .read_status    = (read_status_t)elink_54618se_read_status,
13028         .link_reset     = (link_reset_t)elink_54618se_link_reset,
13029         .config_loopback = (config_loopback_t)elink_54618se_config_loopback,
13030         .format_fw_ver  = (format_fw_ver_t)NULL,
13031         .hw_reset       = (hw_reset_t)NULL,
13032         .set_link_led   = (set_link_led_t)elink_5461x_set_link_led,
13033         .phy_specific_func = (phy_specific_func_t)elink_54618se_specific_func
13034 };
13035 /*****************************************************************/
13036 /*                                                               */
13037 /* Populate the phy according. Main function: elink_populate_phy   */
13038 /*                                                               */
13039 /*****************************************************************/
13040
13041 static void elink_populate_preemphasis(struct bnx2x_softc *sc,
13042                                      uint32_t shmem_base,
13043                                      struct elink_phy *phy, uint8_t port,
13044                                      uint8_t phy_index)
13045 {
13046         /* Get the 4 lanes xgxs config rx and tx */
13047         uint32_t rx = 0, tx = 0, i;
13048         for (i = 0; i < 2; i++) {
13049                 /* INT_PHY and ELINK_EXT_PHY1 share the same value location in
13050                  * the shmem. When num_phys is greater than 1, than this value
13051                  * applies only to ELINK_EXT_PHY1
13052                  */
13053                 if (phy_index == ELINK_INT_PHY || phy_index == ELINK_EXT_PHY1) {
13054                         rx = REG_RD(sc, shmem_base +
13055                                     offsetof(struct shmem_region,
13056                         dev_info.port_hw_config[port].xgxs_config_rx[i << 1]));
13057
13058                         tx = REG_RD(sc, shmem_base +
13059                                     offsetof(struct shmem_region,
13060                         dev_info.port_hw_config[port].xgxs_config_tx[i << 1]));
13061                 } else {
13062                         rx = REG_RD(sc, shmem_base +
13063                                     offsetof(struct shmem_region,
13064                         dev_info.port_hw_config[port].xgxs_config2_rx[i << 1]));
13065
13066                         tx = REG_RD(sc, shmem_base +
13067                                     offsetof(struct shmem_region,
13068                         dev_info.port_hw_config[port].xgxs_config2_rx[i << 1]));
13069                 }
13070
13071                 phy->rx_preemphasis[i << 1] = ((rx >> 16) & 0xffff);
13072                 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
13073
13074                 phy->tx_preemphasis[i << 1] = ((tx >> 16) & 0xffff);
13075                 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
13076                 ELINK_DEBUG_P2(sc, "phy->rx_preemphasis = %x, phy->tx_preemphasis = %x",
13077                         phy->rx_preemphasis[i << 1],
13078                         phy->tx_preemphasis[i << 1]);
13079         }
13080 }
13081
13082 static uint32_t elink_get_ext_phy_config(struct bnx2x_softc *sc,
13083                                     uint32_t shmem_base,
13084                                     uint8_t phy_index, uint8_t port)
13085 {
13086         uint32_t ext_phy_config = 0;
13087         switch (phy_index) {
13088         case ELINK_EXT_PHY1:
13089                 ext_phy_config = REG_RD(sc, shmem_base +
13090                                               offsetof(struct shmem_region,
13091                         dev_info.port_hw_config[port].external_phy_config));
13092                 break;
13093         case ELINK_EXT_PHY2:
13094                 ext_phy_config = REG_RD(sc, shmem_base +
13095                                               offsetof(struct shmem_region,
13096                         dev_info.port_hw_config[port].external_phy_config2));
13097                 break;
13098         default:
13099                 ELINK_DEBUG_P1(sc, "Invalid phy_index %d", phy_index);
13100                 return ELINK_STATUS_ERROR;
13101         }
13102
13103         return ext_phy_config;
13104 }
13105 static elink_status_t elink_populate_int_phy(struct bnx2x_softc *sc,
13106                                   uint32_t shmem_base, uint8_t port,
13107                                   struct elink_phy *phy)
13108 {
13109         uint32_t phy_addr;
13110         uint32_t chip_id;
13111         uint32_t switch_cfg = (REG_RD(sc, shmem_base +
13112                                        offsetof(struct shmem_region,
13113                         dev_info.port_feature_config[port].link_config)) &
13114                           PORT_FEATURE_CONNECTED_SWITCH_MASK);
13115         chip_id = (REG_RD(sc, MISC_REG_CHIP_NUM) << 16) |
13116                 ((REG_RD(sc, MISC_REG_CHIP_REV) & 0xf) << 12);
13117
13118         ELINK_DEBUG_P1(sc, ":chip_id = 0x%x", chip_id);
13119         if (USES_WARPCORE(sc)) {
13120                 uint32_t serdes_net_if;
13121                 phy_addr = REG_RD(sc,
13122                                   MISC_REG_WC0_CTRL_PHY_ADDR);
13123                 *phy = phy_warpcore;
13124                 if (REG_RD(sc, MISC_REG_PORT4MODE_EN_OVWR) == 0x3)
13125                         phy->flags |= ELINK_FLAGS_4_PORT_MODE;
13126                 else
13127                         phy->flags &= ~ELINK_FLAGS_4_PORT_MODE;
13128                         /* Check Dual mode */
13129                 serdes_net_if = (REG_RD(sc, shmem_base +
13130                                         offsetof(struct shmem_region, dev_info.
13131                                         port_hw_config[port].default_cfg)) &
13132                                  PORT_HW_CFG_NET_SERDES_IF_MASK);
13133                 /* Set the appropriate supported and flags indications per
13134                  * interface type of the chip
13135                  */
13136                 switch (serdes_net_if) {
13137                 case PORT_HW_CFG_NET_SERDES_IF_SGMII:
13138                         phy->supported &= (ELINK_SUPPORTED_10baseT_Half |
13139                                            ELINK_SUPPORTED_10baseT_Full |
13140                                            ELINK_SUPPORTED_100baseT_Half |
13141                                            ELINK_SUPPORTED_100baseT_Full |
13142                                            ELINK_SUPPORTED_1000baseT_Full |
13143                                            ELINK_SUPPORTED_FIBRE |
13144                                            ELINK_SUPPORTED_Autoneg |
13145                                            ELINK_SUPPORTED_Pause |
13146                                            ELINK_SUPPORTED_Asym_Pause);
13147                         phy->media_type = ELINK_ETH_PHY_BASE_T;
13148                         break;
13149                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
13150                         phy->supported &= (ELINK_SUPPORTED_1000baseT_Full |
13151                                            ELINK_SUPPORTED_10000baseT_Full |
13152                                            ELINK_SUPPORTED_FIBRE |
13153                                            ELINK_SUPPORTED_Pause |
13154                                            ELINK_SUPPORTED_Asym_Pause);
13155                         phy->media_type = ELINK_ETH_PHY_XFP_FIBER;
13156                         break;
13157                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
13158                         phy->supported &= (ELINK_SUPPORTED_1000baseT_Full |
13159                                            ELINK_SUPPORTED_10000baseT_Full |
13160                                            ELINK_SUPPORTED_FIBRE |
13161                                            ELINK_SUPPORTED_Pause |
13162                                            ELINK_SUPPORTED_Asym_Pause);
13163                         phy->media_type = ELINK_ETH_PHY_SFPP_10G_FIBER;
13164                         break;
13165                 case PORT_HW_CFG_NET_SERDES_IF_KR:
13166                         phy->media_type = ELINK_ETH_PHY_KR;
13167                         phy->supported &= (ELINK_SUPPORTED_1000baseKX_Full |
13168                                            ELINK_SUPPORTED_10000baseKR_Full |
13169                                            ELINK_SUPPORTED_FIBRE |
13170                                            ELINK_SUPPORTED_Autoneg |
13171                                            ELINK_SUPPORTED_Pause |
13172                                            ELINK_SUPPORTED_Asym_Pause);
13173                         break;
13174                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
13175                         phy->media_type = ELINK_ETH_PHY_KR;
13176                         phy->flags |= ELINK_FLAGS_WC_DUAL_MODE;
13177                         phy->supported &= (ELINK_SUPPORTED_20000baseMLD2_Full |
13178                                            ELINK_SUPPORTED_FIBRE |
13179                                            ELINK_SUPPORTED_Pause |
13180                                            ELINK_SUPPORTED_Asym_Pause);
13181                         break;
13182                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
13183                         phy->media_type = ELINK_ETH_PHY_KR;
13184                         phy->flags |= ELINK_FLAGS_WC_DUAL_MODE;
13185                         phy->supported &= (ELINK_SUPPORTED_20000baseKR2_Full |
13186                                            ELINK_SUPPORTED_10000baseKR_Full |
13187                                            ELINK_SUPPORTED_1000baseKX_Full |
13188                                            ELINK_SUPPORTED_Autoneg |
13189                                            ELINK_SUPPORTED_FIBRE |
13190                                            ELINK_SUPPORTED_Pause |
13191                                            ELINK_SUPPORTED_Asym_Pause);
13192                         phy->flags &= ~ELINK_FLAGS_TX_ERROR_CHECK;
13193                         break;
13194                 default:
13195                         ELINK_DEBUG_P1(sc, "Unknown WC interface type 0x%x",
13196                                        serdes_net_if);
13197                         break;
13198                 }
13199
13200                 /* Enable MDC/MDIO work-around for E3 A0 since free running MDC
13201                  * was not set as expected. For B0, ECO will be enabled so there
13202                  * won't be an issue there
13203                  */
13204                 if (CHIP_REV(sc) == CHIP_REV_Ax)
13205                         phy->flags |= ELINK_FLAGS_MDC_MDIO_WA;
13206                 else
13207                         phy->flags |= ELINK_FLAGS_MDC_MDIO_WA_B0;
13208                 ELINK_DEBUG_P3(sc, "media_type = %x, flags = %x, supported = %x",
13209                                 phy->media_type, phy->flags, phy->supported);
13210         } else {
13211                 switch (switch_cfg) {
13212                 case ELINK_SWITCH_CFG_1G:
13213                         phy_addr = REG_RD(sc,
13214                                           NIG_REG_SERDES0_CTRL_PHY_ADDR +
13215                                           port * 0x10);
13216                         *phy = phy_serdes;
13217                         break;
13218                 case ELINK_SWITCH_CFG_10G:
13219                         phy_addr = REG_RD(sc,
13220                                           NIG_REG_XGXS0_CTRL_PHY_ADDR +
13221                                           port * 0x18);
13222                         *phy = phy_xgxs;
13223                         break;
13224                 default:
13225                         ELINK_DEBUG_P0(sc, "Invalid switch_cfg");
13226                         return ELINK_STATUS_ERROR;
13227                 }
13228         }
13229         phy->addr = (uint8_t)phy_addr;
13230         phy->mdio_ctrl = elink_get_emac_base(sc,
13231                                             SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
13232                                             port);
13233         if (CHIP_IS_E2(sc))
13234                 phy->def_md_devad = ELINK_E2_DEFAULT_PHY_DEV_ADDR;
13235         else
13236                 phy->def_md_devad = ELINK_DEFAULT_PHY_DEV_ADDR;
13237
13238         ELINK_DEBUG_P3(sc, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x",
13239                    port, phy->addr, phy->mdio_ctrl);
13240
13241         elink_populate_preemphasis(sc, shmem_base, phy, port, ELINK_INT_PHY);
13242         return ELINK_STATUS_OK;
13243 }
13244
13245 static elink_status_t elink_populate_ext_phy(struct bnx2x_softc *sc,
13246                                   uint8_t phy_index,
13247                                   uint32_t shmem_base,
13248                                   uint32_t shmem2_base,
13249                                   uint8_t port,
13250                                   struct elink_phy *phy)
13251 {
13252         uint32_t ext_phy_config, phy_type, config2;
13253         uint32_t mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
13254         ext_phy_config = elink_get_ext_phy_config(sc, shmem_base,
13255                                                   phy_index, port);
13256         phy_type = ELINK_XGXS_EXT_PHY_TYPE(ext_phy_config);
13257         /* Select the phy type */
13258         switch (phy_type) {
13259         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8073:
13260                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
13261                 *phy = phy_8073;
13262                 break;
13263         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8705:
13264                 *phy = phy_8705;
13265                 break;
13266         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8706:
13267                 *phy = phy_8706;
13268                 break;
13269         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726:
13270                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
13271                 *phy = phy_8726;
13272                 break;
13273         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727_NOC:
13274                 /* BNX2X8727_NOC => BNX2X8727 no over current */
13275                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
13276                 *phy = phy_8727;
13277                 phy->flags |= ELINK_FLAGS_NOC;
13278                 break;
13279         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
13280         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
13281                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
13282                 *phy = phy_8727;
13283                 break;
13284         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8481:
13285                 *phy = phy_8481;
13286                 break;
13287         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823:
13288                 *phy = phy_84823;
13289                 break;
13290         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84833:
13291                 *phy = phy_84833;
13292                 break;
13293         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834:
13294                 *phy = phy_84834;
13295                 break;
13296         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858:
13297                 *phy = phy_84858;
13298                 break;
13299         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X54616:
13300         case PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE:
13301                 *phy = phy_54618se;
13302                 if (phy_type == PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE)
13303                         phy->flags |= ELINK_FLAGS_EEE;
13304                 break;
13305         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
13306                 *phy = phy_7101;
13307                 break;
13308         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
13309                 *phy = phy_null;
13310                 return ELINK_STATUS_ERROR;
13311         default:
13312                 *phy = phy_null;
13313                 /* In case external PHY wasn't found */
13314                 if ((phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
13315                     (phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
13316                         return ELINK_STATUS_ERROR;
13317                 return ELINK_STATUS_OK;
13318         }
13319
13320         phy->addr = ELINK_XGXS_EXT_PHY_ADDR(ext_phy_config);
13321         elink_populate_preemphasis(sc, shmem_base, phy, port, phy_index);
13322
13323         /* The shmem address of the phy version is located on different
13324          * structures. In case this structure is too old, do not set
13325          * the address
13326          */
13327         config2 = REG_RD(sc, shmem_base + offsetof(struct shmem_region,
13328                                         dev_info.shared_hw_config.config2));
13329         if (phy_index == ELINK_EXT_PHY1) {
13330                 phy->ver_addr = shmem_base + offsetof(struct shmem_region,
13331                                 port_mb[port].ext_phy_fw_version);
13332
13333                 /* Check specific mdc mdio settings */
13334                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
13335                         mdc_mdio_access = config2 &
13336                         SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
13337         } else {
13338                 uint32_t size = REG_RD(sc, shmem2_base);
13339
13340                 if (size >
13341                     offsetof(struct shmem2_region, ext_phy_fw_version2)) {
13342                         phy->ver_addr = shmem2_base +
13343                             offsetof(struct shmem2_region,
13344                                      ext_phy_fw_version2[port]);
13345                 }
13346                 /* Check specific mdc mdio settings */
13347                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
13348                         mdc_mdio_access = (config2 &
13349                         SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
13350                         (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
13351                          SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
13352         }
13353         phy->mdio_ctrl = elink_get_emac_base(sc, mdc_mdio_access, port);
13354
13355         if (elink_is_8483x_8485x(phy) && (phy->ver_addr)) {
13356                 /* Remove 100Mb link supported for BNX2X84833/4 when phy fw
13357                  * version lower than or equal to 1.39
13358                  */
13359                 uint32_t raw_ver = REG_RD(sc, phy->ver_addr);
13360                 if (((raw_ver & 0x7F) <= 39) &&
13361                     (((raw_ver & 0xF80) >> 7) <= 1))
13362                         phy->supported &= ~(ELINK_SUPPORTED_100baseT_Half |
13363                                             ELINK_SUPPORTED_100baseT_Full);
13364         }
13365
13366         ELINK_DEBUG_P3(sc, "phy_type 0x%x port %d found in index %d",
13367                    phy_type, port, phy_index);
13368         ELINK_DEBUG_P2(sc, "             addr=0x%x, mdio_ctl=0x%x",
13369                    phy->addr, phy->mdio_ctrl);
13370         return ELINK_STATUS_OK;
13371 }
13372
13373 static elink_status_t elink_populate_phy(struct bnx2x_softc *sc,
13374                               uint8_t phy_index, uint32_t shmem_base,
13375                               uint32_t shmem2_base, uint8_t port,
13376                               struct elink_phy *phy)
13377 {
13378         elink_status_t status = ELINK_STATUS_OK;
13379         phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
13380         if (phy_index == ELINK_INT_PHY)
13381                 return elink_populate_int_phy(sc, shmem_base, port, phy);
13382         status = elink_populate_ext_phy(sc, phy_index, shmem_base, shmem2_base,
13383                                         port, phy);
13384         return status;
13385 }
13386
13387 static void elink_phy_def_cfg(struct elink_params *params,
13388                               struct elink_phy *phy,
13389                               uint8_t phy_index)
13390 {
13391         struct bnx2x_softc *sc = params->sc;
13392         uint32_t link_config;
13393         /* Populate the default phy configuration for MF mode */
13394         if (phy_index == ELINK_EXT_PHY2) {
13395                 link_config = REG_RD(sc, params->shmem_base +
13396                                      offsetof(struct shmem_region, dev_info.
13397                         port_feature_config[params->port].link_config2));
13398                 phy->speed_cap_mask = REG_RD(sc, params->shmem_base +
13399                                              offsetof(struct shmem_region,
13400                                                       dev_info.
13401                         port_hw_config[params->port].speed_capability_mask2));
13402         } else {
13403                 link_config = REG_RD(sc, params->shmem_base +
13404                                      offsetof(struct shmem_region, dev_info.
13405                                 port_feature_config[params->port].link_config));
13406                 phy->speed_cap_mask = REG_RD(sc, params->shmem_base +
13407                                              offsetof(struct shmem_region,
13408                                                       dev_info.
13409                         port_hw_config[params->port].speed_capability_mask));
13410         }
13411         ELINK_DEBUG_P3(sc,
13412            "Default config phy idx %x cfg 0x%x speed_cap_mask 0x%x",
13413            phy_index, link_config, phy->speed_cap_mask);
13414
13415         phy->req_duplex = DUPLEX_FULL;
13416         switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
13417         case PORT_FEATURE_LINK_SPEED_10M_HALF:
13418                 phy->req_duplex = DUPLEX_HALF;
13419                 /* fallthrough */
13420         case PORT_FEATURE_LINK_SPEED_10M_FULL:
13421                 phy->req_line_speed = ELINK_SPEED_10;
13422                 break;
13423         case PORT_FEATURE_LINK_SPEED_100M_HALF:
13424                 phy->req_duplex = DUPLEX_HALF;
13425                 /* fallthrough */
13426         case PORT_FEATURE_LINK_SPEED_100M_FULL:
13427                 phy->req_line_speed = ELINK_SPEED_100;
13428                 break;
13429         case PORT_FEATURE_LINK_SPEED_1G:
13430                 phy->req_line_speed = ELINK_SPEED_1000;
13431                 break;
13432         case PORT_FEATURE_LINK_SPEED_2_5G:
13433                 phy->req_line_speed = ELINK_SPEED_2500;
13434                 break;
13435         case PORT_FEATURE_LINK_SPEED_10G_CX4:
13436                 phy->req_line_speed = ELINK_SPEED_10000;
13437                 break;
13438         default:
13439                 phy->req_line_speed = ELINK_SPEED_AUTO_NEG;
13440                 break;
13441         }
13442
13443         ELINK_DEBUG_P2(sc, "Default config phy idx %x, req_duplex config %x",
13444                         phy_index, phy->req_duplex);
13445
13446         switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
13447         case PORT_FEATURE_FLOW_CONTROL_AUTO:
13448                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_AUTO;
13449                 break;
13450         case PORT_FEATURE_FLOW_CONTROL_TX:
13451                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_TX;
13452                 break;
13453         case PORT_FEATURE_FLOW_CONTROL_RX:
13454                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_RX;
13455                 break;
13456         case PORT_FEATURE_FLOW_CONTROL_BOTH:
13457                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_BOTH;
13458                 break;
13459         default:
13460                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_NONE;
13461                 break;
13462         }
13463         ELINK_DEBUG_P3(sc, "Requested Duplex = %x, line_speed = %x, flow_ctrl = %x",
13464                        phy->req_duplex, phy->req_line_speed,
13465                        phy->req_flow_ctrl);
13466 }
13467
13468 uint32_t elink_phy_selection(struct elink_params *params)
13469 {
13470         uint32_t phy_config_swapped, prio_cfg;
13471         uint32_t return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
13472
13473         phy_config_swapped = params->multi_phy_config &
13474                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
13475
13476         prio_cfg = params->multi_phy_config &
13477                         PORT_HW_CFG_PHY_SELECTION_MASK;
13478
13479         if (phy_config_swapped) {
13480                 switch (prio_cfg) {
13481                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
13482                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
13483                         break;
13484                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
13485                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
13486                         break;
13487                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
13488                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
13489                         break;
13490                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
13491                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
13492                         break;
13493                 }
13494         } else
13495                 return_cfg = prio_cfg;
13496
13497         return return_cfg;
13498 }
13499
13500 elink_status_t elink_phy_probe(struct elink_params *params)
13501 {
13502         uint8_t phy_index, actual_phy_idx;
13503         uint32_t phy_config_swapped, sync_offset, media_types;
13504         struct bnx2x_softc *sc = params->sc;
13505         struct elink_phy *phy;
13506         params->num_phys = 0;
13507         ELINK_DEBUG_P0(sc, "Begin phy probe");
13508 #ifdef ELINK_INCLUDE_EMUL
13509         if (CHIP_REV_IS_EMUL(sc))
13510                 return ELINK_STATUS_OK;
13511 #endif
13512         phy_config_swapped = params->multi_phy_config &
13513                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
13514
13515         for (phy_index = ELINK_INT_PHY; phy_index < ELINK_MAX_PHYS;
13516               phy_index++) {
13517                 actual_phy_idx = phy_index;
13518                 if (phy_config_swapped) {
13519                         if (phy_index == ELINK_EXT_PHY1)
13520                                 actual_phy_idx = ELINK_EXT_PHY2;
13521                         else if (phy_index == ELINK_EXT_PHY2)
13522                                 actual_phy_idx = ELINK_EXT_PHY1;
13523                 }
13524                 ELINK_DEBUG_P3(sc, "phy_config_swapped %x, phy_index %x,"
13525                                " actual_phy_idx %x", phy_config_swapped,
13526                            phy_index, actual_phy_idx);
13527                 phy = &params->phy[actual_phy_idx];
13528                 if (elink_populate_phy(sc, phy_index, params->shmem_base,
13529                                        params->shmem2_base, params->port,
13530                                        phy) != ELINK_STATUS_OK) {
13531                         params->num_phys = 0;
13532                         ELINK_DEBUG_P1(sc, "phy probe failed in phy index %d",
13533                                    phy_index);
13534                         for (phy_index = ELINK_INT_PHY;
13535                               phy_index < ELINK_MAX_PHYS;
13536                               phy_index++)
13537                                 *phy = phy_null;
13538                         return ELINK_STATUS_ERROR;
13539                 }
13540                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
13541                         break;
13542
13543                 if (params->feature_config_flags &
13544                     ELINK_FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET)
13545                         phy->flags &= ~ELINK_FLAGS_TX_ERROR_CHECK;
13546
13547                 if (!(params->feature_config_flags &
13548                       ELINK_FEATURE_CONFIG_MT_SUPPORT))
13549                         phy->flags |= ELINK_FLAGS_MDC_MDIO_WA_G;
13550
13551                 sync_offset = params->shmem_base +
13552                         offsetof(struct shmem_region,
13553                         dev_info.port_hw_config[params->port].media_type);
13554                 media_types = REG_RD(sc, sync_offset);
13555
13556                 /* Update media type for non-PMF sync only for the first time
13557                  * In case the media type changes afterwards, it will be updated
13558                  * using the update_status function
13559                  */
13560                 if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
13561                                     (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
13562                                      actual_phy_idx))) == 0) {
13563                         media_types |= ((phy->media_type &
13564                                         PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
13565                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
13566                                  actual_phy_idx));
13567                 }
13568                 REG_WR(sc, sync_offset, media_types);
13569
13570                 elink_phy_def_cfg(params, phy, phy_index);
13571                 params->num_phys++;
13572         }
13573
13574         ELINK_DEBUG_P1(sc, "End phy probe. #phys found %x", params->num_phys);
13575         return ELINK_STATUS_OK;
13576 }
13577
13578 #ifdef ELINK_INCLUDE_EMUL
13579 static elink_status_t elink_init_e3_emul_mac(struct elink_params *params,
13580                                              struct elink_vars *vars)
13581 {
13582         struct bnx2x_softc *sc = params->sc;
13583         vars->line_speed = params->req_line_speed[0];
13584         /* In case link speed is auto, set speed the highest as possible */
13585         if (params->req_line_speed[0] == ELINK_SPEED_AUTO_NEG) {
13586                 if (params->feature_config_flags &
13587                     ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC)
13588                         vars->line_speed = ELINK_SPEED_2500;
13589                 else if (elink_is_4_port_mode(sc))
13590                         vars->line_speed = ELINK_SPEED_10000;
13591                 else
13592                         vars->line_speed = ELINK_SPEED_20000;
13593         }
13594         if (vars->line_speed < ELINK_SPEED_10000) {
13595                 if ((params->feature_config_flags &
13596                      ELINK_FEATURE_CONFIG_EMUL_DISABLE_UMAC)) {
13597                         ELINK_DEBUG_P1(sc, "Invalid line speed %d while UMAC is"
13598                                    " disabled!", params->req_line_speed[0]);
13599                         return ELINK_STATUS_ERROR;
13600                 }
13601                 switch (vars->line_speed) {
13602                 case ELINK_SPEED_10:
13603                         vars->link_status = ELINK_LINK_10TFD;
13604                         break;
13605                 case ELINK_SPEED_100:
13606                         vars->link_status = ELINK_LINK_100TXFD;
13607                         break;
13608                 case ELINK_SPEED_1000:
13609                         vars->link_status = ELINK_LINK_1000TFD;
13610                         break;
13611                 case ELINK_SPEED_2500:
13612                         vars->link_status = ELINK_LINK_2500TFD;
13613                         break;
13614                 default:
13615                         ELINK_DEBUG_P1(sc, "Invalid line speed %d for UMAC",
13616                                    vars->line_speed);
13617                         return ELINK_STATUS_ERROR;
13618                 }
13619                 vars->link_status |= LINK_STATUS_LINK_UP;
13620
13621                 if (params->loopback_mode == ELINK_LOOPBACK_UMAC)
13622                         elink_umac_enable(params, vars, 1);
13623                 else
13624                         elink_umac_enable(params, vars, 0);
13625         } else {
13626                 /* Link speed >= 10000 requires XMAC enabled */
13627                 if (params->feature_config_flags &
13628                     ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC) {
13629                         ELINK_DEBUG_P1(sc, "Invalid line speed %d while XMAC is"
13630                                    " disabled!", params->req_line_speed[0]);
13631                 return ELINK_STATUS_ERROR;
13632         }
13633                 /* Check link speed */
13634                 switch (vars->line_speed) {
13635                 case ELINK_SPEED_10000:
13636                         vars->link_status = ELINK_LINK_10GTFD;
13637                         break;
13638                 case ELINK_SPEED_20000:
13639                         vars->link_status = ELINK_LINK_20GTFD;
13640                         break;
13641                 default:
13642                         ELINK_DEBUG_P1(sc, "Invalid line speed %d for XMAC",
13643                                    vars->line_speed);
13644                         return ELINK_STATUS_ERROR;
13645                 }
13646                 vars->link_status |= LINK_STATUS_LINK_UP;
13647                 if (params->loopback_mode == ELINK_LOOPBACK_XMAC)
13648                         elink_xmac_enable(params, vars, 1);
13649                 else
13650                         elink_xmac_enable(params, vars, 0);
13651         }
13652                 return ELINK_STATUS_OK;
13653 }
13654
13655 static elink_status_t elink_init_emul(struct elink_params *params,
13656                             struct elink_vars *vars)
13657 {
13658         struct bnx2x_softc *sc = params->sc;
13659         if (CHIP_IS_E3(sc)) {
13660                 if (elink_init_e3_emul_mac(params, vars) !=
13661                     ELINK_STATUS_OK)
13662                         return ELINK_STATUS_ERROR;
13663         } else {
13664                 if (params->feature_config_flags &
13665                     ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC) {
13666                         vars->line_speed = ELINK_SPEED_1000;
13667                         vars->link_status = (LINK_STATUS_LINK_UP |
13668                                              ELINK_LINK_1000XFD);
13669                         if (params->loopback_mode ==
13670                             ELINK_LOOPBACK_EMAC)
13671                                 elink_emac_enable(params, vars, 1);
13672                         else
13673                                 elink_emac_enable(params, vars, 0);
13674                 } else {
13675                         vars->line_speed = ELINK_SPEED_10000;
13676                         vars->link_status = (LINK_STATUS_LINK_UP |
13677                                              ELINK_LINK_10GTFD);
13678                         if (params->loopback_mode ==
13679                             ELINK_LOOPBACK_BMAC)
13680                                 elink_bmac_enable(params, vars, 1, 1);
13681                         else
13682                                 elink_bmac_enable(params, vars, 0, 1);
13683                 }
13684         }
13685         vars->link_up = 1;
13686         vars->duplex = DUPLEX_FULL;
13687         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13688
13689                 if (CHIP_IS_E1x(sc))
13690                         elink_pbf_update(params, vars->flow_ctrl,
13691                                          vars->line_speed);
13692                 /* Disable drain */
13693                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13694
13695                 /* update shared memory */
13696                 elink_update_mng(params, vars->link_status);
13697         return ELINK_STATUS_OK;
13698 }
13699 #endif
13700 #ifdef ELINK_INCLUDE_FPGA
13701 static elink_status_t elink_init_fpga(struct elink_params *params,
13702                             struct elink_vars *vars)
13703 {
13704         /* Enable on E1.5 FPGA */
13705         struct bnx2x_softc *sc = params->sc;
13706         vars->duplex = DUPLEX_FULL;
13707         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13708         if (!(CHIP_IS_E1(sc))) {
13709                 vars->flow_ctrl = (ELINK_FLOW_CTRL_TX |
13710                                    ELINK_FLOW_CTRL_RX);
13711                 vars->link_status |= (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
13712                                       LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
13713         }
13714         if (CHIP_IS_E3(sc)) {
13715                 vars->line_speed = params->req_line_speed[0];
13716                 switch (vars->line_speed) {
13717                 case ELINK_SPEED_AUTO_NEG:
13718                         vars->line_speed = ELINK_SPEED_2500;
13719                 case ELINK_SPEED_2500:
13720                         vars->link_status = ELINK_LINK_2500TFD;
13721                         break;
13722                 case ELINK_SPEED_1000:
13723                         vars->link_status = ELINK_LINK_1000XFD;
13724                         break;
13725                 case ELINK_SPEED_100:
13726                         vars->link_status = ELINK_LINK_100TXFD;
13727                         break;
13728                 case ELINK_SPEED_10:
13729                         vars->link_status = ELINK_LINK_10TFD;
13730                         break;
13731                 default:
13732                         ELINK_DEBUG_P1(sc, "Invalid link speed %d",
13733                                    params->req_line_speed[0]);
13734                         return ELINK_STATUS_ERROR;
13735                 }
13736                 vars->link_status |= LINK_STATUS_LINK_UP;
13737                 if (params->loopback_mode == ELINK_LOOPBACK_UMAC)
13738                         elink_umac_enable(params, vars, 1);
13739                 else
13740                         elink_umac_enable(params, vars, 0);
13741         } else {
13742                 vars->line_speed = ELINK_SPEED_10000;
13743                 vars->link_status = (LINK_STATUS_LINK_UP | ELINK_LINK_10GTFD);
13744                 if (params->loopback_mode == ELINK_LOOPBACK_EMAC)
13745                         elink_emac_enable(params, vars, 1);
13746                 else
13747                         elink_emac_enable(params, vars, 0);
13748         }
13749         vars->link_up = 1;
13750
13751         if (CHIP_IS_E1x(sc))
13752                 elink_pbf_update(params, vars->flow_ctrl,
13753                                  vars->line_speed);
13754         /* Disable drain */
13755         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13756
13757         /* Update shared memory */
13758         elink_update_mng(params, vars->link_status);
13759                 return ELINK_STATUS_OK;
13760 }
13761 #endif
13762 static void elink_init_bmac_loopback(struct elink_params *params,
13763                                      struct elink_vars *vars)
13764 {
13765         struct bnx2x_softc *sc = params->sc;
13766                 vars->link_up = 1;
13767                 vars->line_speed = ELINK_SPEED_10000;
13768                 vars->duplex = DUPLEX_FULL;
13769                 vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13770                 vars->mac_type = ELINK_MAC_TYPE_BMAC;
13771
13772                 vars->phy_flags = PHY_XGXS_FLAG;
13773
13774                 elink_xgxs_deassert(params);
13775
13776                 /* Set bmac loopback */
13777                 elink_bmac_enable(params, vars, 1, 1);
13778
13779                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13780 }
13781
13782 static void elink_init_emac_loopback(struct elink_params *params,
13783                                      struct elink_vars *vars)
13784 {
13785         struct bnx2x_softc *sc = params->sc;
13786                 vars->link_up = 1;
13787                 vars->line_speed = ELINK_SPEED_1000;
13788                 vars->duplex = DUPLEX_FULL;
13789                 vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13790                 vars->mac_type = ELINK_MAC_TYPE_EMAC;
13791
13792                 vars->phy_flags = PHY_XGXS_FLAG;
13793
13794                 elink_xgxs_deassert(params);
13795                 /* Set bmac loopback */
13796                 elink_emac_enable(params, vars, 1);
13797                 elink_emac_program(params, vars);
13798                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13799 }
13800
13801 static void elink_init_xmac_loopback(struct elink_params *params,
13802                                      struct elink_vars *vars)
13803 {
13804         struct bnx2x_softc *sc = params->sc;
13805         vars->link_up = 1;
13806         if (!params->req_line_speed[0])
13807                 vars->line_speed = ELINK_SPEED_10000;
13808         else
13809                 vars->line_speed = params->req_line_speed[0];
13810         vars->duplex = DUPLEX_FULL;
13811         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13812         vars->mac_type = ELINK_MAC_TYPE_XMAC;
13813         vars->phy_flags = PHY_XGXS_FLAG;
13814         /* Set WC to loopback mode since link is required to provide clock
13815          * to the XMAC in 20G mode
13816          */
13817         elink_set_aer_mmd(params, &params->phy[0]);
13818         elink_warpcore_reset_lane(sc, &params->phy[0], 0);
13819         params->phy[ELINK_INT_PHY].config_loopback(
13820                         &params->phy[ELINK_INT_PHY],
13821                         params);
13822
13823         elink_xmac_enable(params, vars, 1);
13824         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13825 }
13826
13827 static void elink_init_umac_loopback(struct elink_params *params,
13828                                      struct elink_vars *vars)
13829 {
13830         struct bnx2x_softc *sc = params->sc;
13831         vars->link_up = 1;
13832         vars->line_speed = ELINK_SPEED_1000;
13833         vars->duplex = DUPLEX_FULL;
13834         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13835         vars->mac_type = ELINK_MAC_TYPE_UMAC;
13836         vars->phy_flags = PHY_XGXS_FLAG;
13837         elink_umac_enable(params, vars, 1);
13838
13839         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13840 }
13841
13842 static void elink_init_xgxs_loopback(struct elink_params *params,
13843                                      struct elink_vars *vars)
13844 {
13845         struct bnx2x_softc *sc = params->sc;
13846         struct elink_phy *int_phy = &params->phy[ELINK_INT_PHY];
13847         vars->link_up = 1;
13848         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13849         vars->duplex = DUPLEX_FULL;
13850         if (params->req_line_speed[0] == ELINK_SPEED_1000)
13851                 vars->line_speed = ELINK_SPEED_1000;
13852         else if ((params->req_line_speed[0] == ELINK_SPEED_20000) ||
13853                  (int_phy->flags & ELINK_FLAGS_WC_DUAL_MODE))
13854                 vars->line_speed = ELINK_SPEED_20000;
13855         else
13856                 vars->line_speed = ELINK_SPEED_10000;
13857
13858         if (!USES_WARPCORE(sc))
13859                 elink_xgxs_deassert(params);
13860         elink_link_initialize(params, vars);
13861
13862         if (params->req_line_speed[0] == ELINK_SPEED_1000) {
13863                 if (USES_WARPCORE(sc))
13864                         elink_umac_enable(params, vars, 0);
13865                 else {
13866                         elink_emac_program(params, vars);
13867                         elink_emac_enable(params, vars, 0);
13868                 }
13869         } else {
13870                 if (USES_WARPCORE(sc))
13871                         elink_xmac_enable(params, vars, 0);
13872                 else
13873                         elink_bmac_enable(params, vars, 0, 1);
13874         }
13875
13876         if (params->loopback_mode == ELINK_LOOPBACK_XGXS) {
13877                 /* Set 10G XGXS loopback */
13878                 int_phy->config_loopback(int_phy, params);
13879         } else {
13880                 /* Set external phy loopback */
13881                 uint8_t phy_index;
13882                 for (phy_index = ELINK_EXT_PHY1;
13883                       phy_index < params->num_phys; phy_index++)
13884                         if (params->phy[phy_index].config_loopback)
13885                                 params->phy[phy_index].config_loopback(
13886                                         &params->phy[phy_index],
13887                                         params);
13888         }
13889         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13890
13891         elink_set_led(params, vars, ELINK_LED_MODE_OPER, vars->line_speed);
13892 }
13893
13894 void elink_set_rx_filter(struct elink_params *params, uint8_t en)
13895 {
13896         struct bnx2x_softc *sc = params->sc;
13897         uint8_t val = en * 0x1F;
13898
13899         /* Open / close the gate between the NIG and the BRB */
13900         if (!CHIP_IS_E1x(sc))
13901                 val |= en * 0x20;
13902         REG_WR(sc, NIG_REG_LLH0_BRB1_DRV_MASK + params->port * 4, val);
13903
13904         if (!CHIP_IS_E1(sc)) {
13905                 REG_WR(sc, NIG_REG_LLH0_BRB1_DRV_MASK_MF + params->port * 4,
13906                        en * 0x3);
13907         }
13908
13909         REG_WR(sc, (params->port ? NIG_REG_LLH1_BRB1_NOT_MCP :
13910                     NIG_REG_LLH0_BRB1_NOT_MCP), en);
13911 }
13912 static elink_status_t elink_avoid_link_flap(struct elink_params *params,
13913                                             struct elink_vars *vars)
13914 {
13915         uint32_t phy_idx;
13916         uint32_t dont_clear_stat, lfa_sts;
13917         struct bnx2x_softc *sc = params->sc;
13918
13919         elink_set_mdio_emac_per_phy(sc, params);
13920         /* Sync the link parameters */
13921         elink_link_status_update(params, vars);
13922
13923         /*
13924          * The module verification was already done by previous link owner,
13925          * so this call is meant only to get warning message
13926          */
13927
13928         for (phy_idx = ELINK_INT_PHY; phy_idx < params->num_phys; phy_idx++) {
13929                 struct elink_phy *phy = &params->phy[phy_idx];
13930                 if (phy->phy_specific_func) {
13931                         ELINK_DEBUG_P0(sc, "Calling PHY specific func");
13932                         phy->phy_specific_func(phy, params, ELINK_PHY_INIT);
13933                 }
13934                 if ((phy->media_type == ELINK_ETH_PHY_SFPP_10G_FIBER) ||
13935                     (phy->media_type == ELINK_ETH_PHY_SFP_1G_FIBER) ||
13936                     (phy->media_type == ELINK_ETH_PHY_DA_TWINAX))
13937                         elink_verify_sfp_module(phy, params);
13938         }
13939         lfa_sts = REG_RD(sc, params->lfa_base +
13940                          offsetof(struct shmem_lfa,
13941                                   lfa_sts));
13942
13943         dont_clear_stat = lfa_sts & SHMEM_LFA_DONT_CLEAR_STAT;
13944
13945         /* Re-enable the NIG/MAC */
13946         if (CHIP_IS_E3(sc)) {
13947                 if (!dont_clear_stat) {
13948                         REG_WR(sc, GRCBASE_MISC +
13949                                MISC_REGISTERS_RESET_REG_2_CLEAR,
13950                                (MISC_REGISTERS_RESET_REG_2_MSTAT0 <<
13951                                 params->port));
13952                         REG_WR(sc, GRCBASE_MISC +
13953                                MISC_REGISTERS_RESET_REG_2_SET,
13954                                (MISC_REGISTERS_RESET_REG_2_MSTAT0 <<
13955                                 params->port));
13956                 }
13957                 if (vars->line_speed < ELINK_SPEED_10000)
13958                         elink_umac_enable(params, vars, 0);
13959                 else
13960                         elink_xmac_enable(params, vars, 0);
13961         } else {
13962                 if (vars->line_speed < ELINK_SPEED_10000)
13963                         elink_emac_enable(params, vars, 0);
13964                 else
13965                         elink_bmac_enable(params, vars, 0, !dont_clear_stat);
13966         }
13967
13968         /* Increment LFA count */
13969         lfa_sts = ((lfa_sts & ~LINK_FLAP_AVOIDANCE_COUNT_MASK) |
13970                    (((((lfa_sts & LINK_FLAP_AVOIDANCE_COUNT_MASK) >>
13971                        LINK_FLAP_AVOIDANCE_COUNT_OFFSET) + 1) & 0xff)
13972                     << LINK_FLAP_AVOIDANCE_COUNT_OFFSET));
13973         /* Clear link flap reason */
13974         lfa_sts &= ~LFA_LINK_FLAP_REASON_MASK;
13975
13976         REG_WR(sc, params->lfa_base +
13977                offsetof(struct shmem_lfa, lfa_sts), lfa_sts);
13978
13979         /* Disable NIG DRAIN */
13980         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13981
13982         /* Enable interrupts */
13983         elink_link_int_enable(params);
13984         return ELINK_STATUS_OK;
13985 }
13986
13987 static void elink_cannot_avoid_link_flap(struct elink_params *params,
13988                                          struct elink_vars *vars,
13989                                          int lfa_status)
13990 {
13991         uint32_t lfa_sts, cfg_idx, tmp_val;
13992         struct bnx2x_softc *sc = params->sc;
13993
13994         elink_link_reset(params, vars, 1);
13995
13996         if (!params->lfa_base)
13997                 return;
13998         /* Store the new link parameters */
13999         REG_WR(sc, params->lfa_base +
14000                offsetof(struct shmem_lfa, req_duplex),
14001                params->req_duplex[0] | (params->req_duplex[1] << 16));
14002
14003         REG_WR(sc, params->lfa_base +
14004                offsetof(struct shmem_lfa, req_flow_ctrl),
14005                params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16));
14006
14007         REG_WR(sc, params->lfa_base +
14008                offsetof(struct shmem_lfa, req_line_speed),
14009                params->req_line_speed[0] | (params->req_line_speed[1] << 16));
14010
14011         for (cfg_idx = 0; cfg_idx < SHMEM_LINK_CONFIG_SIZE; cfg_idx++) {
14012                 REG_WR(sc, params->lfa_base +
14013                        offsetof(struct shmem_lfa,
14014                                 speed_cap_mask[cfg_idx]),
14015                        params->speed_cap_mask[cfg_idx]);
14016         }
14017
14018         tmp_val = REG_RD(sc, params->lfa_base +
14019                          offsetof(struct shmem_lfa, additional_config));
14020         tmp_val &= ~REQ_FC_AUTO_ADV_MASK;
14021         tmp_val |= params->req_fc_auto_adv;
14022
14023         REG_WR(sc, params->lfa_base +
14024                offsetof(struct shmem_lfa, additional_config), tmp_val);
14025
14026         lfa_sts = REG_RD(sc, params->lfa_base +
14027                          offsetof(struct shmem_lfa, lfa_sts));
14028
14029         /* Clear the "Don't Clear Statistics" bit, and set reason */
14030         lfa_sts &= ~SHMEM_LFA_DONT_CLEAR_STAT;
14031
14032         /* Set link flap reason */
14033         lfa_sts &= ~LFA_LINK_FLAP_REASON_MASK;
14034         lfa_sts |= ((lfa_status & LFA_LINK_FLAP_REASON_MASK) <<
14035                     LFA_LINK_FLAP_REASON_OFFSET);
14036
14037         /* Increment link flap counter */
14038         lfa_sts = ((lfa_sts & ~LINK_FLAP_COUNT_MASK) |
14039                    (((((lfa_sts & LINK_FLAP_COUNT_MASK) >>
14040                        LINK_FLAP_COUNT_OFFSET) + 1) & 0xff)
14041                     << LINK_FLAP_COUNT_OFFSET));
14042         REG_WR(sc, params->lfa_base +
14043                offsetof(struct shmem_lfa, lfa_sts), lfa_sts);
14044         /* Proceed with regular link initialization */
14045 }
14046
14047 elink_status_t elink_phy_init(struct elink_params *params,
14048                               struct elink_vars *vars)
14049 {
14050         int lfa_status;
14051         struct bnx2x_softc *sc = params->sc;
14052         ELINK_DEBUG_P0(sc, "Phy Initialization started");
14053         ELINK_DEBUG_P2(sc, "(1) req_speed %d, req_flowctrl %d",
14054                    params->req_line_speed[0], params->req_flow_ctrl[0]);
14055         ELINK_DEBUG_P2(sc, "(2) req_speed %d, req_flowctrl %d",
14056                    params->req_line_speed[1], params->req_flow_ctrl[1]);
14057         ELINK_DEBUG_P1(sc, "req_adv_flow_ctrl 0x%x", params->req_fc_auto_adv);
14058         vars->link_status = 0;
14059         vars->phy_link_up = 0;
14060         vars->link_up = 0;
14061         vars->line_speed = 0;
14062         vars->duplex = DUPLEX_FULL;
14063         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
14064         vars->mac_type = ELINK_MAC_TYPE_NONE;
14065         vars->phy_flags = 0;
14066         vars->check_kr2_recovery_cnt = 0;
14067         params->link_flags = ELINK_PHY_INITIALIZED;
14068         /* Driver opens NIG-BRB filters */
14069         elink_set_rx_filter(params, 1);
14070         elink_chng_link_count(params, 1);
14071         /* Check if link flap can be avoided */
14072         lfa_status = elink_check_lfa(params);
14073
14074         ELINK_DEBUG_P3(sc, " params : port = %x, loopback_mode = %x req_duplex = %x",
14075                        params->port, params->loopback_mode,
14076                        params->req_duplex[0]);
14077         ELINK_DEBUG_P3(sc, " params : switch_cfg = %x, lane_config = %x req_duplex[1] = %x",
14078                        params->switch_cfg, params->lane_config,
14079                        params->req_duplex[1]);
14080         ELINK_DEBUG_P3(sc, " params : chip_id = %x, feature_config_flags = %x, num_phys = %x",
14081                        params->chip_id, params->feature_config_flags,
14082                        params->num_phys);
14083         ELINK_DEBUG_P3(sc, " params : rsrv = %x, eee_mode = %x, hw_led_mode = %x",
14084                        params->rsrv, params->eee_mode, params->hw_led_mode);
14085         ELINK_DEBUG_P3(sc, " params : multi_phy = %x, req_fc_auto_adv = %x, link_flags = %x",
14086                        params->multi_phy_config, params->req_fc_auto_adv,
14087                        params->link_flags);
14088         ELINK_DEBUG_P2(sc, " params : lfa_base = %x, link_attr = %x",
14089                        params->lfa_base, params->link_attr_sync);
14090         if (lfa_status == 0) {
14091                 ELINK_DEBUG_P0(sc, "Link Flap Avoidance in progress");
14092                 return elink_avoid_link_flap(params, vars);
14093         }
14094
14095         ELINK_DEBUG_P1(sc, "Cannot avoid link flap lfa_sta=0x%x",
14096                        lfa_status);
14097         elink_cannot_avoid_link_flap(params, vars, lfa_status);
14098
14099         /* Disable attentions */
14100         elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + params->port * 4,
14101                        (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14102                         ELINK_NIG_MASK_XGXS0_LINK10G |
14103                         ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14104                         ELINK_NIG_MASK_MI_INT));
14105 #ifdef ELINK_INCLUDE_EMUL
14106         if (!(params->feature_config_flags &
14107               ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC))
14108 #endif
14109
14110         elink_emac_init(params, vars);
14111
14112         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
14113                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
14114
14115         if ((params->num_phys == 0) &&
14116             !CHIP_REV_IS_SLOW(sc)) {
14117                 ELINK_DEBUG_P0(sc, "No phy found for initialization !!");
14118                 return ELINK_STATUS_ERROR;
14119         }
14120         set_phy_vars(params, vars);
14121
14122         ELINK_DEBUG_P1(sc, "Num of phys on board: %d", params->num_phys);
14123 #ifdef ELINK_INCLUDE_FPGA
14124         if (CHIP_REV_IS_FPGA(sc)) {
14125                 return elink_init_fpga(params, vars);
14126         } else
14127 #endif
14128 #ifdef ELINK_INCLUDE_EMUL
14129         if (CHIP_REV_IS_EMUL(sc)) {
14130                 return elink_init_emul(params, vars);
14131         } else
14132 #endif
14133         switch (params->loopback_mode) {
14134         case ELINK_LOOPBACK_BMAC:
14135                 elink_init_bmac_loopback(params, vars);
14136                 break;
14137         case ELINK_LOOPBACK_EMAC:
14138                 elink_init_emac_loopback(params, vars);
14139                 break;
14140         case ELINK_LOOPBACK_XMAC:
14141                 elink_init_xmac_loopback(params, vars);
14142                 break;
14143         case ELINK_LOOPBACK_UMAC:
14144                 elink_init_umac_loopback(params, vars);
14145                 break;
14146         case ELINK_LOOPBACK_XGXS:
14147         case ELINK_LOOPBACK_EXT_PHY:
14148                 elink_init_xgxs_loopback(params, vars);
14149                 break;
14150         default:
14151                 if (!CHIP_IS_E3(sc)) {
14152                         if (params->switch_cfg == ELINK_SWITCH_CFG_10G)
14153                                 elink_xgxs_deassert(params);
14154                         else
14155                                 elink_serdes_deassert(sc, params->port);
14156                 }
14157                 elink_link_initialize(params, vars);
14158                 DELAY(1000 * 30);
14159                 elink_link_int_enable(params);
14160                 break;
14161         }
14162         elink_update_mng(params, vars->link_status);
14163
14164         elink_update_mng_eee(params, vars->eee_status);
14165         return ELINK_STATUS_OK;
14166 }
14167
14168 elink_status_t elink_link_reset(struct elink_params *params,
14169                      struct elink_vars *vars,
14170                      uint8_t reset_ext_phy)
14171 {
14172         struct bnx2x_softc *sc = params->sc;
14173         uint8_t phy_index, port = params->port, clear_latch_ind = 0;
14174         ELINK_DEBUG_P1(sc, "Resetting the link of port %d", port);
14175         /* Disable attentions */
14176         vars->link_status = 0;
14177         elink_chng_link_count(params, 1);
14178         elink_update_mng(params, vars->link_status);
14179         vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
14180                               SHMEM_EEE_ACTIVE_BIT);
14181         elink_update_mng_eee(params, vars->eee_status);
14182         elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port * 4,
14183                        (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14184                         ELINK_NIG_MASK_XGXS0_LINK10G |
14185                         ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14186                         ELINK_NIG_MASK_MI_INT));
14187
14188         /* Activate nig drain */
14189         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port * 4, 1);
14190
14191         /* Disable nig egress interface */
14192         if (!CHIP_IS_E3(sc)) {
14193                 REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port * 4, 0);
14194                 REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port * 4, 0);
14195         }
14196
14197 #ifdef ELINK_INCLUDE_EMUL
14198         /* Stop BigMac rx */
14199         if (!(params->feature_config_flags &
14200               ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC))
14201 #endif
14202                 if (!CHIP_IS_E3(sc))
14203                         elink_set_bmac_rx(sc, params->chip_id, port, 0);
14204 #ifdef ELINK_INCLUDE_EMUL
14205         /* Stop XMAC/UMAC rx */
14206         if (!(params->feature_config_flags &
14207               ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC))
14208 #endif
14209                 if (CHIP_IS_E3(sc) &&
14210                 !CHIP_REV_IS_FPGA(sc)) {
14211                         elink_set_xmac_rxtx(params, 0);
14212                         elink_set_umac_rxtx(params, 0);
14213                 }
14214         /* Disable emac */
14215         if (!CHIP_IS_E3(sc))
14216                 REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port * 4, 0);
14217
14218         DELAY(1000 * 10);
14219         /* The PHY reset is controlled by GPIO 1
14220          * Hold it as vars low
14221          */
14222          /* Clear link led */
14223         elink_set_mdio_emac_per_phy(sc, params);
14224         elink_set_led(params, vars, ELINK_LED_MODE_OFF, 0);
14225
14226         if (reset_ext_phy && (!CHIP_REV_IS_SLOW(sc))) {
14227                 for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
14228                       phy_index++) {
14229                         if (params->phy[phy_index].link_reset) {
14230                                 elink_set_aer_mmd(params,
14231                                                   &params->phy[phy_index]);
14232                                 params->phy[phy_index].link_reset(
14233                                         &params->phy[phy_index],
14234                                         params);
14235                         }
14236                         if (params->phy[phy_index].flags &
14237                             ELINK_FLAGS_REARM_LATCH_SIGNAL)
14238                                 clear_latch_ind = 1;
14239                 }
14240         }
14241
14242         if (clear_latch_ind) {
14243                 /* Clear latching indication */
14244                 elink_rearm_latch_signal(sc, port, 0);
14245                 elink_bits_dis(sc, NIG_REG_LATCH_BC_0 + port * 4,
14246                                1 << ELINK_NIG_LATCH_BC_ENABLE_MI_INT);
14247         }
14248 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
14249         if (!CHIP_REV_IS_SLOW(sc))
14250 #endif
14251         if (params->phy[ELINK_INT_PHY].link_reset)
14252                 params->phy[ELINK_INT_PHY].link_reset(
14253                         &params->phy[ELINK_INT_PHY], params);
14254
14255         /* Disable nig ingress interface */
14256         if (!CHIP_IS_E3(sc)) {
14257                 /* Reset BigMac */
14258                 REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
14259                        (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
14260                 REG_WR(sc, NIG_REG_BMAC0_IN_EN + port * 4, 0);
14261                 REG_WR(sc, NIG_REG_EMAC0_IN_EN + port * 4, 0);
14262         } else {
14263                 uint32_t xmac_base = (params->port) ? GRCBASE_XMAC1 :
14264                                                       GRCBASE_XMAC0;
14265                 elink_set_xumac_nig(params, 0, 0);
14266                 if (REG_RD(sc, MISC_REG_RESET_REG_2) &
14267                     MISC_REGISTERS_RESET_REG_2_XMAC)
14268                         REG_WR(sc, xmac_base + XMAC_REG_CTRL,
14269                                XMAC_CTRL_REG_SOFT_RESET);
14270         }
14271         vars->link_up = 0;
14272         vars->phy_flags = 0;
14273         return ELINK_STATUS_OK;
14274 }
14275 elink_status_t elink_lfa_reset(struct elink_params *params,
14276                                struct elink_vars *vars)
14277 {
14278         struct bnx2x_softc *sc = params->sc;
14279         vars->link_up = 0;
14280         vars->phy_flags = 0;
14281         params->link_flags &= ~ELINK_PHY_INITIALIZED;
14282         if (!params->lfa_base)
14283                 return elink_link_reset(params, vars, 1);
14284         /*
14285          * Activate NIG drain so that during this time the device won't send
14286          * anything while it is unable to response.
14287          */
14288         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 1);
14289
14290         /*
14291          * Close gracefully the gate from BMAC to NIG such that no half packets
14292          * are passed.
14293          */
14294         if (!CHIP_IS_E3(sc))
14295                 elink_set_bmac_rx(sc, params->chip_id, params->port, 0);
14296
14297         if (CHIP_IS_E3(sc)) {
14298                 elink_set_xmac_rxtx(params, 0);
14299                 elink_set_umac_rxtx(params, 0);
14300         }
14301         /* Wait 10ms for the pipe to clean up*/
14302         DELAY(1000 * 10);
14303
14304         /* Clean the NIG-BRB using the network filters in a way that will
14305          * not cut a packet in the middle.
14306          */
14307         elink_set_rx_filter(params, 0);
14308
14309         /*
14310          * Re-open the gate between the BMAC and the NIG, after verifying the
14311          * gate to the BRB is closed, otherwise packets may arrive to the
14312          * firmware before driver had initialized it. The target is to achieve
14313          * minimum management protocol down time.
14314          */
14315         if (!CHIP_IS_E3(sc))
14316                 elink_set_bmac_rx(sc, params->chip_id, params->port, 1);
14317
14318         if (CHIP_IS_E3(sc)) {
14319                 elink_set_xmac_rxtx(params, 1);
14320                 elink_set_umac_rxtx(params, 1);
14321         }
14322         /* Disable NIG drain */
14323         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
14324         return ELINK_STATUS_OK;
14325 }
14326
14327 /****************************************************************************/
14328 /*                              Common function                             */
14329 /****************************************************************************/
14330 static elink_status_t elink_8073_common_init_phy(struct bnx2x_softc *sc,
14331                                       uint32_t shmem_base_path[],
14332                                       uint32_t shmem2_base_path[],
14333                                       uint8_t phy_index,
14334                                       __rte_unused uint32_t chip_id)
14335 {
14336         struct elink_phy phy[PORT_MAX];
14337         struct elink_phy *phy_blk[PORT_MAX];
14338         uint16_t val;
14339         int8_t port = 0;
14340         int8_t port_of_path = 0;
14341         uint32_t swap_val, swap_override;
14342         swap_val = REG_RD(sc,  NIG_REG_PORT_SWAP);
14343         swap_override = REG_RD(sc,  NIG_REG_STRAP_OVERRIDE);
14344         port ^= (swap_val && swap_override);
14345         elink_ext_phy_hw_reset(sc, port);
14346         /* PART1 - Reset both phys */
14347         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14348                 uint32_t shmem_base, shmem2_base;
14349                 /* In E2, same phy is using for port0 of the two paths */
14350                 if (CHIP_IS_E1x(sc)) {
14351                         shmem_base = shmem_base_path[0];
14352                         shmem2_base = shmem2_base_path[0];
14353                         port_of_path = port;
14354                 } else {
14355                         shmem_base = shmem_base_path[port];
14356                         shmem2_base = shmem2_base_path[port];
14357                         port_of_path = 0;
14358                 }
14359
14360                 /* Extract the ext phy address for the port */
14361                 if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14362                                        port_of_path, &phy[port]) !=
14363                     ELINK_STATUS_OK) {
14364                         ELINK_DEBUG_P0(sc, "populate_phy failed");
14365                         return ELINK_STATUS_ERROR;
14366                 }
14367                 /* Disable attentions */
14368                 elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
14369                                port_of_path * 4,
14370                                (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14371                                 ELINK_NIG_MASK_XGXS0_LINK10G |
14372                                 ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14373                                 ELINK_NIG_MASK_MI_INT));
14374
14375                 /* Need to take the phy out of low power mode in order
14376                  * to write to access its registers
14377                  */
14378                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
14379                                MISC_REGISTERS_GPIO_OUTPUT_HIGH,
14380                                port);
14381
14382                 /* Reset the phy */
14383                 elink_cl45_write(sc, &phy[port],
14384                                  MDIO_PMA_DEVAD,
14385                                  MDIO_PMA_REG_CTRL,
14386                                  1 << 15);
14387         }
14388
14389         /* Add delay of 150ms after reset */
14390         DELAY(1000 * 150);
14391
14392         if (phy[PORT_0].addr & 0x1) {
14393                 phy_blk[PORT_0] = &(phy[PORT_1]);
14394                 phy_blk[PORT_1] = &(phy[PORT_0]);
14395         } else {
14396                 phy_blk[PORT_0] = &(phy[PORT_0]);
14397                 phy_blk[PORT_1] = &(phy[PORT_1]);
14398         }
14399
14400         /* PART2 - Download firmware to both phys */
14401         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14402                 if (CHIP_IS_E1x(sc))
14403                         port_of_path = port;
14404                 else
14405                         port_of_path = 0;
14406
14407                 ELINK_DEBUG_P1(sc, "Loading spirom for phy address 0x%x",
14408                            phy_blk[port]->addr);
14409                 if (elink_8073_8727_external_rom_boot(sc, phy_blk[port],
14410                                                       port_of_path))
14411                         return ELINK_STATUS_ERROR;
14412
14413                 /* Only set bit 10 = 1 (Tx power down) */
14414                 elink_cl45_read(sc, phy_blk[port],
14415                                 MDIO_PMA_DEVAD,
14416                                 MDIO_PMA_REG_TX_POWER_DOWN, &val);
14417
14418                 /* Phase1 of TX_POWER_DOWN reset */
14419                 elink_cl45_write(sc, phy_blk[port],
14420                                  MDIO_PMA_DEVAD,
14421                                  MDIO_PMA_REG_TX_POWER_DOWN,
14422                                  (val | 1 << 10));
14423         }
14424
14425         /* Toggle Transmitter: Power down and then up with 600ms delay
14426          * between
14427          */
14428         DELAY(1000 * 600);
14429
14430         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
14431         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14432                 /* Phase2 of POWER_DOWN_RESET */
14433                 /* Release bit 10 (Release Tx power down) */
14434                 elink_cl45_read(sc, phy_blk[port],
14435                                 MDIO_PMA_DEVAD,
14436                                 MDIO_PMA_REG_TX_POWER_DOWN, &val);
14437
14438                 elink_cl45_write(sc, phy_blk[port],
14439                                 MDIO_PMA_DEVAD,
14440                                 MDIO_PMA_REG_TX_POWER_DOWN,
14441                                 (val & (~(1 << 10))));
14442                 DELAY(1000 * 15);
14443
14444                 /* Read modify write the SPI-ROM version select register */
14445                 elink_cl45_read(sc, phy_blk[port],
14446                                 MDIO_PMA_DEVAD,
14447                                 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
14448                 elink_cl45_write(sc, phy_blk[port],
14449                                  MDIO_PMA_DEVAD,
14450                                  MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1 << 12)));
14451
14452                 /* set GPIO2 back to LOW */
14453                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
14454                                MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
14455         }
14456         return ELINK_STATUS_OK;
14457 }
14458 static elink_status_t elink_8726_common_init_phy(struct bnx2x_softc *sc,
14459                                       uint32_t shmem_base_path[],
14460                                       uint32_t shmem2_base_path[],
14461                                       uint8_t phy_index,
14462                                       __rte_unused uint32_t chip_id)
14463 {
14464         uint32_t val;
14465         int8_t port;
14466         struct elink_phy phy;
14467         /* Use port1 because of the static port-swap */
14468         /* Enable the module detection interrupt */
14469         val = REG_RD(sc, MISC_REG_GPIO_EVENT_EN);
14470         val |= ((1 << MISC_REGISTERS_GPIO_3) |
14471                 (1 << (MISC_REGISTERS_GPIO_3 +
14472                  MISC_REGISTERS_GPIO_PORT_SHIFT)));
14473         REG_WR(sc, MISC_REG_GPIO_EVENT_EN, val);
14474
14475         elink_ext_phy_hw_reset(sc, 0);
14476         DELAY(1000 * 5);
14477         for (port = 0; port < PORT_MAX; port++) {
14478                 uint32_t shmem_base, shmem2_base;
14479
14480                 /* In E2, same phy is using for port0 of the two paths */
14481                 if (CHIP_IS_E1x(sc)) {
14482                         shmem_base = shmem_base_path[0];
14483                         shmem2_base = shmem2_base_path[0];
14484                 } else {
14485                         shmem_base = shmem_base_path[port];
14486                         shmem2_base = shmem2_base_path[port];
14487                 }
14488                 /* Extract the ext phy address for the port */
14489                 if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14490                                        port, &phy) !=
14491                     ELINK_STATUS_OK) {
14492                         ELINK_DEBUG_P0(sc, "populate phy failed");
14493                         return ELINK_STATUS_ERROR;
14494                 }
14495
14496                 /* Reset phy*/
14497                 elink_cl45_write(sc, &phy,
14498                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
14499
14500
14501                 /* Set fault module detected LED on */
14502                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_0,
14503                                MISC_REGISTERS_GPIO_HIGH,
14504                                port);
14505         }
14506
14507         return ELINK_STATUS_OK;
14508 }
14509 static void elink_get_ext_phy_reset_gpio(struct bnx2x_softc *sc,
14510                                          uint32_t shmem_base,
14511                                          uint8_t *io_gpio, uint8_t *io_port)
14512 {
14513
14514         uint32_t phy_gpio_reset = REG_RD(sc, shmem_base +
14515                                           offsetof(struct shmem_region,
14516                                 dev_info.port_hw_config[PORT_0].default_cfg));
14517         switch (phy_gpio_reset) {
14518         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
14519                 *io_gpio = 0;
14520                 *io_port = 0;
14521                 break;
14522         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
14523                 *io_gpio = 1;
14524                 *io_port = 0;
14525                 break;
14526         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
14527                 *io_gpio = 2;
14528                 *io_port = 0;
14529                 break;
14530         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
14531                 *io_gpio = 3;
14532                 *io_port = 0;
14533                 break;
14534         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
14535                 *io_gpio = 0;
14536                 *io_port = 1;
14537                 break;
14538         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
14539                 *io_gpio = 1;
14540                 *io_port = 1;
14541                 break;
14542         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
14543                 *io_gpio = 2;
14544                 *io_port = 1;
14545                 break;
14546         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
14547                 *io_gpio = 3;
14548                 *io_port = 1;
14549                 break;
14550         default:
14551                 /* Don't override the io_gpio and io_port */
14552                 break;
14553         }
14554 }
14555
14556 static elink_status_t elink_8727_common_init_phy(struct bnx2x_softc *sc,
14557                                       uint32_t shmem_base_path[],
14558                                       uint32_t shmem2_base_path[],
14559                                       uint8_t phy_index,
14560                                       __rte_unused uint32_t chip_id)
14561 {
14562         int8_t port, reset_gpio;
14563         uint32_t swap_val, swap_override;
14564         struct elink_phy phy[PORT_MAX];
14565         struct elink_phy *phy_blk[PORT_MAX];
14566         int8_t port_of_path;
14567         swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
14568         swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
14569
14570         reset_gpio = MISC_REGISTERS_GPIO_1;
14571         port = 1;
14572
14573         /* Retrieve the reset gpio/port which control the reset.
14574          * Default is GPIO1, PORT1
14575          */
14576         elink_get_ext_phy_reset_gpio(sc, shmem_base_path[0],
14577                                      (uint8_t *)&reset_gpio, (uint8_t *)&port);
14578
14579         /* Calculate the port based on port swap */
14580         port ^= (swap_val && swap_override);
14581
14582         /* Initiate PHY reset*/
14583         elink_cb_gpio_write(sc, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
14584                        port);
14585         DELAY(1000 * 1);
14586         elink_cb_gpio_write(sc, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
14587                        port);
14588
14589         DELAY(1000 * 5);
14590
14591         /* PART1 - Reset both phys */
14592         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14593                 uint32_t shmem_base, shmem2_base;
14594
14595                 /* In E2, same phy is using for port0 of the two paths */
14596                 if (CHIP_IS_E1x(sc)) {
14597                         shmem_base = shmem_base_path[0];
14598                         shmem2_base = shmem2_base_path[0];
14599                         port_of_path = port;
14600                 } else {
14601                         shmem_base = shmem_base_path[port];
14602                         shmem2_base = shmem2_base_path[port];
14603                         port_of_path = 0;
14604                 }
14605
14606                 /* Extract the ext phy address for the port */
14607                 if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14608                                        port_of_path, &phy[port]) !=
14609                                        ELINK_STATUS_OK) {
14610                         ELINK_DEBUG_P0(sc, "populate phy failed");
14611                         return ELINK_STATUS_ERROR;
14612                 }
14613                 /* disable attentions */
14614                 elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
14615                                port_of_path * 4,
14616                                (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14617                                 ELINK_NIG_MASK_XGXS0_LINK10G |
14618                                 ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14619                                 ELINK_NIG_MASK_MI_INT));
14620
14621
14622                 /* Reset the phy */
14623                 elink_cl45_write(sc, &phy[port],
14624                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1 << 15);
14625         }
14626
14627         /* Add delay of 150ms after reset */
14628         DELAY(1000 * 150);
14629         if (phy[PORT_0].addr & 0x1) {
14630                 phy_blk[PORT_0] = &(phy[PORT_1]);
14631                 phy_blk[PORT_1] = &(phy[PORT_0]);
14632         } else {
14633                 phy_blk[PORT_0] = &(phy[PORT_0]);
14634                 phy_blk[PORT_1] = &(phy[PORT_1]);
14635         }
14636         /* PART2 - Download firmware to both phys */
14637         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14638                 if (CHIP_IS_E1x(sc))
14639                         port_of_path = port;
14640                 else
14641                         port_of_path = 0;
14642                 ELINK_DEBUG_P1(sc, "Loading spirom for phy address 0x%x",
14643                            phy_blk[port]->addr);
14644                 if (elink_8073_8727_external_rom_boot(sc, phy_blk[port],
14645                                                       port_of_path))
14646                         return ELINK_STATUS_ERROR;
14647                 /* Disable PHY transmitter output */
14648                 elink_cl45_write(sc, phy_blk[port],
14649                                  MDIO_PMA_DEVAD,
14650                                  MDIO_PMA_REG_TX_DISABLE, 1);
14651
14652         }
14653         return ELINK_STATUS_OK;
14654 }
14655
14656 static elink_status_t elink_84833_common_init_phy(struct bnx2x_softc *sc,
14657                                 uint32_t shmem_base_path[],
14658                                 __rte_unused uint32_t shmem2_base_path[],
14659                                 __rte_unused uint8_t phy_index,
14660                                 uint32_t chip_id)
14661 {
14662         uint8_t reset_gpios;
14663         reset_gpios = elink_84833_get_reset_gpios(sc, shmem_base_path, chip_id);
14664         elink_cb_gpio_mult_write(sc, reset_gpios,
14665                                  MISC_REGISTERS_GPIO_OUTPUT_LOW);
14666         DELAY(10);
14667         elink_cb_gpio_mult_write(sc, reset_gpios,
14668                                  MISC_REGISTERS_GPIO_OUTPUT_HIGH);
14669         ELINK_DEBUG_P1(sc, "84833 reset pulse on pin values 0x%x",
14670                 reset_gpios);
14671         return ELINK_STATUS_OK;
14672 }
14673 static elink_status_t elink_ext_phy_common_init(struct bnx2x_softc *sc,
14674                                      uint32_t shmem_base_path[],
14675                                      uint32_t shmem2_base_path[],
14676                                      uint8_t phy_index,
14677                                      uint32_t ext_phy_type, uint32_t chip_id)
14678 {
14679         elink_status_t rc = ELINK_STATUS_OK;
14680
14681         switch (ext_phy_type) {
14682         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8073:
14683                 rc = elink_8073_common_init_phy(sc, shmem_base_path,
14684                                                 shmem2_base_path,
14685                                                 phy_index, chip_id);
14686                 break;
14687         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
14688         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
14689         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727_NOC:
14690                 rc = elink_8727_common_init_phy(sc, shmem_base_path,
14691                                                 shmem2_base_path,
14692                                                 phy_index, chip_id);
14693                 break;
14694
14695         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726:
14696                 /* GPIO1 affects both ports, so there's need to pull
14697                  * it for single port alone
14698                  */
14699                 rc = elink_8726_common_init_phy(sc, shmem_base_path,
14700                                                 shmem2_base_path,
14701                                                 phy_index, chip_id);
14702                 break;
14703         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84833:
14704         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834:
14705         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858:
14706                 /* GPIO3's are linked, and so both need to be toggled
14707                  * to obtain required 2us pulse.
14708                  */
14709                 rc = elink_84833_common_init_phy(sc, shmem_base_path,
14710                                                 shmem2_base_path,
14711                                                 phy_index, chip_id);
14712                 break;
14713         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
14714                 rc = ELINK_STATUS_ERROR;
14715                 break;
14716         default:
14717                 ELINK_DEBUG_P1(sc,
14718                            "ext_phy 0x%x common init not required",
14719                            ext_phy_type);
14720                 break;
14721         }
14722
14723         if (rc != ELINK_STATUS_OK)
14724                 elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED, 0);
14725                                      /* "Warning: PHY was not initialized,"
14726                                       * " Port %d",
14727                                       */
14728
14729         return rc;
14730 }
14731
14732 elink_status_t elink_common_init_phy(struct bnx2x_softc *sc,
14733                           uint32_t shmem_base_path[],
14734                           uint32_t shmem2_base_path[], uint32_t chip_id,
14735                           __rte_unused uint8_t one_port_enabled)
14736 {
14737         elink_status_t rc = ELINK_STATUS_OK;
14738         uint32_t phy_ver, val;
14739         uint8_t phy_index = 0;
14740         uint32_t ext_phy_type, ext_phy_config;
14741 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
14742         if (CHIP_REV_IS_EMUL(sc) || CHIP_REV_IS_FPGA(sc))
14743                 return ELINK_STATUS_OK;
14744 #endif
14745
14746         elink_set_mdio_clk(sc, chip_id, GRCBASE_EMAC0);
14747         elink_set_mdio_clk(sc, chip_id, GRCBASE_EMAC1);
14748         ELINK_DEBUG_P0(sc, "Begin common phy init");
14749         if (CHIP_IS_E3(sc)) {
14750                 /* Enable EPIO */
14751                 val = REG_RD(sc, MISC_REG_GEN_PURP_HWG);
14752                 REG_WR(sc, MISC_REG_GEN_PURP_HWG, val | 1);
14753         }
14754         /* Check if common init was already done */
14755         phy_ver = REG_RD(sc, shmem_base_path[0] +
14756                          offsetof(struct shmem_region,
14757                                   port_mb[PORT_0].ext_phy_fw_version));
14758         if (phy_ver) {
14759                 ELINK_DEBUG_P1(sc, "Not doing common init; phy ver is 0x%x",
14760                                phy_ver);
14761                 return ELINK_STATUS_OK;
14762         }
14763
14764         /* Read the ext_phy_type for arbitrary port(0) */
14765         for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
14766               phy_index++) {
14767                 ext_phy_config = elink_get_ext_phy_config(sc,
14768                                                           shmem_base_path[0],
14769                                                           phy_index, 0);
14770                 ext_phy_type = ELINK_XGXS_EXT_PHY_TYPE(ext_phy_config);
14771                 rc |= elink_ext_phy_common_init(sc, shmem_base_path,
14772                                                 shmem2_base_path,
14773                                                 phy_index, ext_phy_type,
14774                                                 chip_id);
14775         }
14776         return rc;
14777 }
14778
14779 static void elink_check_over_curr(struct elink_params *params,
14780                                   struct elink_vars *vars)
14781 {
14782         struct bnx2x_softc *sc = params->sc;
14783         uint32_t cfg_pin;
14784         uint8_t port = params->port;
14785         uint32_t pin_val;
14786
14787         cfg_pin = (REG_RD(sc, params->shmem_base +
14788                           offsetof(struct shmem_region,
14789                                dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) &
14790                    PORT_HW_CFG_E3_OVER_CURRENT_MASK) >>
14791                 PORT_HW_CFG_E3_OVER_CURRENT_SHIFT;
14792
14793         /* Ignore check if no external input PIN available */
14794         if (elink_get_cfg_pin(sc, cfg_pin, &pin_val) != ELINK_STATUS_OK)
14795                 return;
14796
14797         if (!pin_val) {
14798                 if ((vars->phy_flags & PHY_OVER_CURRENT_FLAG) == 0) {
14799                         elink_cb_event_log(sc, ELINK_LOG_ID_OVER_CURRENT,
14800                                            params->port);
14801                                         /* "Error:  Power fault on Port %d has"
14802                                          *  " been detected and the power to "
14803                                          *  "that SFP+ module has been removed"
14804                                          *  " to prevent failure of the card."
14805                                          *  " Please remove the SFP+ module and"
14806                                          *  " restart the system to clear this"
14807                                          *  " error.",
14808                                          */
14809                         vars->phy_flags |= PHY_OVER_CURRENT_FLAG;
14810                         elink_warpcore_power_module(params, 0);
14811                 }
14812         } else
14813                 vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG;
14814 }
14815
14816 /* Returns 0 if no change occurred since last check; 1 otherwise. */
14817 static uint8_t elink_analyze_link_error(struct elink_params *params,
14818                                     struct elink_vars *vars, uint32_t status,
14819                                     uint32_t phy_flag, uint32_t link_flag,
14820                                     uint8_t notify)
14821 {
14822         struct bnx2x_softc *sc = params->sc;
14823         /* Compare new value with previous value */
14824         uint8_t led_mode;
14825         uint32_t old_status = (vars->phy_flags & phy_flag) ? 1 : 0;
14826
14827         if ((status ^ old_status) == 0)
14828                 return 0;
14829
14830         /* If values differ */
14831         switch (phy_flag) {
14832         case PHY_HALF_OPEN_CONN_FLAG:
14833                 ELINK_DEBUG_P0(sc, "Analyze Remote Fault");
14834                 break;
14835         case PHY_SFP_TX_FAULT_FLAG:
14836                 ELINK_DEBUG_P0(sc, "Analyze TX Fault");
14837                 break;
14838         default:
14839                 ELINK_DEBUG_P0(sc, "Analyze UNKNOWN");
14840         }
14841         ELINK_DEBUG_P3(sc, "Link changed:[%x %x]->%x", vars->link_up,
14842            old_status, status);
14843
14844         /* Do not touch the link in case physical link down */
14845         if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0)
14846                 return 1;
14847
14848         /* a. Update shmem->link_status accordingly
14849          * b. Update elink_vars->link_up
14850          */
14851         if (status) {
14852                 vars->link_status &= ~LINK_STATUS_LINK_UP;
14853                 vars->link_status |= link_flag;
14854                 vars->link_up = 0;
14855                 vars->phy_flags |= phy_flag;
14856
14857                 /* activate nig drain */
14858                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 1);
14859                 /* Set LED mode to off since the PHY doesn't know about these
14860                  * errors
14861                  */
14862                 led_mode = ELINK_LED_MODE_OFF;
14863         } else {
14864                 vars->link_status |= LINK_STATUS_LINK_UP;
14865                 vars->link_status &= ~link_flag;
14866                 vars->link_up = 1;
14867                 vars->phy_flags &= ~phy_flag;
14868                 led_mode = ELINK_LED_MODE_OPER;
14869
14870                 /* Clear nig drain */
14871                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
14872         }
14873         elink_sync_link(params, vars);
14874         /* Update the LED according to the link state */
14875         elink_set_led(params, vars, led_mode, ELINK_SPEED_10000);
14876
14877         /* Update link status in the shared memory */
14878         elink_update_mng(params, vars->link_status);
14879
14880         /* C. Trigger General Attention */
14881         vars->periodic_flags |= ELINK_PERIODIC_FLAGS_LINK_EVENT;
14882         if (notify)
14883                 elink_cb_notify_link_changed(sc);
14884
14885         return 1;
14886 }
14887
14888 /******************************************************************************
14889  * Description:
14890  *      This function checks for half opened connection change indication.
14891  *      When such change occurs, it calls the elink_analyze_link_error
14892  *      to check if Remote Fault is set or cleared. Reception of remote fault
14893  *      status message in the MAC indicates that the peer's MAC has detected
14894  *      a fault, for example, due to break in the TX side of fiber.
14895  *
14896  ******************************************************************************/
14897 static
14898 elink_status_t elink_check_half_open_conn(struct elink_params *params,
14899                                 struct elink_vars *vars,
14900                                 uint8_t notify)
14901 {
14902         struct bnx2x_softc *sc = params->sc;
14903         uint32_t lss_status = 0;
14904         uint32_t mac_base;
14905         /* In case link status is physically up @ 10G do */
14906         if (((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0) ||
14907             (REG_RD(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port * 4)))
14908                 return ELINK_STATUS_OK;
14909
14910         if (CHIP_IS_E3(sc) &&
14911             (REG_RD(sc, MISC_REG_RESET_REG_2) &
14912               (MISC_REGISTERS_RESET_REG_2_XMAC))) {
14913                 /* Check E3 XMAC */
14914                 /* Note that link speed cannot be queried here, since it may be
14915                  * zero while link is down. In case UMAC is active, LSS will
14916                  * simply not be set
14917                  */
14918                 mac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
14919
14920                 /* Clear stick bits (Requires rising edge) */
14921                 REG_WR(sc, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
14922                 REG_WR(sc, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
14923                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
14924                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
14925                 if (REG_RD(sc, mac_base + XMAC_REG_RX_LSS_STATUS))
14926                         lss_status = 1;
14927
14928                 elink_analyze_link_error(params, vars, lss_status,
14929                                          PHY_HALF_OPEN_CONN_FLAG,
14930                                          LINK_STATUS_NONE, notify);
14931         } else if (REG_RD(sc, MISC_REG_RESET_REG_2) &
14932                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) {
14933                 /* Check E1X / E2 BMAC */
14934                 uint32_t lss_status_reg;
14935                 uint32_t wb_data[2];
14936                 mac_base = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
14937                         NIG_REG_INGRESS_BMAC0_MEM;
14938                 /*  Read BIGMAC_REGISTER_RX_LSS_STATUS */
14939                 if (CHIP_IS_E2(sc))
14940                         lss_status_reg = BIGMAC2_REGISTER_RX_LSS_STAT;
14941                 else
14942                         lss_status_reg = BIGMAC_REGISTER_RX_LSS_STATUS;
14943
14944                 REG_RD_DMAE(sc, mac_base + lss_status_reg, wb_data, 2);
14945                 lss_status = (wb_data[0] > 0);
14946
14947                 elink_analyze_link_error(params, vars, lss_status,
14948                                          PHY_HALF_OPEN_CONN_FLAG,
14949                                          LINK_STATUS_NONE, notify);
14950         }
14951         return ELINK_STATUS_OK;
14952 }
14953 static void elink_sfp_tx_fault_detection(struct elink_phy *phy,
14954                                          struct elink_params *params,
14955                                          struct elink_vars *vars)
14956 {
14957         struct bnx2x_softc *sc = params->sc;
14958         uint32_t cfg_pin, value = 0;
14959         uint8_t led_change, port = params->port;
14960
14961         /* Get The SFP+ TX_Fault controlling pin ([eg]pio) */
14962         cfg_pin = (REG_RD(sc, params->shmem_base + offsetof(struct shmem_region,
14963                           dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
14964                    PORT_HW_CFG_E3_TX_FAULT_MASK) >>
14965                   PORT_HW_CFG_E3_TX_FAULT_SHIFT;
14966
14967         if (elink_get_cfg_pin(sc, cfg_pin, &value)) {
14968                 ELINK_DEBUG_P1(sc, "Failed to read pin 0x%02x", cfg_pin);
14969                 return;
14970         }
14971
14972         led_change = elink_analyze_link_error(params, vars, value,
14973                                               PHY_SFP_TX_FAULT_FLAG,
14974                                               LINK_STATUS_SFP_TX_FAULT, 1);
14975
14976         if (led_change) {
14977                 /* Change TX_Fault led, set link status for further syncs */
14978                 uint8_t led_mode;
14979
14980                 if (vars->phy_flags & PHY_SFP_TX_FAULT_FLAG) {
14981                         led_mode = MISC_REGISTERS_GPIO_HIGH;
14982                         vars->link_status |= LINK_STATUS_SFP_TX_FAULT;
14983                 } else {
14984                         led_mode = MISC_REGISTERS_GPIO_LOW;
14985                         vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT;
14986                 }
14987
14988                 /* If module is unapproved, led should be on regardless */
14989                 if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED)) {
14990                         ELINK_DEBUG_P1(sc, "Change TX_Fault LED: ->%x",
14991                            led_mode);
14992                         elink_set_e3_module_fault_led(params, led_mode);
14993                 }
14994         }
14995 }
14996 static void elink_kr2_recovery(struct elink_params *params,
14997                                struct elink_vars *vars,
14998                                struct elink_phy *phy)
14999 {
15000         struct bnx2x_softc *sc = params->sc;
15001         ELINK_DEBUG_P0(sc, "KR2 recovery");
15002         elink_warpcore_enable_AN_KR2(phy, params, vars);
15003         elink_warpcore_restart_AN_KR(phy, params);
15004 }
15005
15006 static void elink_check_kr2_wa(struct elink_params *params,
15007                                struct elink_vars *vars,
15008                                struct elink_phy *phy)
15009 {
15010         struct bnx2x_softc *sc = params->sc;
15011         uint16_t base_page, next_page, not_kr2_device, lane;
15012         int sigdet;
15013
15014         /* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery
15015          * Since some switches tend to reinit the AN process and clear the
15016          * the advertised BP/NP after ~2 seconds causing the KR2 to be disabled
15017          * and recovered many times
15018          */
15019         if (vars->check_kr2_recovery_cnt > 0) {
15020                 vars->check_kr2_recovery_cnt--;
15021                 return;
15022         }
15023
15024         sigdet = elink_warpcore_get_sigdet(phy, params);
15025         if (!sigdet) {
15026                 if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
15027                         elink_kr2_recovery(params, vars, phy);
15028                         ELINK_DEBUG_P0(sc, "No sigdet");
15029                 }
15030                 return;
15031         }
15032
15033         lane = elink_get_warpcore_lane(phy, params);
15034         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
15035                           MDIO_AER_BLOCK_AER_REG, lane);
15036         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
15037                         MDIO_AN_REG_LP_AUTO_NEG, &base_page);
15038         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
15039                         MDIO_AN_REG_LP_AUTO_NEG2, &next_page);
15040         elink_set_aer_mmd(params, phy);
15041
15042         /* CL73 has not begun yet */
15043         if (base_page == 0) {
15044                 if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
15045                         elink_kr2_recovery(params, vars, phy);
15046                         ELINK_DEBUG_P0(sc, "No BP");
15047                 }
15048                 return;
15049         }
15050
15051         /* In case NP bit is not set in the BasePage, or it is set,
15052          * but only KX is advertised, declare this link partner as non-KR2
15053          * device.
15054          */
15055         not_kr2_device = (((base_page & 0x8000) == 0) ||
15056                           (((base_page & 0x8000) &&
15057                             ((next_page & 0xe0) == 0x20))));
15058
15059         /* In case KR2 is already disabled, check if we need to re-enable it */
15060         if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
15061                 if (!not_kr2_device) {
15062                         ELINK_DEBUG_P2(sc, "BP=0x%x, NP=0x%x", base_page,
15063                            next_page);
15064                         elink_kr2_recovery(params, vars, phy);
15065                 }
15066                 return;
15067         }
15068         /* KR2 is enabled, but not KR2 device */
15069         if (not_kr2_device) {
15070                 /* Disable KR2 on both lanes */
15071                 ELINK_DEBUG_P2(sc, "BP=0x%x, NP=0x%x", base_page, next_page);
15072                 elink_disable_kr2(params, vars, phy);
15073                 /* Restart AN on leading lane */
15074                 elink_warpcore_restart_AN_KR(phy, params);
15075                 return;
15076         }
15077 }
15078
15079 void elink_period_func(struct elink_params *params, struct elink_vars *vars)
15080 {
15081         uint16_t phy_idx;
15082         struct bnx2x_softc *sc = params->sc;
15083         for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
15084                 if (params->phy[phy_idx].flags & ELINK_FLAGS_TX_ERROR_CHECK) {
15085                         elink_set_aer_mmd(params, &params->phy[phy_idx]);
15086                         if (elink_check_half_open_conn(params, vars, 1) !=
15087                             ELINK_STATUS_OK)
15088                                 ELINK_DEBUG_P0(sc, "Fault detection failed");
15089                         break;
15090                 }
15091         }
15092
15093         if (CHIP_IS_E3(sc)) {
15094                 struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
15095                 elink_set_aer_mmd(params, phy);
15096                 if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
15097                      (phy->speed_cap_mask &
15098                       PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) ||
15099                     (phy->req_line_speed == ELINK_SPEED_20000))
15100                         elink_check_kr2_wa(params, vars, phy);
15101                 elink_check_over_curr(params, vars);
15102                 if (vars->rx_tx_asic_rst)
15103                         elink_warpcore_config_runtime(phy, params, vars);
15104
15105                 if ((REG_RD(sc, params->shmem_base +
15106                             offsetof(struct shmem_region, dev_info.
15107                                 port_hw_config[params->port].default_cfg))
15108                     & PORT_HW_CFG_NET_SERDES_IF_MASK) ==
15109                     PORT_HW_CFG_NET_SERDES_IF_SFI) {
15110                         if (elink_is_sfp_module_plugged(phy, params)) {
15111                                 elink_sfp_tx_fault_detection(phy, params, vars);
15112                         } else if (vars->link_status &
15113                                 LINK_STATUS_SFP_TX_FAULT) {
15114                                 /* Clean trail, interrupt corrects the leds */
15115                                 vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT;
15116                                 vars->phy_flags &= ~PHY_SFP_TX_FAULT_FLAG;
15117                                 /* Update link status in the shared memory */
15118                                 elink_update_mng(params, vars->link_status);
15119                         }
15120                 }
15121         }
15122 }
15123
15124 uint8_t elink_fan_failure_det_req(struct bnx2x_softc *sc,
15125                              uint32_t shmem_base,
15126                              uint32_t shmem2_base,
15127                              uint8_t port)
15128 {
15129         uint8_t phy_index, fan_failure_det_req = 0;
15130         struct elink_phy phy;
15131         for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
15132               phy_index++) {
15133                 if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
15134                                        port, &phy)
15135                     != ELINK_STATUS_OK) {
15136                         ELINK_DEBUG_P0(sc, "populate phy failed");
15137                         return 0;
15138                 }
15139                 fan_failure_det_req |= (phy.flags &
15140                                         ELINK_FLAGS_FAN_FAILURE_DET_REQ);
15141         }
15142         return fan_failure_det_req;
15143 }
15144
15145 void elink_hw_reset_phy(struct elink_params *params)
15146 {
15147         uint8_t phy_index;
15148         struct bnx2x_softc *sc = params->sc;
15149         elink_update_mng(params, 0);
15150         elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + params->port * 4,
15151                        (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
15152                         ELINK_NIG_MASK_XGXS0_LINK10G |
15153                         ELINK_NIG_MASK_SERDES0_LINK_STATUS |
15154                         ELINK_NIG_MASK_MI_INT));
15155
15156         for (phy_index = ELINK_INT_PHY; phy_index < ELINK_MAX_PHYS;
15157               phy_index++) {
15158                 if (params->phy[phy_index].hw_reset) {
15159                         params->phy[phy_index].hw_reset(
15160                                 &params->phy[phy_index],
15161                                 params);
15162                         params->phy[phy_index] = phy_null;
15163                 }
15164         }
15165 }
15166
15167 void elink_init_mod_abs_int(struct bnx2x_softc *sc, struct elink_vars *vars,
15168                             uint32_t chip_id, uint32_t shmem_base,
15169                             uint32_t shmem2_base,
15170                             uint8_t port)
15171 {
15172         uint8_t gpio_num = 0xff, gpio_port = 0xff, phy_index;
15173         uint32_t val;
15174         uint32_t offset, aeu_mask, swap_val, swap_override, sync_offset;
15175         if (CHIP_IS_E3(sc)) {
15176                 if (elink_get_mod_abs_int_cfg(sc, chip_id,
15177                                               shmem_base,
15178                                               port,
15179                                               &gpio_num,
15180                                               &gpio_port) != ELINK_STATUS_OK)
15181                         return;
15182         } else {
15183                 struct elink_phy phy;
15184                 for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
15185                       phy_index++) {
15186                         if (elink_populate_phy(sc, phy_index, shmem_base,
15187                                                shmem2_base, port, &phy)
15188                             != ELINK_STATUS_OK) {
15189                                 ELINK_DEBUG_P0(sc, "populate phy failed");
15190                                 return;
15191                         }
15192                         if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726) {
15193                                 gpio_num = MISC_REGISTERS_GPIO_3;
15194                                 gpio_port = port;
15195                                 break;
15196                         }
15197                 }
15198         }
15199
15200         if (gpio_num == 0xff)
15201                 return;
15202
15203         /* Set GPIO3 to trigger SFP+ module insertion/removal */
15204         elink_cb_gpio_write(sc, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z,
15205                             gpio_port);
15206
15207         swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
15208         swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
15209         gpio_port ^= (swap_val && swap_override);
15210
15211         vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 <<
15212                 (gpio_num + (gpio_port << 2));
15213
15214         sync_offset = shmem_base +
15215                 offsetof(struct shmem_region,
15216                          dev_info.port_hw_config[port].aeu_int_mask);
15217         REG_WR(sc, sync_offset, vars->aeu_int_mask);
15218
15219         ELINK_DEBUG_P3(sc, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x",
15220                        gpio_num, gpio_port, vars->aeu_int_mask);
15221
15222         if (port == 0)
15223                 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
15224         else
15225                 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
15226
15227         /* Open appropriate AEU for interrupts */
15228         aeu_mask = REG_RD(sc, offset);
15229         aeu_mask |= vars->aeu_int_mask;
15230         REG_WR(sc, offset, aeu_mask);
15231
15232         /* Enable the GPIO to trigger interrupt */
15233         val = REG_RD(sc, MISC_REG_GPIO_EVENT_EN);
15234         val |= 1 << (gpio_num + (gpio_port << 2));
15235         REG_WR(sc, MISC_REG_GPIO_EVENT_EN, val);
15236 }